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.
309 lines
12 KiB
309 lines
12 KiB
import type { RestorableFunctionSpy } from 'alsatian';
|
|
import { AsyncTest, Expect, Setup, SetupFixture, SpyOn, Teardown, Test } from 'alsatian';
|
|
|
|
import type { AppManager } from '../../../src/server/AppManager';
|
|
import type { ProxiedApp } from '../../../src/server/ProxiedApp';
|
|
import type { AppBridges } from '../../../src/server/bridges';
|
|
import type { AppApiManager, AppExternalComponentManager, AppSchedulerManager, AppSlashCommandManager } from '../../../src/server/managers';
|
|
import { AppAccessorManager, AppOutboundCommunicationProviderManager } from '../../../src/server/managers';
|
|
import { OutboundMessageProvider } from '../../../src/server/managers/AppOutboundCommunicationProvider';
|
|
import { AppPermissionManager } from '../../../src/server/managers/AppPermissionManager';
|
|
import type { UIActionButtonManager } from '../../../src/server/managers/UIActionButtonManager';
|
|
import type { AppLogStorage } from '../../../src/server/storage';
|
|
import { TestsAppBridges } from '../../test-data/bridges/appBridges';
|
|
import { TestsAppLogStorage } from '../../test-data/storage/logStorage';
|
|
import { TestData } from '../../test-data/utilities';
|
|
|
|
export class AppOutboundCommunicationProviderManagerTestFixture {
|
|
public static doThrow = false;
|
|
|
|
private mockBridges: TestsAppBridges;
|
|
|
|
private mockApp: ProxiedApp;
|
|
|
|
private mockAccessors: AppAccessorManager;
|
|
|
|
private mockManager: AppManager;
|
|
|
|
private hasPermissionSpy: RestorableFunctionSpy;
|
|
|
|
@SetupFixture
|
|
public setupFixture() {
|
|
this.mockBridges = new TestsAppBridges();
|
|
|
|
this.mockApp = TestData.getMockApp({ id: 'testing', name: 'testing' }, this.mockManager);
|
|
|
|
const bri = this.mockBridges;
|
|
const app = this.mockApp;
|
|
|
|
this.mockManager = {
|
|
getBridges(): AppBridges {
|
|
return bri;
|
|
},
|
|
getCommandManager() {
|
|
return {} as AppSlashCommandManager;
|
|
},
|
|
getExternalComponentManager(): AppExternalComponentManager {
|
|
return {} as AppExternalComponentManager;
|
|
},
|
|
getApiManager() {
|
|
return {} as AppApiManager;
|
|
},
|
|
getOneById(appId: string): ProxiedApp {
|
|
return appId === 'failMePlease' ? undefined : app;
|
|
},
|
|
getLogStorage(): AppLogStorage {
|
|
return new TestsAppLogStorage();
|
|
},
|
|
getSchedulerManager() {
|
|
return {} as AppSchedulerManager;
|
|
},
|
|
getUIActionButtonManager() {
|
|
return {} as UIActionButtonManager;
|
|
},
|
|
getOutboundCommunicationProviderManager() {
|
|
return {} as AppOutboundCommunicationProviderManager;
|
|
},
|
|
} as AppManager;
|
|
|
|
this.mockAccessors = new AppAccessorManager(this.mockManager);
|
|
const ac = this.mockAccessors;
|
|
this.mockManager.getAccessorManager = function _getAccessorManager(): AppAccessorManager {
|
|
return ac;
|
|
};
|
|
}
|
|
|
|
@Setup
|
|
public setup() {
|
|
this.hasPermissionSpy = SpyOn(AppPermissionManager, 'hasPermission');
|
|
this.hasPermissionSpy.andReturn(true);
|
|
}
|
|
|
|
@Teardown
|
|
public teardown() {
|
|
this.hasPermissionSpy.restore();
|
|
}
|
|
|
|
@Test()
|
|
public basicAppOutboundCommunicationProviderManager() {
|
|
Expect(() => new AppOutboundCommunicationProviderManager({} as AppManager)).toThrow();
|
|
Expect(() => new AppOutboundCommunicationProviderManager(this.mockManager)).not.toThrow();
|
|
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
Expect((manager as any).manager).toBe(this.mockManager);
|
|
Expect((manager as any).accessors).toBe(this.mockManager.getAccessorManager());
|
|
Expect((manager as any).outboundMessageProviders).toBeDefined();
|
|
Expect((manager as any).outboundMessageProviders.size).toBe(0);
|
|
}
|
|
|
|
@Test()
|
|
public addProvider() {
|
|
const provider = TestData.getOutboundPhoneMessageProvider();
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
|
|
Expect(() => manager.addProvider('testing', provider)).not.toThrow();
|
|
Expect((manager as any).outboundMessageProviders.size).toBe(1);
|
|
Expect(() => manager.addProvider('failMePlease', provider)).toThrowError(
|
|
Error,
|
|
'App must exist in order for an outbound provider to be added.',
|
|
);
|
|
Expect((manager as any).outboundMessageProviders.size).toBe(1);
|
|
}
|
|
|
|
@Test()
|
|
public isAlreadyDefined() {
|
|
const provider = TestData.getOutboundPhoneMessageProvider();
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
|
|
Expect(manager.isAlreadyDefined('testing', 'phone')).toBe(false);
|
|
|
|
manager.addProvider('testing', provider);
|
|
|
|
Expect(manager.isAlreadyDefined('testing', 'phone')).toBe(true);
|
|
Expect(manager.isAlreadyDefined('testing', 'email')).toBe(false);
|
|
Expect(manager.isAlreadyDefined('another-app', 'phone')).toBe(false);
|
|
}
|
|
|
|
@Test()
|
|
public addProviderTwiceShouldOverwrite() {
|
|
const provider1 = TestData.getOutboundPhoneMessageProvider('provider1');
|
|
const provider2 = TestData.getOutboundPhoneMessageProvider('provider2');
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
|
|
manager.addProvider('testing', provider1);
|
|
const firstProviderInfo = (manager as any).outboundMessageProviders.get('testing').get('phone');
|
|
Expect(firstProviderInfo.provider.name).toBe('provider1');
|
|
|
|
// Adding a provider of the same type should overwrite the previous one
|
|
manager.addProvider('testing', provider2);
|
|
const secondProviderInfo = (manager as any).outboundMessageProviders.get('testing').get('phone');
|
|
Expect(secondProviderInfo.provider.name).toBe('provider2');
|
|
Expect((manager as any).outboundMessageProviders.get('testing').size).toBe(1);
|
|
}
|
|
|
|
@Test()
|
|
public addProviderWithoutPermission() {
|
|
const provider = TestData.getOutboundPhoneMessageProvider();
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
|
|
this.hasPermissionSpy.andReturn(false);
|
|
|
|
Expect(() => manager.addProvider('testing', provider)).toThrow();
|
|
}
|
|
|
|
@Test()
|
|
public ignoreAppsWithoutProviders() {
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
|
|
Expect(() => manager.registerProviders('non-existant')).not.toThrow();
|
|
}
|
|
|
|
@AsyncTest()
|
|
public async registerProviders() {
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
|
|
manager.addProvider('firstApp', TestData.getOutboundPhoneMessageProvider());
|
|
const appInfo = (manager as any).outboundMessageProviders.get('firstApp');
|
|
Expect(appInfo).toBeDefined();
|
|
const regInfo = appInfo.get('phone');
|
|
Expect(regInfo).toBeDefined();
|
|
|
|
Expect(regInfo.isRegistered).toBe(false);
|
|
await Expect(async () => manager.registerProviders('firstApp')).not.toThrowAsync();
|
|
Expect(regInfo.isRegistered).toBe(true);
|
|
}
|
|
|
|
@AsyncTest()
|
|
public async registerTwoProviders() {
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
|
|
manager.addProvider('firstApp', TestData.getOutboundPhoneMessageProvider());
|
|
manager.addProvider('firstApp', TestData.getOutboundEmailMessageProvider());
|
|
const firstApp = (manager as any).outboundMessageProviders.get('firstApp');
|
|
Expect(firstApp).toBeDefined();
|
|
const firstRegInfo = firstApp.get('phone');
|
|
Expect(firstRegInfo).toBeDefined();
|
|
const secondRegInfo = firstApp.get('email');
|
|
Expect(secondRegInfo).toBeDefined();
|
|
|
|
Expect(firstRegInfo.isRegistered).toBe(false);
|
|
Expect(secondRegInfo.isRegistered).toBe(false);
|
|
await Expect(async () => manager.registerProviders('firstApp')).not.toThrowAsync();
|
|
Expect(firstRegInfo.isRegistered).toBe(true);
|
|
Expect(secondRegInfo.isRegistered).toBe(true);
|
|
}
|
|
|
|
@AsyncTest()
|
|
public async registerProvidersFromMultipleApps() {
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
|
|
manager.addProvider('firstApp', TestData.getOutboundPhoneMessageProvider());
|
|
manager.addProvider('firstApp', TestData.getOutboundEmailMessageProvider());
|
|
manager.addProvider('secondApp', TestData.getOutboundPhoneMessageProvider('another-phone-provider'));
|
|
|
|
const firstApp = (manager as any).outboundMessageProviders.get('firstApp');
|
|
Expect(firstApp).toBeDefined();
|
|
const firstRegInfo = firstApp.get('phone');
|
|
const secondRegInfo = firstApp.get('email');
|
|
Expect(firstRegInfo).toBeDefined();
|
|
Expect(secondRegInfo).toBeDefined();
|
|
const secondApp = (manager as any).outboundMessageProviders.get('secondApp');
|
|
Expect(secondApp).toBeDefined();
|
|
const thirdRegInfo = secondApp.get('phone');
|
|
Expect(thirdRegInfo).toBeDefined();
|
|
|
|
Expect(firstRegInfo.isRegistered).toBe(false);
|
|
Expect(secondRegInfo.isRegistered).toBe(false);
|
|
await Expect(async () => manager.registerProviders('firstApp')).not.toThrowAsync();
|
|
Expect(firstRegInfo.isRegistered).toBe(true);
|
|
Expect(secondRegInfo.isRegistered).toBe(true);
|
|
Expect(thirdRegInfo.isRegistered).toBe(false);
|
|
await Expect(async () => manager.registerProviders('secondApp')).not.toThrowAsync();
|
|
Expect(thirdRegInfo.isRegistered).toBe(true);
|
|
}
|
|
|
|
@AsyncTest()
|
|
public async unregisterProviders() {
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
|
|
manager.addProvider('testing', TestData.getOutboundPhoneMessageProvider());
|
|
const regInfo = (manager as any).outboundMessageProviders.get('testing').get('phone');
|
|
await Expect(async () => manager.registerProviders('testing')).not.toThrowAsync();
|
|
|
|
await Expect(async () => manager.unregisterProviders('non-existant')).not.toThrowAsync();
|
|
Expect(regInfo.isRegistered).toBe(true);
|
|
await Expect(async () => manager.unregisterProviders('testing')).not.toThrowAsync();
|
|
Expect(regInfo.isRegistered).toBe(false);
|
|
// It should be removed from the map
|
|
Expect((manager as any).outboundMessageProviders.has('testing')).toBe(false);
|
|
}
|
|
|
|
@AsyncTest()
|
|
public async unregisterProvidersWithKeepReferences() {
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
|
|
manager.addProvider('testing', TestData.getOutboundPhoneMessageProvider());
|
|
const appInfo = (manager as any).outboundMessageProviders.get('testing');
|
|
const regInfo = appInfo.get('phone');
|
|
|
|
await Expect(async () => manager.registerProviders('testing')).not.toThrowAsync();
|
|
Expect(regInfo.isRegistered).toBe(true);
|
|
await Expect(async () => manager.unregisterProviders('testing', { keepReferences: true })).not.toThrowAsync();
|
|
Expect(regInfo.isRegistered).toBe(false);
|
|
// It should not be removed from the map
|
|
Expect((manager as any).outboundMessageProviders.has('testing')).toBe(true);
|
|
}
|
|
|
|
@Test()
|
|
public failToGetMetadataWithoutProvider() {
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
|
|
Expect(() => manager.getProviderMetadata('testing', 'phone')).toThrowError(Error, 'provider-not-registered');
|
|
|
|
manager.addProvider('testing', TestData.getOutboundPhoneMessageProvider());
|
|
|
|
Expect(() => manager.getProviderMetadata('testing', 'email')).toThrowError(Error, 'provider-not-registered');
|
|
}
|
|
|
|
@Test()
|
|
public getProviderMetadata() {
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
manager.addProvider('testing', TestData.getOutboundPhoneMessageProvider());
|
|
|
|
SpyOn(OutboundMessageProvider.prototype, 'runGetProviderMetadata').andReturn({
|
|
name: 'test-provider',
|
|
capabilities: ['sms'],
|
|
});
|
|
|
|
const metadata = manager.getProviderMetadata('testing', 'phone');
|
|
Expect(metadata).toEqual({
|
|
name: 'test-provider',
|
|
capabilities: ['sms'],
|
|
});
|
|
}
|
|
|
|
@Test()
|
|
public failToSendOutboundMessageWithoutProvider() {
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
const message = TestData.getOutboundMessage();
|
|
|
|
Expect(() => manager.sendOutboundMessage('testing', 'phone', message)).toThrowError(Error, 'provider-not-registered');
|
|
|
|
manager.addProvider('testing', TestData.getOutboundPhoneMessageProvider());
|
|
|
|
Expect(() => manager.sendOutboundMessage('testing', 'email', message)).toThrowError(Error, 'provider-not-registered');
|
|
}
|
|
|
|
@Test()
|
|
public sendOutboundMessage() {
|
|
const manager = new AppOutboundCommunicationProviderManager(this.mockManager);
|
|
manager.addProvider('testing', TestData.getOutboundPhoneMessageProvider());
|
|
|
|
const message = TestData.getOutboundMessage();
|
|
|
|
SpyOn(OutboundMessageProvider.prototype, 'runSendOutboundMessage').andReturn(Promise.resolve('message-id'));
|
|
|
|
const result = manager.sendOutboundMessage('testing', 'phone', message);
|
|
Expect(result).toBeDefined();
|
|
}
|
|
}
|
|
|