The communications platform that puts data protection first.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
Rocket.Chat/packages/apps-engine/tests/server/managers/AppRuntimeManager.spec.ts

154 lines
5.0 KiB

import { AsyncTest, Expect, Setup, SetupFixture, SpyOn } from 'alsatian';
import { AppStatus } from '../../../src/definition/AppStatus';
import type { AppManager } from '../../../src/server/AppManager';
import type { IParseAppPackageResult } from '../../../src/server/compiler';
import { AppRuntimeManager } from '../../../src/server/managers/AppRuntimeManager';
import type { IRuntimeController } from '../../../src/server/runtime/IRuntimeController';
import type { IAppStorageItem } from '../../../src/server/storage';
export class AppRuntimeManagerTestFixture {
private mockManager: AppManager;
private runtimeManager: AppRuntimeManager;
private mockAppPackage: IParseAppPackageResult;
private mockStorageItem: IAppStorageItem;
private mockSubprocessController: IRuntimeController;
@SetupFixture
public setupFixture() {
this.mockManager = {
getAccessorManager() {
return {} as any;
},
getApiManager() {
return {} as any;
},
getLogStorage() {
return {} as any;
},
getBridges() {
return {} as any;
},
} as AppManager;
this.mockAppPackage = {
info: {
id: 'test-app',
name: 'Test App',
nameSlug: 'test-app',
version: '1.0.0',
description: 'Test app for unit testing',
author: {
name: 'Test Author',
homepage: 'https://test.com',
support: 'https://test.com/support',
},
permissions: [],
requiredApiVersion: '1.0.0',
classFile: 'main.js',
iconFile: 'icon.png',
implements: [],
},
files: {
'main.js': 'console.log("Hello World");',
},
languageContent: {} as unknown as IParseAppPackageResult['languageContent'],
implemented: {} as unknown as IParseAppPackageResult['implemented'],
} as IParseAppPackageResult;
this.mockStorageItem = {
id: 'test-app',
status: AppStatus.MANUALLY_ENABLED,
info: this.mockAppPackage.info,
createdAt: new Date(),
updatedAt: new Date(),
} as IAppStorageItem;
this.mockSubprocessController = {
async setupApp() {
return Promise.resolve();
},
async stopApp() {
return Promise.resolve();
},
getAppId() {
return 'test-app';
},
async getStatus() {
return Promise.resolve(AppStatus.MANUALLY_ENABLED);
},
async sendRequest() {
return Promise.resolve(true);
},
on: () => this.mockSubprocessController,
once: () => this.mockSubprocessController,
off: () => this.mockSubprocessController,
emit: () => true,
addListener: () => this.mockSubprocessController,
removeListener: () => this.mockSubprocessController,
removeAllListeners: () => this.mockSubprocessController,
setMaxListeners: () => this.mockSubprocessController,
getMaxListeners: () => 10,
listeners: () => [],
rawListeners: () => [],
listenerCount: () => 0,
prependListener: () => this.mockSubprocessController,
prependOnceListener: () => this.mockSubprocessController,
eventNames: () => [],
} as IRuntimeController;
}
@Setup
public setup() {
this.runtimeManager = new AppRuntimeManager(this.mockManager, () => this.mockSubprocessController);
}
@AsyncTest('Starts runtime for app successfully')
public async startRuntimeForAppSuccessfully() {
await Expect(() => this.runtimeManager.startRuntimeForApp(this.mockAppPackage, this.mockStorageItem)).not.toThrowAsync();
/* eslint-disable-next-line dot-notation -- We need to access the property like this for the compile not to complain */
Expect(this.runtimeManager['subprocesses'][this.mockAppPackage.info.id]).toBe(this.mockSubprocessController);
}
@AsyncTest('Fails to start runtime for app that already has a runtime')
public async startMultipleRuntimesForSameApp() {
await Expect(() => this.runtimeManager.startRuntimeForApp(this.mockAppPackage, this.mockStorageItem)).not.toThrowAsync();
await Expect(() => this.runtimeManager.startRuntimeForApp(this.mockAppPackage, this.mockStorageItem)).toThrowErrorAsync(
Error,
'App already has an associated runtime',
);
}
@AsyncTest('Starts multiple runtimes for app successfully with force option')
public async startMultipleRuntimesForSameAppWithForceOption() {
await Expect(() => this.runtimeManager.startRuntimeForApp(this.mockAppPackage, this.mockStorageItem)).not.toThrowAsync();
await Expect(() =>
this.runtimeManager.startRuntimeForApp(this.mockAppPackage, this.mockStorageItem, { force: true }),
).not.toThrowAsync();
/* eslint-disable-next-line dot-notation -- We need to access the property like this for the compile not to complain */
Expect(this.runtimeManager['subprocesses'][this.mockAppPackage.info.id]).toBe(this.mockSubprocessController);
}
@AsyncTest()
public async startRuntimeThatFailsToSetup() {
SpyOn(this.mockSubprocessController, 'setupApp').andReturn(Promise.reject(new Error('Nope')));
await Expect(() => this.runtimeManager.startRuntimeForApp(this.mockAppPackage, this.mockStorageItem)).toThrowErrorAsync(Error, 'Nope');
/* eslint-disable-next-line dot-notation -- We need to access the property like this for the compile not to complain */
Expect(this.runtimeManager['subprocesses'][this.mockAppPackage.info.id]).not.toBeDefined();
}
}