♻️ backend: fix e2e editing session test, make ApplicationApiService a singleton (#525)

This commit is contained in:
Eric Doughty-Papassideris
2024-09-18 21:25:30 +02:00
parent be10393435
commit 9db0fddc98
4 changed files with 41 additions and 9 deletions
@@ -14,6 +14,11 @@ export default class ApplicationsApiService extends TdriveService<undefined> {
version = "1"; version = "1";
name = "applicationsapi"; name = "applicationsapi";
private static default: ApplicationsApiService;
public static getDefault() {
return this.default;
}
public async doInit(): Promise<this> { public async doInit(): Promise<this> {
const fastify = this.context.getProvider<WebServerAPI>("webserver").getServer(); const fastify = this.context.getProvider<WebServerAPI>("webserver").getServer();
fastify.register((instance, _opts, next) => { fastify.register((instance, _opts, next) => {
@@ -70,10 +75,23 @@ export default class ApplicationsApiService extends TdriveService<undefined> {
} }
} }
} }
ApplicationsApiService.default = this;
return this; return this;
} }
/** Get the configuration of a given `appId` or `undefined` if unknown */
public getApplicationConfig(appId: string) {
const apps = config.get<Application[]>("applications.plugins") || [];
return apps.find(app => app.id === appId);
}
/** Get the configuration of a given `appId` or throw an error if unknown */
public requireApplicationConfig(appId: string) {
const app = this.getApplicationConfig(appId);
if (!app) throw new Error(`Unknown application.id ${JSON.stringify(appId)}`);
return app;
}
/** Send a request to the plugin by its application id /** Send a request to the plugin by its application id
* @param url Full URL that doesn't start with a `/` * @param url Full URL that doesn't start with a `/`
*/ */
@@ -82,9 +100,7 @@ export default class ApplicationsApiService extends TdriveService<undefined> {
url: string, url: string,
appId: string, appId: string,
) { ) {
const apps = config.get<Application[]>("applications.plugins") || []; const app = this.requireApplicationConfig(appId);
const app = apps.find(app => app.id === appId);
if (!app) throw new Error(`Unknown application.id ${JSON.stringify(appId)}`);
if (!app.internal_domain) if (!app.internal_domain)
throw new Error(`application.id ${JSON.stringify(appId)} missing an internal_domain`); throw new Error(`application.id ${JSON.stringify(appId)} missing an internal_domain`);
const signature = jwt.sign( const signature = jwt.sign(
@@ -61,6 +61,7 @@ import config from "config";
import { MultipartFile } from "@fastify/multipart"; import { MultipartFile } from "@fastify/multipart";
import { UploadOptions } from "src/services/files/types"; import { UploadOptions } from "src/services/files/types";
import { SortType } from "src/core/platform/services/search/api"; import { SortType } from "src/core/platform/services/search/api";
import ApplicationsApiService from "../../applications-api";
export class DocumentsService { export class DocumentsService {
version: "1"; version: "1";
@@ -976,9 +977,16 @@ export class DocumentsService {
this.logger.error("invalid execution context"); this.logger.error("invalid execution context");
return null; return null;
} }
if (
//TODO: This needs to try in a loop depending on oo-connector response !editorApplicationId ||
// when there is already a key !ApplicationsApiService.getDefault().getApplicationConfig(editorApplicationId)
) {
logger.error(`Missing or invalid application ID: ${JSON.stringify(editorApplicationId)}`);
CrudException.throwMe(
new Error("Unknown appId"),
new CrudException("Missing or invalid application ID", 400),
);
}
let newKey: string; let newKey: string;
try { try {
newKey = EditingSessionKeyFormat.generate( newKey = EditingSessionKeyFormat.generate(
@@ -516,7 +516,7 @@ export default class UserApi {
async getDocumentByEditingKey(editing_session_key: string) { async getDocumentByEditingKey(editing_session_key: string) {
return await this.platform.app.inject({ return await this.platform.app.inject({
method: "GET", method: "GET",
url: `${UserApi.DOC_URL}/companies/${this.platform.workspace.company_id}/item/editing_session/${encodeURIComponent(editing_session_key)}`, url: `${UserApi.DOC_URL}/editing_session/${encodeURIComponent(editing_session_key)}`,
headers: { headers: {
authorization: `Bearer ${this.jwt}` authorization: `Bearer ${this.jwt}`
} }
@@ -1,10 +1,13 @@
import { describe, beforeAll, beforeEach, it, expect, afterAll } from "@jest/globals"; import { describe, beforeAll, beforeEach, it, expect, afterAll, jest } from "@jest/globals";
import { init, TestPlatform } from "../setup"; import { init, TestPlatform } from "../setup";
import UserApi from "../common/user-api"; import UserApi from "../common/user-api";
import { DriveFile, TYPE as DriveFileType } from "../../../src/services/documents/entities/drive-file"; import { DriveFile, TYPE as DriveFileType } from "../../../src/services/documents/entities/drive-file";
import exp = require("node:constants"); import exp = require("node:constants");
import ApplicationsApiService from "../../../src/services/applications-api";
import { afterEach } from "node:test";
import Application from "../../../src/services/applications/entities/application";
describe("the Drive's documents' editing session kind-of-lock", () => { describe("the Drive's documents' editing session kind-of-lock", () => {
let platform: TestPlatform | null; let platform: TestPlatform | null;
@@ -49,6 +52,11 @@ describe("the Drive's documents' editing session kind-of-lock", () => {
parent_id: currentUserRoot, parent_id: currentUserRoot,
scope: "personal", scope: "personal",
}); });
jest.spyOn(ApplicationsApiService.getDefault(), 'getApplicationConfig').mockImplementation((id) => id === "e2e_testing" ? {} as Application : undefined);
});
afterEach(() => {
jest.restoreAllMocks();
}); });
it("atomicCompareAndSet allows a single value at a time", async () => { it("atomicCompareAndSet allows a single value at a time", async () => {