From 0121eb21ef1fb2a5be2a02d7ad8c9602c2749013 Mon Sep 17 00:00:00 2001 From: Massimiliano Ziccardi Date: Wed, 16 Dec 2020 10:54:06 +0100 Subject: [PATCH] =?UTF-8?q?test:=20=F0=9F=92=8D=20added=20more=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/cmds/app-cmds/create.test.ts | 20 ++- test/cmds/app-cmds/delete.test.ts | 11 +- test/cmds/app-cmds/list.test.ts | 25 +--- test/cmds/app-cmds/rename.test.ts | 13 -- .../create-cmds/androidVariant.test.ts | 56 ++++++++ .../variants-cmds/create-cmds/iosCert.test.ts | 57 ++++++++ .../create-cmds/iosToken.test.ts | 59 ++++++++ .../create-cmds/webPushVariant.test.ts | 57 ++++++++ test/cmds/variants-cmds/create.test.ts | 61 -------- test/cmds/variants-cmds/delete.test.ts | 25 ---- .../handlers/AndroidVariantHandler.test.ts | 43 ------ .../handlers/VariantHandlerFactory.test.ts | 36 ----- .../handlers/WebPushVariantHandler.test.ts | 45 ------ .../handlers/iOSCertVariantHandler.test.ts | 44 ------ .../handlers/iOSTokenVariantHandler.test.ts | 45 ------ test/cmds/variants-cmds/list.test.ts | 18 +-- test/mocks/DataStore.ts | 68 ++++++++- test/mocks/UPSMock.ts | 134 ++++++++++++++---- test/mocks/applications.ts | 116 ++++++++++++--- test/mocks/auth.ts | 29 ++++ test/mocks/constants.ts | 22 +++ test/mocks/variants.ts | 118 +++++++++++++-- test/resources/mock-pkey.pem | 1 + test/resources/mockcert.p12 | 1 + 24 files changed, 673 insertions(+), 431 deletions(-) create mode 100644 test/cmds/variants-cmds/create-cmds/androidVariant.test.ts create mode 100644 test/cmds/variants-cmds/create-cmds/iosCert.test.ts create mode 100644 test/cmds/variants-cmds/create-cmds/iosToken.test.ts create mode 100644 test/cmds/variants-cmds/create-cmds/webPushVariant.test.ts delete mode 100644 test/cmds/variants-cmds/create.test.ts delete mode 100644 test/cmds/variants-cmds/handlers/AndroidVariantHandler.test.ts delete mode 100644 test/cmds/variants-cmds/handlers/VariantHandlerFactory.test.ts delete mode 100644 test/cmds/variants-cmds/handlers/WebPushVariantHandler.test.ts delete mode 100644 test/cmds/variants-cmds/handlers/iOSCertVariantHandler.test.ts delete mode 100644 test/cmds/variants-cmds/handlers/iOSTokenVariantHandler.test.ts create mode 100644 test/mocks/auth.ts create mode 100644 test/resources/mock-pkey.pem create mode 100644 test/resources/mockcert.p12 diff --git a/test/cmds/app-cmds/create.test.ts b/test/cmds/app-cmds/create.test.ts index bc79338..131276a 100644 --- a/test/cmds/app-cmds/create.test.ts +++ b/test/cmds/app-cmds/create.test.ts @@ -1,6 +1,6 @@ import {ConsoleMock} from '../../mocks'; import {handler} from '../../../src/cmds/app-cmds/create'; -import {initMockEngine} from '../../mocks/UPSMock'; +import {getAllApplications, initMockEngine} from '../../mocks/UPSMock'; import {IDGenerator} from '../../mocks/DataStore'; beforeEach(() => { @@ -21,20 +21,16 @@ describe('applications', () => { await handler({ url: 'http://localhost:9999', name: 'TEST-APP', + output: 'json', _: [], $0: '', }); - expect(ConsoleMock.log).toHaveBeenCalledTimes(2); - expect(ConsoleMock.log).toHaveBeenCalledWith( - 'Application created successfully' - ); - expect(ConsoleMock.log).toHaveBeenCalledWith( - `╔══════════╤══════════════════════════════════════╗ -║ NAME │ PUSH-APPLICATION-ID ║ -╟──────────┼──────────────────────────────────────╢ -║ TEST-APP │ ${appId} ║ -╚══════════╧══════════════════════════════════════╝ -` + + const testApp = getAllApplications().find( + app => app.pushApplicationID === appId ); + + expect(ConsoleMock.log).toHaveBeenCalledTimes(1); + expect(ConsoleMock.log).toHaveBeenCalledWith(JSON.stringify([testApp])); }); }); diff --git a/test/cmds/app-cmds/delete.test.ts b/test/cmds/app-cmds/delete.test.ts index 314e637..2d05829 100644 --- a/test/cmds/app-cmds/delete.test.ts +++ b/test/cmds/app-cmds/delete.test.ts @@ -2,7 +2,6 @@ import {Arguments} from 'yargs'; import {ConsoleMock} from '../../mocks'; import {handler} from '../../../src/cmds/app-cmds/delete'; -import * as inquirer from 'inquirer'; import { createApplications, getAllApplications, @@ -20,10 +19,6 @@ beforeEach(() => { ConsoleMock.init(); initMockEngine(); ConsoleMock.mockClear(); - const promptMock = (inquirer.prompt as unknown) as jest.Mock< - typeof inquirer.prompt - >; - promptMock.mockClear(); }); afterEach(() => { @@ -36,7 +31,7 @@ describe('Delete Application', () => { // @ts-ignore await handler({ url: 'http://localhost:9999', - appId: [''], + appId: '', _: [''], $0: '', } as Arguments); @@ -49,11 +44,11 @@ describe('Delete Application', () => { // @ts-ignore await handler({ url: 'http://localhost:9999', - appId: ['1234'], + name: 'bad name', _: [''], $0: '', } as Arguments); expect(ConsoleMock.log).toHaveBeenCalled(); - expect(ConsoleMock.log).toHaveBeenCalledWith('0 applications deleted'); + expect(ConsoleMock.log).toHaveBeenCalledWith('0 application(s) deleted'); }); }); diff --git a/test/cmds/app-cmds/list.test.ts b/test/cmds/app-cmds/list.test.ts index 3252b69..86c4c99 100644 --- a/test/cmds/app-cmds/list.test.ts +++ b/test/cmds/app-cmds/list.test.ts @@ -26,24 +26,12 @@ describe('applications', () => { const apps = getAllApplications(); // @ts-ignore - await handler({url: 'http://localhost:9999'}); + await handler({url: 'http://localhost:9999', output: 'json'}); + + const res = JSON.parse(ConsoleMock.log.mock.calls[0][0]); expect(ConsoleMock.log).toHaveBeenCalledTimes(1); - expect(ConsoleMock.log).toHaveBeenCalledWith( - `╔═══════╤══════════════════════════════════════╤══════════╤═══════════════╤═══════════════╗ -║ NAME │ PUSH-APPLICATION-ID │ VARIANTS │ INSTALLATIONS │ SENT-MESSAGES ║ -╟───────┼──────────────────────────────────────┼──────────┼───────────────┼───────────────╢ -║ ${apps[0].name} │ ${apps[0].pushApplicationID} │ 3 │ NaN │ NaN ║ -╟───────┼──────────────────────────────────────┼──────────┼───────────────┼───────────────╢ -║ ${apps[1].name} │ ${apps[1].pushApplicationID} │ 3 │ NaN │ NaN ║ -╟───────┼──────────────────────────────────────┼──────────┼───────────────┼───────────────╢ -║ ${apps[2].name} │ ${apps[2].pushApplicationID} │ 3 │ NaN │ NaN ║ -╟───────┼──────────────────────────────────────┼──────────┼───────────────┼───────────────╢ -║ ${apps[3].name} │ ${apps[3].pushApplicationID} │ 3 │ NaN │ NaN ║ -╟───────┼──────────────────────────────────────┼──────────┼───────────────┼───────────────╢ -║ ${apps[4].name} │ ${apps[4].pushApplicationID} │ 3 │ NaN │ NaN ║ -╚═══════╧══════════════════════════════════════╧══════════╧═══════════════╧═══════════════╝ -` - ); + expect(res).toMatchObject(apps); + expect(res.length).toEqual(apps.length); }); it('Should return "no applications found"', async () => { @@ -51,9 +39,10 @@ describe('applications', () => { // @ts-ignore await handler({ url: 'http://localhost:9999', + output: 'json', filter: JSON.stringify(filter), }); expect(ConsoleMock.log).toHaveBeenCalledTimes(1); - expect(ConsoleMock.log).toHaveBeenCalledWith('No applications found'); + expect(ConsoleMock.log).toHaveBeenCalledWith(JSON.stringify([])); }); }); diff --git a/test/cmds/app-cmds/rename.test.ts b/test/cmds/app-cmds/rename.test.ts index b61210b..1a7fbb4 100644 --- a/test/cmds/app-cmds/rename.test.ts +++ b/test/cmds/app-cmds/rename.test.ts @@ -1,28 +1,15 @@ import {ConsoleMock} from '../../mocks'; import {handler} from '../../../src/cmds/app-cmds/rename'; -import {UPSAdminClientFactory} from '../../../src/utils/UPSAdminClientFactory'; -import * as inquirer from 'inquirer'; import { createApplications, getAllApplications, initMockEngine, } from '../../mocks/UPSMock'; -jest.mock('inquirer', () => ({ - prompt: jest - .fn() - .mockReturnValueOnce({confirm: true}) - .mockReturnValue({confirm: false}), -})); - beforeEach(() => { ConsoleMock.init(); initMockEngine(); ConsoleMock.mockClear(); - const promptMock = (inquirer.prompt as unknown) as jest.Mock< - typeof inquirer.prompt - >; - promptMock.mockClear(); }); afterEach(() => { diff --git a/test/cmds/variants-cmds/create-cmds/androidVariant.test.ts b/test/cmds/variants-cmds/create-cmds/androidVariant.test.ts new file mode 100644 index 0000000..3918827 --- /dev/null +++ b/test/cmds/variants-cmds/create-cmds/androidVariant.test.ts @@ -0,0 +1,56 @@ +/* eslint-disable @typescript-eslint/ban-ts-ignore */ +import {ConsoleMock} from '../../../mocks'; +import { + createApplication, + getAllApplications, + initMockEngine, +} from '../../../mocks/UPSMock'; +import {IDGenerator} from '../../../mocks/DataStore'; +import {AndroidVariant} from '@aerogear/unifiedpush-admin-client'; +import {handler} from '../../../../src/cmds/variants-cmds/create-cmds/andoridVariant'; + +beforeEach(() => { + // Clear all instances and calls to constructor and all methods: + initMockEngine(); + createApplications(10); + ConsoleMock.init(); + ConsoleMock.mockClear(); +}); + +afterEach(() => { + ConsoleMock.uninstall(); +}); + +const createApplications = (howmany: number) => { + for (let i = 0; i < howmany; i++) { + createApplication(`TEST APP-${i}`); + } +}; + +describe('variants create', () => { + it('Should create an android variants', async () => { + const app = getAllApplications()[3]; + const variantDef = { + name: 'TEST-ANDROID', + type: 'android', + googleKey: 'TEST-GOOGLE-KEY', + projectNumber: 'TEST-PROJECT-NUMBER', + } as AndroidVariant; + + const argv = { + url: 'http://localhost:9999', + appId: app.pushApplicationID, + output: 'json', + ...variantDef, + }; + + const variantID = IDGenerator.peek(); + + // @ts-ignore + await handler(argv); + expect(ConsoleMock.log).toHaveBeenCalledTimes(1); + expect(JSON.parse(ConsoleMock.log.mock.calls[0][0])).toEqual([ + app.variants?.find(v => v.variantID === variantID), + ]); + }); +}); diff --git a/test/cmds/variants-cmds/create-cmds/iosCert.test.ts b/test/cmds/variants-cmds/create-cmds/iosCert.test.ts new file mode 100644 index 0000000..fb78203 --- /dev/null +++ b/test/cmds/variants-cmds/create-cmds/iosCert.test.ts @@ -0,0 +1,57 @@ +/* eslint-disable @typescript-eslint/ban-ts-ignore */ +import {ConsoleMock} from '../../../mocks'; +import { + createApplication, + getAllApplications, + initMockEngine, +} from '../../../mocks/UPSMock'; +import {IDGenerator} from '../../../mocks/DataStore'; +import {IOSVariantDefinition} from '@aerogear/unifiedpush-admin-client'; +import {handler} from '../../../../src/cmds/variants-cmds/create-cmds/iosCert'; + +beforeEach(() => { + // Clear all instances and calls to constructor and all methods: + initMockEngine(); + createApplications(10); + ConsoleMock.init(); + ConsoleMock.mockClear(); +}); + +afterEach(() => { + ConsoleMock.uninstall(); +}); + +const createApplications = (howmany: number) => { + for (let i = 0; i < howmany; i++) { + createApplication(`TEST APP-${i}`); + } +}; + +describe('variants create', () => { + it('Should create an ios variants', async () => { + const app = getAllApplications()[3]; + const variantDef = { + name: 'TEST-IOS', + type: 'ios', + certificate: 'test/resources/mockcert.p12', + passphrase: 'PASSWORD', + production: false, + } as IOSVariantDefinition; + + const argv = { + url: 'http://localhost:9999', + appId: app.pushApplicationID, + output: 'json', + ...variantDef, + }; + + const variantID = IDGenerator.peek(); + + // @ts-ignore + await handler(argv); + expect(ConsoleMock.log).toHaveBeenCalledTimes(1); + expect(JSON.parse(ConsoleMock.log.mock.calls[0][0])).toEqual([ + app.variants?.find(v => v.variantID === variantID), + ]); + }); +}); diff --git a/test/cmds/variants-cmds/create-cmds/iosToken.test.ts b/test/cmds/variants-cmds/create-cmds/iosToken.test.ts new file mode 100644 index 0000000..6eeabc1 --- /dev/null +++ b/test/cmds/variants-cmds/create-cmds/iosToken.test.ts @@ -0,0 +1,59 @@ +/* eslint-disable @typescript-eslint/ban-ts-ignore */ +import {ConsoleMock} from '../../../mocks'; +import { + createApplication, + getAllApplications, + initMockEngine, +} from '../../../mocks/UPSMock'; +import {IDGenerator} from '../../../mocks/DataStore'; +import {IOSTokenVariantDefinition} from '@aerogear/unifiedpush-admin-client'; +import {handler} from '../../../../src/cmds/variants-cmds/create-cmds/iosToken'; + +beforeEach(() => { + // Clear all instances and calls to constructor and all methods: + initMockEngine(); + createApplications(10); + ConsoleMock.init(); + ConsoleMock.mockClear(); +}); + +afterEach(() => { + ConsoleMock.uninstall(); +}); + +const createApplications = (howmany: number) => { + for (let i = 0; i < howmany; i++) { + createApplication(`TEST APP-${i}`); + } +}; + +describe('variants create', () => { + it('Should create an ios-token variants', async () => { + const app = getAllApplications()[3]; + const variantDef = { + name: 'TEST-IOS', + type: 'ios_token', + production: false, + teamId: 'team', + keyId: 'test-key', + bundleId: 'bundle-id', + privateKey: 'test/resources/mock-pkey.pem', + } as IOSTokenVariantDefinition; + + const argv = { + url: 'http://localhost:9999', + appId: app.pushApplicationID, + output: 'json', + ...variantDef, + }; + + const variantID = IDGenerator.peek(); + // @ts-ignore + await handler(argv); + + const newVariant = app.variants?.find(v => v.variantID === variantID)!; + expect(ConsoleMock.log).toHaveBeenCalledTimes(1); + expect(JSON.parse(ConsoleMock.log.mock.calls[0][0])).toEqual([newVariant]); + expect(newVariant.type).toEqual('ios_token'); + }); +}); diff --git a/test/cmds/variants-cmds/create-cmds/webPushVariant.test.ts b/test/cmds/variants-cmds/create-cmds/webPushVariant.test.ts new file mode 100644 index 0000000..5c433dd --- /dev/null +++ b/test/cmds/variants-cmds/create-cmds/webPushVariant.test.ts @@ -0,0 +1,57 @@ +/* eslint-disable @typescript-eslint/ban-ts-ignore */ +import {ConsoleMock} from '../../../mocks'; +import { + createApplication, + getAllApplications, + initMockEngine, +} from '../../../mocks/UPSMock'; +import {IDGenerator} from '../../../mocks/DataStore'; +import {WebPushVariantDefinition} from '@aerogear/unifiedpush-admin-client'; +import {handler} from '../../../../src/cmds/variants-cmds/create-cmds/webpushVariant'; + +beforeEach(() => { + // Clear all instances and calls to constructor and all methods: + initMockEngine(); + createApplications(10); + ConsoleMock.init(); + ConsoleMock.mockClear(); +}); + +afterEach(() => { + ConsoleMock.uninstall(); +}); + +const createApplications = (howmany: number) => { + for (let i = 0; i < howmany; i++) { + createApplication(`TEST APP-${i}`); + } +}; + +describe('webpush variants create', () => { + it('Should create an web_push variants', async () => { + const app = getAllApplications()[3]; + const variantDef = { + name: 'TEST-WEBPUSH', + type: 'web_push', + publicKey: 'public key', + privateKey: 'private key', + alias: 'mailto:test@aerogear.com', + } as WebPushVariantDefinition; + + const argv = { + url: 'http://localhost:9999', + appId: app.pushApplicationID, + output: 'json', + ...variantDef, + }; + + const variantID = IDGenerator.peek(); + // @ts-ignore + await handler(argv); + + const newVariant = app.variants?.find(v => v.variantID === variantID)!; + expect(ConsoleMock.log).toHaveBeenCalledTimes(1); + expect(JSON.parse(ConsoleMock.log.mock.calls[0][0])).toEqual([newVariant]); + expect(newVariant.type).toEqual('web_push'); + }); +}); diff --git a/test/cmds/variants-cmds/create.test.ts b/test/cmds/variants-cmds/create.test.ts deleted file mode 100644 index 37d5b3c..0000000 --- a/test/cmds/variants-cmds/create.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* eslint-disable @typescript-eslint/ban-ts-ignore */ -import {ConsoleMock} from '../../mocks'; -import {handler} from '../../../src/cmds/variants-cmds/create'; -import {AndroidVariant} from '@aerogear/unifiedpush-admin-client'; -import { - createApplication, - getAllApplications, - initMockEngine, -} from '../../mocks/UPSMock'; -import {IDGenerator} from '../../mocks/DataStore'; - -beforeEach(() => { - // Clear all instances and calls to constructor and all methods: - initMockEngine(); - createApplications(10); - ConsoleMock.init(); - ConsoleMock.mockClear(); -}); - -afterEach(() => { - ConsoleMock.uninstall(); -}); - -const createApplications = (howmany: number) => { - for (let i = 0; i < howmany; i++) { - createApplication(`TEST APP-${i}`); - } -}; - -describe('variants create', () => { - it('Should create an android variants', async () => { - const app = getAllApplications()[3]; - const variantDef = { - name: 'TEST-ANDROID', - type: 'android', - googleKey: 'TEST-GOOGLE-KEY', - projectNumber: 'TEST-PROJECT-NUMBER', - } as AndroidVariant; - - const argv = { - url: 'http://localhost:9999', - appId: app.pushApplicationID, - def: JSON.stringify(variantDef), - }; - - const variantID = IDGenerator.peek(); - - // @ts-ignore - await handler(argv); - expect(ConsoleMock.log).toHaveBeenCalledTimes(2); - expect(ConsoleMock.log).toHaveBeenCalledWith('Variant created'); - expect(ConsoleMock.log).toHaveBeenCalledWith( - `╔══════════════╤══════════════════════════════════════╤═════════╗ -║ NAME │ VARIANT-ID │ TYPE ║ -╟──────────────┼──────────────────────────────────────┼─────────╢ -║ TEST-ANDROID │ ${variantID} │ android ║ -╚══════════════╧══════════════════════════════════════╧═════════╝ -` - ); - }); -}); diff --git a/test/cmds/variants-cmds/delete.test.ts b/test/cmds/variants-cmds/delete.test.ts index a8b9ecb..418055f 100644 --- a/test/cmds/variants-cmds/delete.test.ts +++ b/test/cmds/variants-cmds/delete.test.ts @@ -2,29 +2,17 @@ import {Arguments} from 'yargs'; import {ConsoleMock} from '../../mocks'; import {handler} from '../../../src/cmds/variants-cmds/delete'; -import * as inquirer from 'inquirer'; import { createApplications, getAllApplications, initMockEngine, } from '../../mocks/UPSMock'; -jest.mock('inquirer', () => ({ - prompt: jest - .fn() - .mockReturnValueOnce({confirm: true}) - .mockReturnValue({confirm: false}), -})); - beforeEach(() => { initMockEngine(); ConsoleMock.init(); // Clear all instances and calls to constructor and all methods: ConsoleMock.mockClear(); - const promptMock = (inquirer.prompt as unknown) as jest.Mock< - typeof inquirer.prompt - >; - promptMock.mockClear(); }); afterEach(() => { @@ -50,17 +38,4 @@ describe('variants delete', () => { `${variantCount} variant(s) deleted` ); }); - - it('Should cancel deletion', async () => { - createApplications({}); - const testApp = getAllApplications()[3]; - // @ts-ignore - await handler({ - url: 'http://localhost:9999', - appId: testApp.pushApplicationID, - _: [''], - $0: '', - } as Arguments); - expect(ConsoleMock.log).not.toHaveBeenCalled(); - }); }); diff --git a/test/cmds/variants-cmds/handlers/AndroidVariantHandler.test.ts b/test/cmds/variants-cmds/handlers/AndroidVariantHandler.test.ts deleted file mode 100644 index f77967a..0000000 --- a/test/cmds/variants-cmds/handlers/AndroidVariantHandler.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -import {AndroidVariant} from '@aerogear/unifiedpush-admin-client'; -import {AndroidVariantHandler} from '../../../../src/cmds/variants-cmds/handlers/AndroidVariantHandler'; -import { - createApplications, - getAllApplications, - initMockEngine, -} from '../../../mocks/UPSMock'; - -beforeEach(() => { - initMockEngine(); -}); - -describe('AndroidVariantHandler', () => { - it('Should have everything to create an AndroidVariant', async () => { - createApplications({}); - const testApp = getAllApplications()[6]; - - const handler = new AndroidVariantHandler(); - const variant = (await handler.handle( - { - 'auth-type': 'basic', - url: 'http://localhost:9999', - appId: testApp.pushApplicationID, - _: [''], - $0: '', - }, - { - name: 'test', - googleKey: 'TEST-GOOGLE-KEY', - projectNumber: 'TEST-PRJ-NUMBER', - developer: 'TEST-DEVELOPER', - type: 'android', - } - )) as AndroidVariant; - expect(variant).toBeDefined(); - expect(variant.name).toEqual('test'); - expect(variant.type).toEqual('android'); - //expect(variant.variantID).toEqual('TEST-ID'); - expect(variant.developer).toEqual('TEST-DEVELOPER'); - expect(variant.googleKey).toEqual('TEST-GOOGLE-KEY'); - expect(variant.projectNumber).toEqual('TEST-PRJ-NUMBER'); - }); -}); diff --git a/test/cmds/variants-cmds/handlers/VariantHandlerFactory.test.ts b/test/cmds/variants-cmds/handlers/VariantHandlerFactory.test.ts deleted file mode 100644 index f808856..0000000 --- a/test/cmds/variants-cmds/handlers/VariantHandlerFactory.test.ts +++ /dev/null @@ -1,36 +0,0 @@ -import {VariantHandlerFactory} from '../../../../src/cmds/variants-cmds/handlers'; -import {AndroidVariantHandler} from '../../../../src/cmds/variants-cmds/handlers/AndroidVariantHandler'; -import {IOSCertVariantHandler} from '../../../../src/cmds/variants-cmds/handlers/iOSCertVariantHandler'; -import {IOSTokenVariantHandler} from '../../../../src/cmds/variants-cmds/handlers/iOSTokenVariantHandler'; -import {WebPushVariantHandler} from '../../../../src/cmds/variants-cmds/handlers/WebPushVariantHandler'; - -describe('Variant Handler Factory', () => { - it('Should return an AndroidVariantHandler', () => { - expect(VariantHandlerFactory.getHandler('android')).toBeInstanceOf( - AndroidVariantHandler - ); - }); - it('Should return an IOSCertVariantHandler', () => { - expect(VariantHandlerFactory.getHandler('ios')).toBeInstanceOf( - IOSCertVariantHandler - ); - }); - - it('Should return an IOSTokenVariantHandler', () => { - expect(VariantHandlerFactory.getHandler('ios_token')).toBeInstanceOf( - IOSTokenVariantHandler - ); - }); - - it('Should return an WebPushVariantHandler', () => { - expect(VariantHandlerFactory.getHandler('web_push')).toBeInstanceOf( - WebPushVariantHandler - ); - }); - - it('Should throw an error', () => { - expect(() => VariantHandlerFactory.getHandler('bad_variant')).toThrowError( - "Unknown variant type 'bad_variant'" - ); - }); -}); diff --git a/test/cmds/variants-cmds/handlers/WebPushVariantHandler.test.ts b/test/cmds/variants-cmds/handlers/WebPushVariantHandler.test.ts deleted file mode 100644 index 0004bec..0000000 --- a/test/cmds/variants-cmds/handlers/WebPushVariantHandler.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import {WebPushVariant} from '@aerogear/unifiedpush-admin-client'; -import {WebPushVariantHandler} from '../../../../src/cmds/variants-cmds/handlers/WebPushVariantHandler'; -import { - createApplications, - getAllApplications, - initMockEngine, -} from '../../../mocks/UPSMock'; - -beforeEach(() => { - initMockEngine(); -}); - -describe('WebPushVariantHandler', () => { - it('Should have everything to create a WebPushVariant', async () => { - createApplications({}); - const testApp = getAllApplications()[8]; - const handler = new WebPushVariantHandler(); - const variant = (await handler.handle( - { - 'auth-type': 'basic', - url: 'http://localhost:9999', - appId: testApp.pushApplicationID, - _: [''], - $0: '', - }, - { - name: 'test', - alias: 'mailto:test@redhat.com', - developer: 'TEST-DEVELOPER', - privateKey: 'ABSBSHDBDSBDS', - publicKey: 'SJGSJFGKDSJGFKS', - type: 'web_push', - } as WebPushVariant - )) as WebPushVariant; - expect(variant).toBeDefined(); - expect(variant.name).toEqual('test'); - expect(variant.alias).toEqual('mailto:test@redhat.com'); - expect(variant.type).toEqual('web_push'); - expect(variant.developer).toEqual('TEST-DEVELOPER'); - expect(variant.privateKey).toBeDefined(); - expect(variant.privateKey.length).toBeGreaterThan(1); - expect(variant.publicKey).toBeDefined(); - expect(variant.publicKey.length).toBeGreaterThan(1); - }); -}); diff --git a/test/cmds/variants-cmds/handlers/iOSCertVariantHandler.test.ts b/test/cmds/variants-cmds/handlers/iOSCertVariantHandler.test.ts deleted file mode 100644 index 6490dc3..0000000 --- a/test/cmds/variants-cmds/handlers/iOSCertVariantHandler.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -import {IOSVariant} from '@aerogear/unifiedpush-admin-client'; -import {IOSCertVariantHandler} from '../../../../src/cmds/variants-cmds/handlers/iOSCertVariantHandler'; -import { - createApplications, - getAllApplications, - initMockEngine, -} from '../../../mocks/UPSMock'; - -beforeEach(() => { - // Clear all instances and calls to constructor and all methods: - initMockEngine(); -}); - -describe('IOSCertVariantHandler', () => { - it('Should have everything to create a iOSVariant', async () => { - createApplications({}); - const testApp = getAllApplications()[8]; - const handler = new IOSCertVariantHandler(); - const variant = (await handler.handle( - { - 'auth-type': 'basic', - url: 'http://localhost:9999', - appId: testApp.pushApplicationID, - _: [''], - $0: '', - }, - { - name: 'test-ios', - certificate: '/path/to/cert.p12', - password: 'password', - production: false, - developer: 'TEST-DEVELOPER', - type: 'ios', - } - )) as IOSVariant; - expect(variant).toBeDefined(); - expect(variant.name).toEqual('test-ios'); - expect(variant.type).toEqual('ios'); - expect(variant.certificate).toEqual('/path/to/cert.p12'); - expect(variant.password).toEqual('password'); - expect(variant.developer).toEqual('TEST-DEVELOPER'); - expect(variant.production).toBe(false); - }); -}); diff --git a/test/cmds/variants-cmds/handlers/iOSTokenVariantHandler.test.ts b/test/cmds/variants-cmds/handlers/iOSTokenVariantHandler.test.ts deleted file mode 100644 index eeae9bd..0000000 --- a/test/cmds/variants-cmds/handlers/iOSTokenVariantHandler.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import {IOSTokenVariant} from '@aerogear/unifiedpush-admin-client'; -import {IOSTokenVariantHandler} from '../../../../src/cmds/variants-cmds/handlers/iOSTokenVariantHandler'; -import { - createApplications, - getAllApplications, - initMockEngine, -} from '../../../mocks/UPSMock'; - -beforeEach(() => { - initMockEngine(); -}); - -describe('IOSTokenVariantHandler', () => { - it('Should have everything to create a iOSTokenVariant', async () => { - createApplications({}); - const testApp = getAllApplications()[3]; - const handler = new IOSTokenVariantHandler(); - const variant = (await handler.handle( - { - 'auth-type': 'basic', - url: 'http://localhost:9999', - appId: testApp.pushApplicationID, - _: [''], - $0: '', - }, - { - name: 'test-ios-token', - teamId: 'MyTeamID', - keyId: 'MyKeyID', - bundleId: 'org.aerogear', - type: 'ios_token', - privateKey: '/path/to/key', - developer: 'TEST-DEVELOPER', - production: false, - } - )) as IOSTokenVariant; - expect(variant).toBeDefined(); - expect(variant.name).toEqual('test-ios-token'); - expect(variant.type).toEqual('ios_token'); - expect(variant.teamId).toEqual('MyTeamID'); - expect(variant.keyId).toEqual('MyKeyID'); - expect(variant.bundleId).toEqual('org.aerogear'); - expect(variant.developer).toEqual('TEST-DEVELOPER'); - }); -}); diff --git a/test/cmds/variants-cmds/list.test.ts b/test/cmds/variants-cmds/list.test.ts index 9bda2ca..67ad499 100644 --- a/test/cmds/variants-cmds/list.test.ts +++ b/test/cmds/variants-cmds/list.test.ts @@ -25,25 +25,20 @@ describe('variants list', () => { createApplications({variantCount: 2, variantType: 'android'}); const testApp = getAllApplications()[2]; - const expectedResult = `╔═══════╤══════════════════════════════════════╤═════════╗ -║ NAME │ VARIANT-ID │ TYPE ║ -╟───────┼──────────────────────────────────────┼─────────╢ -║ ${testApp.variants![0].name} │ ${testApp.variants![0].variantID} │ android ║ -╟───────┼──────────────────────────────────────┼─────────╢ -║ ${testApp.variants![1].name} │ ${testApp.variants![1].variantID} │ android ║ -╚═══════╧══════════════════════════════════════╧═════════╝ -`; // @ts-ignore await handler({ url: 'http://localhost:9999', appId: testApp.pushApplicationID, + output: 'json', _: [''], $0: '', } as Arguments); expect(ConsoleMock.log).toHaveBeenCalled(); - expect(ConsoleMock.log).toHaveBeenCalledWith(expectedResult); + expect(ConsoleMock.log).toHaveBeenCalledWith( + JSON.stringify(testApp.variants) + ); }); - it('Should return "no variants found"', async () => { + it('Should return empty result', async () => { createApplications({}); const testApp = getAllApplications()[3]; deleteApplication(testApp.pushApplicationID); @@ -54,10 +49,11 @@ describe('variants list', () => { url: 'http://localhost:9999', appId: testApp.pushApplicationID, filter: JSON.stringify(filter), + output: 'json', _: [''], $0: '', } as Arguments); expect(ConsoleMock.log).toHaveBeenCalled(); - expect(ConsoleMock.log).toHaveBeenCalledWith('No variants found'); + expect(ConsoleMock.log).toHaveBeenCalledWith(JSON.stringify([])); }); }); diff --git a/test/mocks/DataStore.ts b/test/mocks/DataStore.ts index 63e8142..4ad1272 100644 --- a/test/mocks/DataStore.ts +++ b/test/mocks/DataStore.ts @@ -1,14 +1,15 @@ +import {Guid} from 'guid-typescript'; import { AndroidVariant, IOSTokenVariant, IOSVariant, PushApplication, + PushApplicationDefinition, Variant, WebPushVariant, } from '@aerogear/unifiedpush-admin-client'; -import {Guid} from 'guid-typescript'; +import {FlatPushMessageInformation} from '@aerogear/unifiedpush-admin-client/dist/src/commands/metrics/LoadMetricsCommand'; import {VariantDefinition} from '@aerogear/unifiedpush-admin-client/dist/src/commands/variants/Variant'; - export class IDGenerator { static nextid?: string; @@ -31,12 +32,54 @@ export class IDGenerator { export class DataStore { private appList: PushApplication[] = []; + private appMetrics: {[key: string]: FlatPushMessageInformation[]} = {}; + public readonly reset = (): void => { + this.appList = []; + }; + public readonly getAllApps = (): PushApplication[] => this.appList; + public readonly getAppMetrics = ( + appId: string, + page: number, + perPage: number, + sorting: string, + search: string + ): FlatPushMessageInformation[] => { + const sort = ( + ary: FlatPushMessageInformation[] + ): FlatPushMessageInformation[] => + ary.sort( + (a: FlatPushMessageInformation, b: FlatPushMessageInformation) => + (a.submitDate! < b.submitDate! ? -1 : 1) * + (sorting === 'asc' ? 1 : -1) + ); - public readonly reset = () => (this.appList = []); - public readonly getAllApps = () => this.appList; + const allMetrics = sort( + (this.appMetrics[appId] || []).filter( + metric => metric.rawJsonMessage.indexOf(search) !== -1 + ) + ); + + const res = + page === -1 + ? allMetrics + : paginate(allMetrics, page, perPage); + return res; + }; + + public readonly generateMetrics = (appId: string): void => { + this.appMetrics[appId] = this.appMetrics[appId] || []; + this.appMetrics[appId].push({ + pushApplicationId: appId, + rawJsonMessage: '{"key": "value"}', + ipAddress: '127.0.0.1', + clientIdentifier: Guid.create().toString(), + submitDate: getRandomDate(), + }); + }; public readonly createApp = ( name: string, + appDef: PushApplicationDefinition = {}, persist = false ): PushApplication => { const app = { @@ -44,6 +87,7 @@ export class DataStore { masterSecret: Guid.create().toString(), developer: 'test developer', name, + ...appDef, }; if (persist) { @@ -112,6 +156,8 @@ export class DataStore { secret: Guid.create().toString(), alias: 'mailto:test@redhat.com', type: 'web_push', + publicKey: Guid.create().toString(), + privateKey: Guid.create().toString(), ...def, } as WebPushVariant; } @@ -124,15 +170,23 @@ export class DataStore { return variant!; }; - setAppList(pushApplications: PushApplication[]) { + setAppList(pushApplications: PushApplication[]): void { this.appList = pushApplications; } - getApp(appId: string) { + getApp(appId: string): PushApplication | undefined { return this.appList.find(app => app.pushApplicationID === appId); } - deleteApplication(appId: string) { + deleteApplication(appId: string): void { this.appList = this.appList.filter(app => app.pushApplicationID !== appId); } } + +const getRandomDate = ( + from: Date = new Date(2000, 0, 1), + to: Date = new Date(2020, 0, 1) +) => new Date(from.getTime() + Math.random() * (to.getTime() - from.getTime())); + +const paginate = (ary: T[], pageNumber: number, pageSize: number): T[] => + ary.slice(pageNumber * pageSize, (pageNumber + 1) * pageSize); diff --git a/test/mocks/UPSMock.ts b/test/mocks/UPSMock.ts index cd85667..e649aec 100644 --- a/test/mocks/UPSMock.ts +++ b/test/mocks/UPSMock.ts @@ -1,40 +1,77 @@ import * as nock from 'nock'; import {DataStore} from './DataStore'; import {ApplicationsMock} from './applications'; -import {VARIANTS} from './constants'; +import {AuthMock} from './auth'; +import {UPS_URL, VARIANTS} from './constants'; +import { + PushApplication, + PushApplicationDefinition, + Variant, +} from '@aerogear/unifiedpush-admin-client'; +import {FlatPushMessageInformation} from '@aerogear/unifiedpush-admin-client/dist/src/commands/metrics/LoadMetricsCommand'; +import {VariantDefinition} from '@aerogear/unifiedpush-admin-client/dist/src/commands/variants/Variant'; const datastore = new DataStore(); let applicationMocks: ApplicationsMock | undefined = undefined; -export const initMockEngine = () => { +export const initMockEngine = (basePath = UPS_URL): void => { datastore.reset(); nock.cleanAll(); - applicationMocks = new ApplicationsMock(datastore); + applicationMocks = new ApplicationsMock(datastore, basePath); + new AuthMock(basePath); }; // applications mocks -export const createApplication = (name: string) => - applicationMocks!.createApplication(datastore, name); - -export const getAllApplications = () => datastore.getAllApps(); +export const createApplication = ( + name: string, + appDef: PushApplicationDefinition = {} +): PushApplication => + applicationMocks!.createApplication(datastore, name, appDef); +export const getAllApplications = (): PushApplication[] => + datastore.getAllApps(); +export const getAppMetrics = ( + appId: string, + page = -1, + perPage = 10, + sort = 'desc', + search = '' +): FlatPushMessageInformation[] => + datastore.getAppMetrics(appId, page, perPage, sort, search); // variants mocks export const createVariant = ( appId: string, name: string, - variantType: string -) => applicationMocks!.createVariant(appId, name, variantType); + variantType: string, + def: VariantDefinition = {} +): Variant => applicationMocks!.createVariant(appId, name, variantType, def); -export const deleteApplication = (id: string) => +export const deleteApplication = (id: string): void => datastore.deleteApplication(id); -interface CreateAppParams { - appCount?: number; +interface SharedVariantsParams { variantCount?: number; - appNamePrefix?: string; variantNamePrefix?: string; variantType?: string; minVariantCount?: number; + variantDef?: VariantDefinition; +} + +interface CreateVariantsParams extends SharedVariantsParams { + appId: string; +} + +interface CreateAppParams extends SharedVariantsParams { + appCount?: number; + appDef?: PushApplicationDefinition; + appNamePrefix?: string; +} + +interface CreateMetricsParams { + appId: string; + count?: number; + minCount?: number; + maxCount?: number; } export const createApplications = ({ @@ -44,26 +81,65 @@ export const createApplications = ({ variantNamePrefix = 'VAR-', variantType = undefined, minVariantCount = 3, -}: CreateAppParams) => { + appDef = {}, + variantDef = {}, +}: CreateAppParams = {}): void => { + for (let i = 0; i < appCount; i++) { + const app = createApplication(`${appNamePrefix}${i}`, appDef); + createVariants({ + appId: app.pushApplicationID, + variantCount, + minVariantCount, + variantNamePrefix, + variantType, + variantDef, + }); + } +}; + +export const createMetrics = ({ + appId, + count = -1, + minCount = 3, + maxCount = 50, +}: CreateMetricsParams): void => { + const metricsCount = + count === -1 ? Math.ceil(Math.random() * maxCount) + minCount : count; + + for (let i = 0; i < metricsCount; i++) { + datastore.generateMetrics(appId); + } +}; +export const createVariants = ({ + variantCount = 10, + variantNamePrefix = 'VAR-', + variantType = undefined, + minVariantCount = 3, + appId, + variantDef = {}, +}: CreateVariantsParams): Variant[] => { + const res = []; const randomVariantType = () => { return VARIANTS[Math.floor(Math.random() * VARIANTS.length)]; }; - for (let i = 0; i < appCount; i++) { - const app = createApplication(`${appNamePrefix}${i}`); - for ( - let j = 0; - j < - (variantCount !== -1 - ? variantCount - : Math.floor(Math.random() * 20 + minVariantCount)); - j++ - ) { + for ( + let i = 0; + i < + (variantCount !== -1 + ? variantCount + : Math.floor(Math.random() * 20 + minVariantCount)); + i++ + ) { + res.push( createVariant( - app.pushApplicationID, - `${variantNamePrefix}${j}`, - variantType ?? randomVariantType() - ); - } + appId, + `${variantNamePrefix}${i}`, + variantType ?? randomVariantType(), + variantDef + ) + ); } + + return res; }; diff --git a/test/mocks/applications.ts b/test/mocks/applications.ts index 8e49f21..42d434b 100644 --- a/test/mocks/applications.ts +++ b/test/mocks/applications.ts @@ -1,11 +1,16 @@ // applications mocks import * as nock from 'nock'; +import {DataStore} from './DataStore'; +import {VariantsMock} from './variants'; +import {Guid} from 'guid-typescript'; +import {URL} from 'url'; import { PushApplication, PushApplicationDefinition, + Variant, } from '@aerogear/unifiedpush-admin-client'; -import {DataStore} from './DataStore'; -import {VariantsMock} from './variants'; +import {VariantDefinition} from '@aerogear/unifiedpush-admin-client/dist/src/commands/variants/Variant'; +import {getAppMetrics} from './UPSMock'; interface VariantMockDictionary { [appId: string]: VariantsMock; @@ -14,21 +19,27 @@ interface VariantMockDictionary { export class ApplicationsMock { private readonly datastore: DataStore; private readonly variantsMocks: VariantMockDictionary = {}; - constructor(datastore: DataStore) { + private readonly basePath; + constructor(datastore: DataStore, basePath: string) { this.datastore = datastore; + this.basePath = basePath; this.setUpCreateMock(); this.setUpGetApplicationsMock(); } public readonly createApplication = ( datastore: DataStore, - appName: string + appName: string, + appDef: PushApplicationDefinition = {} ): PushApplication => { - const app = this.datastore.createApp(appName, true); + const app = this.datastore.createApp(appName, appDef, true); this.setUpGetApplicationMock(app.pushApplicationID); this.setUpDeleteMock(app.pushApplicationID); this.setUpUpdateMock(app.pushApplicationID); + this.setUpRenewMasterSecretMock(app.pushApplicationID); + this.setUpGetMetricsMock(app.pushApplicationID); this.variantsMocks[app.pushApplicationID] = new VariantsMock( + this.basePath, this.datastore, app ); @@ -38,26 +49,67 @@ export class ApplicationsMock { public readonly createVariant = ( appId: string, name: string, - variantType: string - ) => { + variantType: string, + def: VariantDefinition = {} + ): Variant => { const mock = this.variantsMocks[appId]; - mock.createVariant(name, variantType); + return mock.createVariant(name, variantType, def); }; - private readonly setUpGetApplicationsMock = () => { - let page: number, per_page: number; + private readonly setUpRenewMasterSecretMock = (appId: string) => { + nock(`${this.basePath}`) + .put(`/rest/applications/${appId}/reset`) + .reply(() => { + const app = this.datastore.getApp(appId); + if (app) { + app.masterSecret = Guid.create().toString(); + return [204, app]; + } + return [404]; + }) + .persist(); + }; - nock('http://localhost:9999') - .get('/rest/applications') - .query(query => { - page = parseInt(query.page as string); - per_page = parseInt(query.per_page as string); - return true; + private readonly setUpGetMetricsMock = (appId: string) => { + nock(`${this.basePath}`) + //.get(`/rest/metrics/messages/application/${appId}?page=0&per_page=10&sort=desc&search=`) + .get(`/rest/metrics/messages/application/${appId}`) + .query(() => true) + .reply(uri => { + const url = new URL(this.basePath + uri); + const page = url.searchParams.get('page') + ? parseInt(url.searchParams.get('page')!) + : 0; + const perPage = url.searchParams.get('per_page') + ? parseInt(url.searchParams.get('per_page')!) + : 10; + const sort = url.searchParams.get('sort') ?? 'desc'; + const search = url.searchParams.get('search') ?? ''; + const metrics = getAppMetrics(appId, page, perPage, sort, search); + if (!metrics) { + return [404]; + } + + return [200, metrics, {total: getAppMetrics(appId).length}]; }) - .reply(() => { + .persist(); + }; + + private readonly setUpGetApplicationsMock = () => { + nock(`${this.basePath}`) + .get('/rest/applications') + .query(() => true) + .reply(uri => { + const url = new URL(this.basePath + uri); + const page = url.searchParams.get('page') + ? parseInt(url.searchParams.get('page')!) + : 0; + const perPage = url.searchParams.get('per_page') + ? parseInt(url.searchParams.get('per_page')!) + : 10; return [ 200, - getApplications(this.datastore, undefined, page, per_page), + getApplications(this.datastore, undefined, page, perPage), {total: this.datastore.getAllApps().length}, ]; }) @@ -65,7 +117,7 @@ export class ApplicationsMock { }; private readonly setUpGetApplicationMock = (id: string) => { - nock('http://localhost:9999') + nock(this.basePath) .get(`/rest/applications/${id}`) .reply(() => { const app = this.datastore @@ -83,10 +135,30 @@ export class ApplicationsMock { return [404]; }) .persist(); + nock(this.basePath) + .get( + `/rest/applications/${id}?includeDeviceCount=true&includeActivity=true` + ) + .reply(() => { + const app = this.datastore + .getAllApps() + .find(app => app.pushApplicationID === id); + if (app) { + return [ + 200, + this.datastore + .getAllApps() + .find(app => app.pushApplicationID === id), + {total: this.datastore.getAllApps().length}, + ]; + } + return [404]; + }) + .persist(); }; private readonly setUpCreateMock = (): void => { - nock('http://localhost:9999') + nock(this.basePath) .post('/rest/applications') .reply(200, (uri: string, body: PushApplicationDefinition) => { const app = this.datastore.createApp(body.name!); @@ -96,7 +168,7 @@ export class ApplicationsMock { }; private readonly setUpDeleteMock = (appId: string): void => { - nock('http://localhost:9999') + nock(this.basePath) .delete(`/rest/applications/${appId}`) .reply(() => { if ( @@ -118,7 +190,7 @@ export class ApplicationsMock { }; private readonly setUpUpdateMock = (appId: string): void => { - nock('http://localhost:9999') + nock(this.basePath) .put(`/rest/applications/${appId}`) .reply((url: string, body) => { const update = body as PushApplicationDefinition; diff --git a/test/mocks/auth.ts b/test/mocks/auth.ts new file mode 100644 index 0000000..b7fb5b4 --- /dev/null +++ b/test/mocks/auth.ts @@ -0,0 +1,29 @@ +import * as nock from 'nock'; +import {TEST_AUTH_CONFIG, TEST_UI_CONFIG} from './constants'; + +export class AuthMock { + private readonly basePath; + constructor(basePath: string) { + this.basePath = basePath; + this.setupGetAuthConfigMock(); + this.setupGetUiConfigMock(); + } + + private readonly setupGetAuthConfigMock = () => { + nock(`${this.basePath}`) + .get('/rest/auth/config') + .reply(() => { + return [200, TEST_AUTH_CONFIG]; + }) + .persist(); + }; + + private readonly setupGetUiConfigMock = () => { + nock(`${this.basePath}`) + .get('/rest/ui/config') + .reply(() => { + return [200, TEST_UI_CONFIG]; + }) + .persist(); + }; +} diff --git a/test/mocks/constants.ts b/test/mocks/constants.ts index 447b4bc..ebde850 100644 --- a/test/mocks/constants.ts +++ b/test/mocks/constants.ts @@ -1 +1,23 @@ +import {Result} from '@aerogear/unifiedpush-admin-client/dist/src/commands/metrics/LoadMetricsCommand'; + +export const UPS_URL = 'http://localhost:9999'; export const VARIANTS = ['android', 'ios', 'ios_token', 'web_push']; +export const TEST_AUTH_CONFIG = { + url: 'http://localhost:9999', +}; + +export const TEST_UI_CONFIG = { + variants: ['android', 'ios'], +}; + +export const TEST_METRICS: Result = { + total: 3, + list: [ + { + pushApplicationId: '2194723947239847', + rawJsonMessage: "{ msg: 'test'}", + ipAddress: '127.0.0.1', + clientIdentifier: 'test identifier', + }, + ], +}; diff --git a/test/mocks/variants.ts b/test/mocks/variants.ts index 9bc0a5b..9b85faa 100644 --- a/test/mocks/variants.ts +++ b/test/mocks/variants.ts @@ -1,38 +1,66 @@ import {DataStore} from './DataStore'; import * as nock from 'nock'; +import {VARIANTS} from './constants'; +import {Guid} from 'guid-typescript'; import { - VariantDefinition, + PushApplication, + Variant, VariantType, -} from '@aerogear/unifiedpush-admin-client/dist/src/commands/variants/Variant'; -import {PushApplication, Variant} from '@aerogear/unifiedpush-admin-client'; -import {VARIANTS} from './constants'; + WebPushVariant, +} from '@aerogear/unifiedpush-admin-client'; +import {VariantDefinition} from '@aerogear/unifiedpush-admin-client/dist/src/commands/variants/Variant'; export class VariantsMock { private readonly datastore; private readonly app: PushApplication; - constructor(datastore: DataStore, app: PushApplication) { + private readonly basePath: string; + constructor(basePath: string, datastore: DataStore, app: PushApplication) { this.datastore = datastore; this.app = app; + this.basePath = basePath; VARIANTS.forEach(varType => this.setUpCreateVariantMock(app.pushApplicationID, varType) ); + VARIANTS.forEach(varType => this.setupGetVariantsMock(varType)); } public readonly createVariant = ( variantName: string, - variantType: string + variantType: string, + def: VariantDefinition = {} ): Variant => { const variant = this.datastore.createVariant(this.app.pushApplicationID, { name: variantName, type: variantType as VariantType, + ...def, }); this.setupDeleteVariantMock(variant); this.setupGetVariantMock(variant.variantID, variantType); + this.setupUpdateVariantMock(variant); + this.setupResetSecretMock(variant); + + if (variantType === 'web_push') { + this.setupRenewVapidKeysMock(variant.variantID); + } return variant; }; + private readonly setupGetVariantsMock = (variantType: string) => { + nock(this.basePath) + .get(`/rest/applications/${this.app.pushApplicationID}/${variantType}`) + .reply(() => { + const app = this.datastore.getApp(this.app.pushApplicationID); + if (!app) { + return [404]; + } + + return [204, app.variants || []]; + }) + .persist(); + }; + private readonly setupGetVariantMock = (id: string, variantType: string) => { - nock('http://localhost:9999') + nock(this.basePath) .get( `/rest/applications/${this.app.pushApplicationID}/${variantType}/${id}` ) @@ -46,11 +74,34 @@ export class VariantsMock { } return [204, variant]; - }); + }) + .persist(); + }; + + private readonly setupRenewVapidKeysMock = (id: string) => { + nock(this.basePath) + .put( + `/rest/applications/${this.app.pushApplicationID}/web_push/${id}/renew` + ) + .reply(() => { + const app = this.datastore.getApp(this.app.pushApplicationID); + const variant = app?.variants?.find( + vv => vv.variantID === id && vv.type === 'web_push' + ) as WebPushVariant; + if (!app || !variant) { + return [404]; + } + + variant.publicKey = Guid.create().toString(); + variant.privateKey = Guid.create().toString(); + + return [200, variant]; + }) + .persist(); }; private readonly setupDeleteVariantMock = (v: Variant) => { - nock('http://localhost:9999') + nock(this.basePath) .delete( `/rest/applications/${this.app.pushApplicationID}/${v.type}/${v.variantID}` ) @@ -67,14 +118,56 @@ export class VariantsMock { vv => vv.variantID !== v.variantID || vv.type !== v.type ); return [204]; - }); + }) + .persist(); + }; + + private readonly setupUpdateVariantMock = (v: Variant) => { + nock(this.basePath) + .put( + `/rest/applications/${this.app.pushApplicationID}/${v.type}/${v.variantID}` + ) + .reply((url, body) => { + const app = this.datastore.getApp(this.app.pushApplicationID); + const variantIndex = app?.variants?.findIndex( + vv => vv.variantID === v.variantID && vv.type === v.type + ); + if (!app || !variantIndex || variantIndex === -1) { + return [404]; + } + app.variants![variantIndex] = { + ...app.variants![variantIndex], + ...(body as VariantDefinition), + }; + return [204]; + }) + .persist(); + }; + + private readonly setupResetSecretMock = (v: Variant) => { + nock(this.basePath) + .put( + `/rest/applications/${this.app.pushApplicationID}/${v.type}/${v.variantID}/reset` + ) + .reply(() => { + const app = this.datastore.getApp(this.app.pushApplicationID); + const variantIndex = app?.variants?.findIndex( + vv => vv.variantID === v.variantID && vv.type === v.type + ); + if (!app || !variantIndex || variantIndex === -1) { + return [404]; + } + app.variants![variantIndex].secret = Guid.create().toString(); + return [204, app.variants![variantIndex]]; + }) + .persist(); }; private readonly setUpCreateVariantMock = ( appId: string, variantType: string ): void => { - nock('http://localhost:9999') + nock(this.basePath) .post(`/rest/applications/${appId}/${variantType}`) .reply((url, body) => { const def = body as VariantDefinition; @@ -97,6 +190,7 @@ export class VariantsMock { app.variants = app.variants || []; app.variants.push(variant); return [200, variant]; - }); + }) + .persist(); }; } diff --git a/test/resources/mock-pkey.pem b/test/resources/mock-pkey.pem new file mode 100644 index 0000000..ed8d465 --- /dev/null +++ b/test/resources/mock-pkey.pem @@ -0,0 +1 @@ +mock key diff --git a/test/resources/mockcert.p12 b/test/resources/mockcert.p12 new file mode 100644 index 0000000..f58a85d --- /dev/null +++ b/test/resources/mockcert.p12 @@ -0,0 +1 @@ +JUST A MOCK