import { describe, it, expect, vi } from 'vitest'; import App from './app.js'; import * as getAppModule from '../helpers/get-app.js'; import * as appInfoConverterModule from '../helpers/app-info-converter.js'; describe('App model', () => { it('folderPath should return correct path', () => { expect(App.folderPath.endsWith('/packages/backend/src/apps')).toBe(true); }); it('list should have list of applications keys', () => { expect(App.list).toMatchSnapshot(); }); describe('findAll', () => { it('should return all applications', async () => { const apps = await App.findAll(); expect(apps.length).toBe(App.list.length); }); it('should return matching applications when name argument is given', async () => { const apps = await App.findAll('deepl'); expect(apps.length).toBe(1); expect(apps[0].key).toBe('deepl'); }); it('should return matching applications in plain JSON when stripFunc argument is true', async () => { const appFindOneByNameSpy = vi.spyOn(App, 'findOneByName'); await App.findAll('deepl', true); expect(appFindOneByNameSpy).toHaveBeenCalledWith('deepl', true); }); }); describe('findOneByName', () => { it('should return app info for given app name', async () => { const getAppSpy = vi .spyOn(getAppModule, 'default') .mockImplementation(() => 'mock-app'); const appInfoConverterSpy = vi .spyOn(appInfoConverterModule, 'default') .mockImplementation(() => 'app-info'); const app = await App.findOneByName('DeepL'); expect(getAppSpy).toHaveBeenCalledWith('deepl', false); expect(appInfoConverterSpy).toHaveBeenCalledWith('mock-app'); expect(app).toStrictEqual('app-info'); }); it('should return app info for given app name in plain JSON when stripFunc argument is true', async () => { const getAppSpy = vi .spyOn(getAppModule, 'default') .mockImplementation(() => 'mock-app'); const appInfoConverterSpy = vi .spyOn(appInfoConverterModule, 'default') .mockImplementation(() => 'app-info'); const app = await App.findOneByName('DeepL', true); expect(getAppSpy).toHaveBeenCalledWith('deepl', true); expect(appInfoConverterSpy).toHaveBeenCalledWith('mock-app'); expect(app).toStrictEqual('app-info'); }); }); describe('findOneByKey', () => { it('should return app info for given app key', async () => { const getAppSpy = vi .spyOn(getAppModule, 'default') .mockImplementation(() => 'mock-app'); const appInfoConverterSpy = vi .spyOn(appInfoConverterModule, 'default') .mockImplementation(() => 'app-info'); const app = await App.findOneByKey('deepl'); expect(getAppSpy).toHaveBeenCalledWith('deepl', false); expect(appInfoConverterSpy).toHaveBeenCalledWith('mock-app'); expect(app).toStrictEqual('app-info'); }); it('should return app info for given app key in plain JSON when stripFunc argument is true', async () => { const getAppSpy = vi .spyOn(getAppModule, 'default') .mockImplementation(() => 'mock-app'); const appInfoConverterSpy = vi .spyOn(appInfoConverterModule, 'default') .mockImplementation(() => 'app-info'); const app = await App.findOneByKey('deepl', true); expect(getAppSpy).toHaveBeenCalledWith('deepl', true); expect(appInfoConverterSpy).toHaveBeenCalledWith('mock-app'); expect(app).toStrictEqual('app-info'); }); }); describe('findAuthByKey', () => { it('should return app auth for given app key', async () => { const getAppSpy = vi .spyOn(getAppModule, 'default') .mockImplementation(() => ({ auth: 'mock-auth' })); const appInfoConverterSpy = vi .spyOn(appInfoConverterModule, 'default') .mockImplementation((input) => input); const appAuth = await App.findAuthByKey('deepl'); expect(getAppSpy).toHaveBeenCalledWith('deepl', false); expect(appInfoConverterSpy).toHaveBeenCalledWith({ auth: 'mock-auth' }); expect(appAuth).toStrictEqual('mock-auth'); }); it('should return app auth for given app key in plain JSON when stripFunc argument is true', async () => { const getAppSpy = vi .spyOn(getAppModule, 'default') .mockImplementation(() => ({ auth: 'mock-auth' })); const appInfoConverterSpy = vi .spyOn(appInfoConverterModule, 'default') .mockImplementation((input) => input); const appAuth = await App.findAuthByKey('deepl', true); expect(getAppSpy).toHaveBeenCalledWith('deepl', true); expect(appInfoConverterSpy).toHaveBeenCalledWith({ auth: 'mock-auth' }); expect(appAuth).toStrictEqual('mock-auth'); }); }); describe('findTriggersByKey', () => { it('should return app triggers for given app key', async () => { const getAppSpy = vi .spyOn(getAppModule, 'default') .mockImplementation(() => ({ triggers: 'mock-triggers' })); const appInfoConverterSpy = vi .spyOn(appInfoConverterModule, 'default') .mockImplementation((input) => input); const appTriggers = await App.findTriggersByKey('deepl'); expect(getAppSpy).toHaveBeenCalledWith('deepl', false); expect(appInfoConverterSpy).toHaveBeenCalledWith({ triggers: 'mock-triggers', }); expect(appTriggers).toStrictEqual('mock-triggers'); }); it('should return app triggers for given app key in plain JSON when stripFunc argument is true', async () => { const getAppSpy = vi .spyOn(getAppModule, 'default') .mockImplementation(() => ({ triggers: 'mock-triggers' })); const appInfoConverterSpy = vi .spyOn(appInfoConverterModule, 'default') .mockImplementation((input) => input); const appTriggers = await App.findTriggersByKey('deepl', true); expect(getAppSpy).toHaveBeenCalledWith('deepl', true); expect(appInfoConverterSpy).toHaveBeenCalledWith({ triggers: 'mock-triggers', }); expect(appTriggers).toStrictEqual('mock-triggers'); }); }); describe('findTriggerSubsteps', () => { it('should return app trigger substeps for given app key', async () => { const getAppSpy = vi .spyOn(getAppModule, 'default') .mockImplementation(() => ({ triggers: [{ key: 'mock-trigger', substeps: 'mock-substeps' }], })); const appInfoConverterSpy = vi .spyOn(appInfoConverterModule, 'default') .mockImplementation((input) => input); const appTriggerSubsteps = await App.findTriggerSubsteps( 'deepl', 'mock-trigger' ); expect(getAppSpy).toHaveBeenCalledWith('deepl', false); expect(appInfoConverterSpy).toHaveBeenCalledWith({ triggers: [{ key: 'mock-trigger', substeps: 'mock-substeps' }], }); expect(appTriggerSubsteps).toStrictEqual('mock-substeps'); }); it('should return app trigger substeps for given app key in plain JSON when stripFunc argument is true', async () => { const getAppSpy = vi .spyOn(getAppModule, 'default') .mockImplementation(() => ({ triggers: [{ key: 'mock-trigger', substeps: 'mock-substeps' }], })); const appInfoConverterSpy = vi .spyOn(appInfoConverterModule, 'default') .mockImplementation((input) => input); const appTriggerSubsteps = await App.findTriggerSubsteps( 'deepl', 'mock-trigger', true ); expect(getAppSpy).toHaveBeenCalledWith('deepl', true); expect(appInfoConverterSpy).toHaveBeenCalledWith({ triggers: [{ key: 'mock-trigger', substeps: 'mock-substeps' }], }); expect(appTriggerSubsteps).toStrictEqual('mock-substeps'); }); }); describe('findActionsByKey', () => { it('should return app actions for given app key', async () => { const getAppSpy = vi .spyOn(getAppModule, 'default') .mockImplementation(() => ({ actions: 'mock-actions' })); const appInfoConverterSpy = vi .spyOn(appInfoConverterModule, 'default') .mockImplementation((input) => input); const appActions = await App.findActionsByKey('deepl'); expect(getAppSpy).toHaveBeenCalledWith('deepl', false); expect(appInfoConverterSpy).toHaveBeenCalledWith({ actions: 'mock-actions', }); expect(appActions).toStrictEqual('mock-actions'); }); it('should return app actions for given app key in plain JSON when stripFunc argument is true', async () => { const getAppSpy = vi .spyOn(getAppModule, 'default') .mockImplementation(() => ({ actions: 'mock-actions' })); const appInfoConverterSpy = vi .spyOn(appInfoConverterModule, 'default') .mockImplementation((input) => input); const appActions = await App.findActionsByKey('deepl', true); expect(getAppSpy).toHaveBeenCalledWith('deepl', true); expect(appInfoConverterSpy).toHaveBeenCalledWith({ actions: 'mock-actions', }); expect(appActions).toStrictEqual('mock-actions'); }); }); describe('findActionSubsteps', () => { it('should return app action substeps for given app key', async () => { const getAppSpy = vi .spyOn(getAppModule, 'default') .mockImplementation(() => ({ actions: [{ key: 'mock-action', substeps: 'mock-substeps' }], })); const appInfoConverterSpy = vi .spyOn(appInfoConverterModule, 'default') .mockImplementation((input) => input); const appActionSubsteps = await App.findActionSubsteps( 'deepl', 'mock-action' ); expect(getAppSpy).toHaveBeenCalledWith('deepl', false); expect(appInfoConverterSpy).toHaveBeenCalledWith({ actions: [{ key: 'mock-action', substeps: 'mock-substeps' }], }); expect(appActionSubsteps).toStrictEqual('mock-substeps'); }); it('should return app action substeps for given app key in plain JSON when stripFunc argument is true', async () => { const getAppSpy = vi .spyOn(getAppModule, 'default') .mockImplementation(() => ({ actions: [{ key: 'mock-action', substeps: 'mock-substeps' }], })); const appInfoConverterSpy = vi .spyOn(appInfoConverterModule, 'default') .mockImplementation((input) => input); const appActionSubsteps = await App.findActionSubsteps( 'deepl', 'mock-action', true ); expect(getAppSpy).toHaveBeenCalledWith('deepl', true); expect(appInfoConverterSpy).toHaveBeenCalledWith({ actions: [{ key: 'mock-action', substeps: 'mock-substeps' }], }); expect(appActionSubsteps).toStrictEqual('mock-substeps'); }); }); describe('checkAppAndAction', () => { it('should return undefined when app and action exist', async () => { const findOneByKeySpy = vi .spyOn(App, 'findOneByKey') .mockImplementation(() => ({ actions: [ { key: 'translate-text', }, ], })); const appAndActionExist = await App.checkAppAndAction( 'deepl', 'translate-text' ); expect(findOneByKeySpy).toHaveBeenCalledWith('deepl'); expect(appAndActionExist).toBeUndefined(); }); it('should return undefined when app exists without action argument provided', async () => { const actionFindSpy = vi.fn(); const findOneByKeySpy = vi .spyOn(App, 'findOneByKey') .mockImplementation(() => ({ actions: { find: actionFindSpy, }, })); const appAndActionExist = await App.checkAppAndAction('deepl'); expect(findOneByKeySpy).toHaveBeenCalledWith('deepl'); expect(actionFindSpy).not.toHaveBeenCalled(); expect(appAndActionExist).toBeUndefined(); }); it('should throw an error when app exists, but action does not', async () => { const findOneByKeySpy = vi .spyOn(App, 'findOneByKey') .mockImplementation(() => ({ name: 'deepl' })); await expect(() => App.checkAppAndAction('deepl', 'non-existing-action') ).rejects.toThrowError( 'deepl does not have an action with the "non-existing-action" key!' ); expect(findOneByKeySpy).toHaveBeenCalledWith('deepl'); }); }); describe('checkAppAndTrigger', () => { it('should return undefined when app and trigger exist', async () => { const findOneByKeySpy = vi .spyOn(App, 'findOneByKey') .mockImplementation(() => ({ triggers: [ { key: 'catch-raw-webhook', }, ], })); const appAndTriggerExist = await App.checkAppAndTrigger( 'webhook', 'catch-raw-webhook' ); expect(findOneByKeySpy).toHaveBeenCalledWith('webhook'); expect(appAndTriggerExist).toBeUndefined(); }); it('should return undefined when app exists without trigger argument provided', async () => { const triggerFindSpy = vi.fn(); const findOneByKeySpy = vi .spyOn(App, 'findOneByKey') .mockImplementation(() => ({ actions: { find: triggerFindSpy, }, })); const appAndTriggerExist = await App.checkAppAndTrigger('webhook'); expect(findOneByKeySpy).toHaveBeenCalledWith('webhook'); expect(triggerFindSpy).not.toHaveBeenCalled(); expect(appAndTriggerExist).toBeUndefined(); }); it('should throw an error when app exists, but trigger does not', async () => { const findOneByKeySpy = vi .spyOn(App, 'findOneByKey') .mockImplementation(() => ({ name: 'webhook' })); await expect(() => App.checkAppAndTrigger('webhook', 'non-existing-trigger') ).rejects.toThrowError( 'webhook does not have a trigger with the "non-existing-trigger" key!' ); expect(findOneByKeySpy).toHaveBeenCalledWith('webhook'); }); }); });