From 3090d75d694caf2745878feb896019582d6ac491 Mon Sep 17 00:00:00 2001 From: Sangeetha Krishnan Date: Thu, 13 Jul 2023 14:05:40 +0530 Subject: [PATCH 1/3] Fetch webhook registrations for workspace from IO Events --- src/hooks/post-deploy-event-reg.js | 4 +-- src/hooks/pre-deploy-event-reg.js | 2 +- src/hooks/utils/hook-utils.js | 38 +++++++++++++++--------- test/__fixtures__/registration/list.json | 4 +-- test/__fixtures__/registration/list.txt | 4 +-- test/__fixtures__/registration/list.yml | 4 +-- test/hooks/post-deploy-event-reg.test.js | 10 +++++-- test/mocks.js | 11 +++++-- 8 files changed, 49 insertions(+), 28 deletions(-) diff --git a/src/hooks/post-deploy-event-reg.js b/src/hooks/post-deploy-event-reg.js index b000c68..33dde88 100644 --- a/src/hooks/post-deploy-event-reg.js +++ b/src/hooks/post-deploy-event-reg.js @@ -12,6 +12,6 @@ const { WEBHOOK, deployRegistration } = require('./utils/hook-utils') -module.exports = async function ({ appConfig }) { - await deployRegistration({ appConfig }, WEBHOOK, 'post-deploy-event-reg') +module.exports = async function ({ appConfig, force }) { + await deployRegistration({ appConfig }, WEBHOOK, 'post-deploy-event-reg', force) } diff --git a/src/hooks/pre-deploy-event-reg.js b/src/hooks/pre-deploy-event-reg.js index fca4b89..2f5414d 100644 --- a/src/hooks/pre-deploy-event-reg.js +++ b/src/hooks/pre-deploy-event-reg.js @@ -13,7 +13,7 @@ const { JOURNAL, getDeliveryType } = require('./utils/hook-utils') -module.exports = async function ({ appConfig }) { +module.exports = async function ({ appConfig, force }) { if (appConfig && appConfig.events) { const registrations = appConfig.events.registrations for (const registrationName in registrations) { diff --git a/src/hooks/utils/hook-utils.js b/src/hooks/utils/hook-utils.js index 8e145e8..f05f397 100644 --- a/src/hooks/utils/hook-utils.js +++ b/src/hooks/utils/hook-utils.js @@ -35,7 +35,7 @@ function getDeliveryType (registration) { } /** - * + * @private * @param {object} registration - registration object * @param {object} providerMetadataToProviderIdMapping - mapping of provider metadata to provider id * @returns {Array} of events of interest {provider_id, event_code} @@ -58,7 +58,7 @@ function getEventsOfInterestForRegistration (registration, } /** - * + * @private * @param {object} projectConfig - project config object * @returns {object} Object containing orgId, X_API_KEY, eventsClient */ @@ -75,6 +75,7 @@ async function initEventsSdk (projectConfig) { } /** + * @private * @returns {object} Object containing mapping of provider metadata to provider id */ function getProviderMetadataToProviderIdMapping () { @@ -91,20 +92,20 @@ function getProviderMetadataToProviderIdMapping () { } /** + * @private * @param {object} eventRegistrations - registrations from the .aio config file * @returns {object} Object containing mapping of registration name to registration object */ -function getRegistrationsFromAioConfig (eventRegistrations) { +function getRegistrationNameToRegistrationsMap (eventRegistrations) { const registrationNameToRegistrations = {} - if (eventRegistrations) { - for (const registration of eventRegistrations) { - registrationNameToRegistrations[registration.name] = registration - } + for (const registration of eventRegistrations) { + registrationNameToRegistrations[registration.name] = registration } return registrationNameToRegistrations } /** + * @private * @param {object} body - Registration Create/Update Model * @param {object} eventsSDK - eventsSDK object containing eventsClient and orgId * @param {object} existingRegistration - existing registration obtained from .aio config if exists @@ -122,6 +123,19 @@ async function createOrUpdateRegistration (body, eventsSDK, existingRegistration } } +/** + * @private + * @param {object} eventsSDK - eventsSDK object containing eventsClient and orgId + * @param {object} project - project details from .aio config file + * @returns {object} Object containing all registrations for the workspace + */ +async function getAllRegistrationsForWorkspace (eventsSDK, project) { + const registrationsForWorkspace = await eventsSDK.eventsClient.getAllRegistrationsForWorkspace(eventsSDK.orgId, project.id, + project.workspace.id) + if (!registrationsForWorkspace) { return {} } + return getRegistrationNameToRegistrationsMap(registrationsForWorkspace._embedded.registrations) +} + /** * @param {object} appConfigRoot - Root object containing events and project details * @param {object} appConfigRoot.appConfig - Object containing events and project details @@ -129,8 +143,9 @@ async function createOrUpdateRegistration (body, eventsSDK, existingRegistration * @param {object} appConfigRoot.appConfig.events - Events registrations that are part of the app.config.yaml file * @param {string} expectedDeliveryType - Delivery type based on the hook that is calling. Expected delivery type can be webhook or journal * @param {string} hookType - pre-deploy-event-reg or post-deploy-event-reg hook values + * @param {boolean} forceEventsFlag - determines if registrations that are part of the workspace but not part of the app.config.yaml will be deleted or not */ -async function deployRegistration ({ appConfig: { events, project } }, expectedDeliveryType, hookType) { +async function deployRegistration ({ appConfig: { events, project } }, expectedDeliveryType, hookType, forceEventsFlag) { if (!project) { throw new Error( `No project found, skipping event registration in ${hookType} hook`) @@ -147,12 +162,7 @@ async function deployRegistration ({ appConfig: { events, project } }, expectedD } const registrations = events.registrations const providerMetadataToProviderIdMapping = getProviderMetadataToProviderIdMapping() - let existingRegistrations - if (project.workspace.details.events) { - existingRegistrations = getRegistrationsFromAioConfig( - project.workspace.details.events.registrations) - } - + const existingRegistrations = await getAllRegistrationsForWorkspace(eventsSDK, project) for (const registrationName in registrations) { const deliveryType = getDeliveryType(registrations[registrationName]) if (deliveryType === expectedDeliveryType) { diff --git a/test/__fixtures__/registration/list.json b/test/__fixtures__/registration/list.json index 23c172b..c1e752f 100644 --- a/test/__fixtures__/registration/list.json +++ b/test/__fixtures__/registration/list.json @@ -14,7 +14,7 @@ } }, "id": 11111, - "name": "bowling 1", + "name": "Event Registration 1", "description": "let me know when we can go play bowling!", "client_id": "1234654902189324798", "webhook_url": "https://send-me-a-bowling-event.com/right-now", @@ -48,7 +48,7 @@ } }, "id": 22222, - "name": "table tenis 2", + "name": "Event Registration 2", "description": "registration for table tennis events", "client_id": "1234654902189324798", "webhook_url": "https://send-me-a-table-tennis-event.com/please", diff --git a/test/__fixtures__/registration/list.txt b/test/__fixtures__/registration/list.txt index 1a59639..ea3ba9a 100644 --- a/test/__fixtures__/registration/list.txt +++ b/test/__fixtures__/registration/list.txt @@ -1,4 +1,4 @@ ID NAME ENABLED DELIVERY_TYPE WEBHOOK_STATUS ───────────────────────────────────── ──────────────────────── ───────── ───────────── ────────────── - REGID1 bowling 1 true webhook verified - REGID2 table tenis 2 true webhook verified + REGID1 Event Registration 1 true webhook verified + REGID2 Event Registration 2 true webhook verified diff --git a/test/__fixtures__/registration/list.yml b/test/__fixtures__/registration/list.yml index 6999c7a..414c9c5 100644 --- a/test/__fixtures__/registration/list.yml +++ b/test/__fixtures__/registration/list.yml @@ -11,7 +11,7 @@ _embedded: href: >- https://api.adobe.io/events/consumerOrgId/projectId/workspaceId/registrations/REGID1 id: 11111 - name: bowling 1 + name: Event Registration 1 description: let me know when we can go play bowling! client_id: '1234654902189324798' webhook_url: 'https://send-me-a-bowling-event.com/right-now' @@ -39,7 +39,7 @@ _embedded: href: >- https://api.adobe.io/events/consumerOrgId/projectId/workspaceId/registrations/REGID2 id: 22222 - name: table tenis 2 + name: Event Registration 2 description: registration for table tennis events client_id: '1234654902189324798' webhook_url: 'https://send-me-a-table-tennis-event.com/please' diff --git a/test/hooks/post-deploy-event-reg.test.js b/test/hooks/post-deploy-event-reg.test.js index e26745d..835d09d 100644 --- a/test/hooks/post-deploy-event-reg.test.js +++ b/test/hooks/post-deploy-event-reg.test.js @@ -14,7 +14,8 @@ jest.mock('@adobe/aio-lib-events') const eventsSdk = require('@adobe/aio-lib-events') const mockEventsSdkInstance = { createRegistration: jest.fn(), - updateRegistration: jest.fn() + updateRegistration: jest.fn(), + getAllRegistrationsForWorkspace: jest.fn() } jest.mock('@adobe/aio-lib-ims') const { getToken } = require('@adobe/aio-lib-ims') @@ -126,6 +127,7 @@ describe('post deploy event registration hook interfaces', () => { getToken.mockReturnValue('accessToken') const events = mock.data.sampleEvents events.registrations['Event Registration 1'].delivery_type = 'webhook' + mockEventsSdkInstance.getAllRegistrationsForWorkspace.mockResolvedValue(mock.data.getAllWebhookRegistrationsWithEmptyResponse) mockEventsSdkInstance.createRegistration.mockReturnValue(mock.data.createWebhookRegistrationResponse) const projectWithEmptyEvents = mock.data.sampleProjectWithoutEvents projectWithEmptyEvents.workspace.details.events = {} @@ -141,6 +143,7 @@ describe('post deploy event registration hook interfaces', () => { expect(typeof hook).toBe('function') process.env = mock.data.dotEnv getToken.mockReturnValue('accessToken') + mockEventsSdkInstance.getAllRegistrationsForWorkspace.mockResolvedValue(mock.data.getAllWebhookRegistrationsResponse) mockEventsSdkInstance.updateRegistration.mockRejectedValueOnce(JSON.stringify({ code: 500, errorDetails: { @@ -149,7 +152,7 @@ describe('post deploy event registration hook interfaces', () => { })) await expect(hook({ appConfig: { project: mock.data.sampleProject, events: mock.data.sampleEvents } })).rejects.toThrowError() expect(mockEventsSdkInstance.updateRegistration).toBeCalledTimes(1) - expect(mockEventsSdkInstance.updateRegistration).toHaveBeenCalledWith(CONSUMER_ID, PROJECT_ID, WORKSPACE_ID, 'registrationId1', + expect(mockEventsSdkInstance.updateRegistration).toHaveBeenCalledWith(CONSUMER_ID, PROJECT_ID, WORKSPACE_ID, 'REGID1', mock.data.hookDecodedEventRegistration1 ) }) @@ -159,10 +162,11 @@ describe('post deploy event registration hook interfaces', () => { expect(typeof hook).toBe('function') process.env = mock.data.dotEnv getToken.mockReturnValue('accessToken') + mockEventsSdkInstance.getAllRegistrationsForWorkspace.mockResolvedValue(mock.data.getAllWebhookRegistrationsResponse) mockEventsSdkInstance.updateRegistration.mockReturnValue(mock.data.createWebhookRegistrationResponse) await expect(hook({ appConfig: { project: mock.data.sampleProject, events: mock.data.sampleEvents } })).resolves.not.toThrowError() expect(mockEventsSdkInstance.updateRegistration).toBeCalledTimes(1) - expect(mockEventsSdkInstance.updateRegistration).toHaveBeenCalledWith(CONSUMER_ID, PROJECT_ID, WORKSPACE_ID, 'registrationId1', + expect(mockEventsSdkInstance.updateRegistration).toHaveBeenCalledWith(CONSUMER_ID, PROJECT_ID, WORKSPACE_ID, 'REGID1', mock.data.hookDecodedEventRegistration1 ) }) diff --git a/test/mocks.js b/test/mocks.js index 79e7aee..2f9c663 100644 --- a/test/mocks.js +++ b/test/mocks.js @@ -272,6 +272,12 @@ const createWebhookRegistrationResponse = { ...getWebhookRegistrationResponse } +const getAllWebhookRegistrationsWithEmptyResponse = { + _embedded: { + registrations: [] + } +} + const getAllWebhookRegistrationsResponse = { _embedded: { registrations: [ @@ -288,7 +294,7 @@ const getAllWebhookRegistrationsResponse = { } }, id: 11111, - name: 'bowling 1', + name: 'Event Registration 1', description: 'let me know when we can go play bowling!', client_id: '1234654902189324798', webhook_url: 'https://send-me-a-bowling-event.com/right-now', @@ -322,7 +328,7 @@ const getAllWebhookRegistrationsResponse = { } }, id: 22222, - name: 'table tenis 2', + name: 'Event Registration 2', description: 'registration for table tennis events', client_id: '1234654902189324798', webhook_url: 'https://send-me-a-table-tennis-event.com/please', @@ -660,6 +666,7 @@ const data = { getAllEventMetadata, createWebhookRegistrationResponse, getAllWebhookRegistrationsResponse, + getAllWebhookRegistrationsWithEmptyResponse, getWebhookRegistrationResponse, createWebhookRegistrationInputJSON, createWebhookRegistrationInputJSONNoClientId, From 17af58e4f2545562eff170a30e7b933d6975c3ab Mon Sep 17 00:00:00 2001 From: Sangeetha Krishnan Date: Thu, 13 Jul 2023 23:56:00 +0530 Subject: [PATCH 2/3] delete registrations not part of config on --force-events flag enabled --- src/hooks/pre-deploy-event-reg.js | 2 +- src/hooks/utils/hook-utils.js | 60 ++++++++++++++++++++++++++----- test/mocks.js | 1 + 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/hooks/pre-deploy-event-reg.js b/src/hooks/pre-deploy-event-reg.js index 2f5414d..fca4b89 100644 --- a/src/hooks/pre-deploy-event-reg.js +++ b/src/hooks/pre-deploy-event-reg.js @@ -13,7 +13,7 @@ const { JOURNAL, getDeliveryType } = require('./utils/hook-utils') -module.exports = async function ({ appConfig, force }) { +module.exports = async function ({ appConfig }) { if (appConfig && appConfig.events) { const registrations = appConfig.events.registrations for (const registrationName in registrations) { diff --git a/src/hooks/utils/hook-utils.js b/src/hooks/utils/hook-utils.js index f05f397..2701604 100644 --- a/src/hooks/utils/hook-utils.js +++ b/src/hooks/utils/hook-utils.js @@ -104,6 +104,16 @@ function getRegistrationNameToRegistrationsMap (eventRegistrations) { return registrationNameToRegistrations } +/** + * @private + * @param {Array.} workspaceRegistrationNames Registration names from the Console workspace + * @param {Array.} appConfigRegistrationNames Registration names defined in the app.config.yaml file + * @returns {Array.} Registrations that are part of the workspace, but not part of the app.config.yaml + */ +function getWorkspaceRegistrationsToBeDeleted (workspaceRegistrationNames, appConfigRegistrationNames) { + return workspaceRegistrationNames.filter(wsRegistration => !appConfigRegistrationNames.includes(wsRegistration)) +} + /** * @private * @param {object} body - Registration Create/Update Model @@ -115,11 +125,25 @@ async function createOrUpdateRegistration (body, eventsSDK, existingRegistration if (existingRegistration) { const response = await eventsSDK.eventsClient.updateRegistration(eventsSDK.orgId, project.id, project.workspace.id, existingRegistration.registration_id, body) - console.log('Updated registration:' + JSON.stringify(response)) + console.log('Updated registration with name:' + response.name + ' and id:' + response.registration_id) } else { const response = await eventsSDK.eventsClient.createRegistration(eventsSDK.orgId, project.id, project.workspace.id, body) - console.log('Created registration:' + JSON.stringify(response)) + console.log('Created registration:' + response.name + ' and id:' + response.registration_id) + } +} + +/** + * @private + * @param {object} eventsSDK - eventsSDK object containing eventsClient and orgId + * @param {object} existingRegistration - existing registration obtained from .aio config if exists + * @param {object} project - project details from .aio config file + */ +async function deleteRegistration (eventsSDK, existingRegistration, project) { + if (existingRegistration) { + await eventsSDK.eventsClient.deleteRegistration(eventsSDK.orgId, project.id, project.workspace.id, + existingRegistration.registration_id) + console.log('Deleted registration with name:' + existingRegistration.name + ' and id:' + existingRegistration.registration_id) } } @@ -160,23 +184,24 @@ async function deployRegistration ({ appConfig: { events, project } }, expectedD throw new Error( `Events SDK could not be initialised correctly. Skipping event registration in ${hookType} hook`) } - const registrations = events.registrations + const registrationsFromConfig = events.registrations const providerMetadataToProviderIdMapping = getProviderMetadataToProviderIdMapping() - const existingRegistrations = await getAllRegistrationsForWorkspace(eventsSDK, project) - for (const registrationName in registrations) { - const deliveryType = getDeliveryType(registrations[registrationName]) + const registrationsFromWorkspace = await getAllRegistrationsForWorkspace(eventsSDK, project) + for (const registrationName in registrationsFromConfig) { + const deliveryType = getDeliveryType(registrationsFromConfig[registrationName]) if (deliveryType === expectedDeliveryType) { const body = { name: registrationName, client_id: eventsSDK.X_API_KEY, - description: registrations[registrationName].description, + description: registrationsFromConfig[registrationName].description, delivery_type: deliveryType, + runtime_action: registrationsFromConfig[registrationName].runtime_action, events_of_interest: getEventsOfInterestForRegistration( - registrations[registrationName], providerMetadataToProviderIdMapping) + registrationsFromConfig[registrationName], providerMetadataToProviderIdMapping) } try { let existingRegistration - if (existingRegistrations && existingRegistrations[registrationName]) { existingRegistration = existingRegistrations[registrationName] } + if (registrationsFromWorkspace && registrationsFromWorkspace[registrationName]) { existingRegistration = registrationsFromWorkspace[registrationName] } await createOrUpdateRegistration(body, eventsSDK, existingRegistration, project) } catch (e) { @@ -186,6 +211,23 @@ async function deployRegistration ({ appConfig: { events, project } }, expectedD } } } + + if (forceEventsFlag) { + const registrationsToDeleted = getWorkspaceRegistrationsToBeDeleted(Object.keys(registrationsFromWorkspace), Object.keys(registrationsFromConfig)) + console.log('The following registrations will be deleted: ', registrationsToDeleted) + for (const registrationName of registrationsToDeleted) { + try { + if (registrationsFromWorkspace && registrationsFromWorkspace[registrationName]) { + await deleteRegistration(eventsSDK, + registrationsFromWorkspace[registrationName], project) + } + } catch (e) { + throw new Error( + e + '\ncode:' + e.code + '\nDetails:' + JSON.stringify( + e.sdkDetails)) + } + } + } } module.exports = { diff --git a/test/mocks.js b/test/mocks.js index 2f9c663..e73f13a 100644 --- a/test/mocks.js +++ b/test/mocks.js @@ -603,6 +603,7 @@ const hookDecodedEventRegistration1 = { client_id: 'serviceApiKey', description: 'Registration for IO Events 1', delivery_type: 'webhook', + runtime_action: 'poc-event-1', events_of_interest: [{ provider_id: 'providerId1', event_code: 'eventCode1' From e89ca4123c6cf69f236073c84ce3206a949cfdca Mon Sep 17 00:00:00 2001 From: Sangeetha Krishnan Date: Fri, 14 Jul 2023 01:12:09 +0530 Subject: [PATCH 3/3] add unit tests for syncing registrations on --force-delete --- src/hooks/utils/hook-utils.js | 16 ++--- test/hooks/post-deploy-event-reg.test.js | 78 +++++++++++++++++++++++- 2 files changed, 82 insertions(+), 12 deletions(-) diff --git a/src/hooks/utils/hook-utils.js b/src/hooks/utils/hook-utils.js index 2701604..2df950e 100644 --- a/src/hooks/utils/hook-utils.js +++ b/src/hooks/utils/hook-utils.js @@ -140,11 +140,9 @@ async function createOrUpdateRegistration (body, eventsSDK, existingRegistration * @param {object} project - project details from .aio config file */ async function deleteRegistration (eventsSDK, existingRegistration, project) { - if (existingRegistration) { - await eventsSDK.eventsClient.deleteRegistration(eventsSDK.orgId, project.id, project.workspace.id, - existingRegistration.registration_id) - console.log('Deleted registration with name:' + existingRegistration.name + ' and id:' + existingRegistration.registration_id) - } + await eventsSDK.eventsClient.deleteRegistration(eventsSDK.orgId, project.id, project.workspace.id, + existingRegistration.registration_id) + console.log('Deleted registration with name:' + existingRegistration.name + ' and id:' + existingRegistration.registration_id) } /** @@ -202,8 +200,7 @@ async function deployRegistration ({ appConfig: { events, project } }, expectedD try { let existingRegistration if (registrationsFromWorkspace && registrationsFromWorkspace[registrationName]) { existingRegistration = registrationsFromWorkspace[registrationName] } - await createOrUpdateRegistration(body, eventsSDK, - existingRegistration, project) + await createOrUpdateRegistration(body, eventsSDK, existingRegistration, project) } catch (e) { throw new Error( e + '\ncode:' + e.code + '\nDetails:' + JSON.stringify( @@ -217,10 +214,7 @@ async function deployRegistration ({ appConfig: { events, project } }, expectedD console.log('The following registrations will be deleted: ', registrationsToDeleted) for (const registrationName of registrationsToDeleted) { try { - if (registrationsFromWorkspace && registrationsFromWorkspace[registrationName]) { - await deleteRegistration(eventsSDK, - registrationsFromWorkspace[registrationName], project) - } + await deleteRegistration(eventsSDK, registrationsFromWorkspace[registrationName], project) } catch (e) { throw new Error( e + '\ncode:' + e.code + '\nDetails:' + JSON.stringify( diff --git a/test/hooks/post-deploy-event-reg.test.js b/test/hooks/post-deploy-event-reg.test.js index 835d09d..db92869 100644 --- a/test/hooks/post-deploy-event-reg.test.js +++ b/test/hooks/post-deploy-event-reg.test.js @@ -15,7 +15,8 @@ const eventsSdk = require('@adobe/aio-lib-events') const mockEventsSdkInstance = { createRegistration: jest.fn(), updateRegistration: jest.fn(), - getAllRegistrationsForWorkspace: jest.fn() + getAllRegistrationsForWorkspace: jest.fn(), + deleteRegistration: jest.fn() } jest.mock('@adobe/aio-lib-ims') const { getToken } = require('@adobe/aio-lib-ims') @@ -33,6 +34,10 @@ describe('post deploy event registration hook interfaces', () => { eventsSdk.init.mockResolvedValue(mockEventsSdkInstance) }) + afterEach(() => { + eventsSdk.init.mockRestore() + }) + test('hook interface', async () => { const hook = require('../../src/hooks/post-deploy-event-reg') expect(typeof hook).toBe('function') @@ -170,4 +175,75 @@ describe('post deploy event registration hook interfaces', () => { mock.data.hookDecodedEventRegistration1 ) }) + + test('successfully delete registrations not part of the config', async () => { + const hook = require('../../src/hooks/post-deploy-event-reg') + expect(typeof hook).toBe('function') + process.env = mock.data.dotEnv + getToken.mockReturnValue('accessToken') + const events = { + registrations: { + 'Event Registration 1': mock.data.sampleEvents.registrations['Event Registration 1'] + } + } + mockEventsSdkInstance.getAllRegistrationsForWorkspace.mockResolvedValue(mock.data.getAllWebhookRegistrationsResponse) + mockEventsSdkInstance.updateRegistration.mockReturnValue(mock.data.createWebhookRegistrationResponse) + const projectWithEmptyEvents = mock.data.sampleProjectWithoutEvents + await expect(hook({ appConfig: { project: projectWithEmptyEvents, events }, force: true })).resolves.not.toThrowError() + expect(mockEventsSdkInstance.updateRegistration).toBeCalledTimes(1) + expect(mockEventsSdkInstance.deleteRegistration).toHaveBeenCalledWith(CONSUMER_ID, PROJECT_ID, WORKSPACE_ID, 'REGID2') + }) + + test('test delete registrations not part of the config, with no registrations to delete', async () => { + const hook = require('../../src/hooks/post-deploy-event-reg') + expect(typeof hook).toBe('function') + process.env = mock.data.dotEnv + getToken.mockReturnValue('accessToken') + mockEventsSdkInstance.getAllRegistrationsForWorkspace.mockResolvedValue(mock.data.getAllWebhookRegistrationsResponse) + mockEventsSdkInstance.updateRegistration.mockReturnValue(mock.data.createWebhookRegistrationResponse) + await expect(hook({ appConfig: { project: mock.data.sampleProject, events: mock.data.sampleEvents }, force: true })).resolves.not.toThrowError() + expect(mockEventsSdkInstance.updateRegistration).toBeCalledTimes(1) + expect(mockEventsSdkInstance.updateRegistration).toHaveBeenCalledWith(CONSUMER_ID, PROJECT_ID, WORKSPACE_ID, 'REGID1', + mock.data.hookDecodedEventRegistration1) + expect(mockEventsSdkInstance.deleteRegistration).toHaveBeenCalledTimes(0) + }) + + test('test delete registrations not part of the config, with no registrations in workspace', async () => { + const hook = require('../../src/hooks/post-deploy-event-reg') + expect(typeof hook).toBe('function') + process.env = mock.data.dotEnv + getToken.mockReturnValue('accessToken') + mockEventsSdkInstance.getAllRegistrationsForWorkspace.mockResolvedValue(mock.data.getAllWebhookRegistrationsWithEmptyResponse) + + mockEventsSdkInstance.createRegistration.mockReturnValue(mock.data.createWebhookRegistrationResponse) + await expect(hook({ appConfig: { project: mock.data.sampleProjectWithoutEvents, events: mock.data.sampleEvents }, force: true })).resolves.not.toThrowError() + expect(mockEventsSdkInstance.createRegistration).toBeCalledTimes(1) + expect(mockEventsSdkInstance.createRegistration).toHaveBeenCalledWith(CONSUMER_ID, PROJECT_ID, WORKSPACE_ID, + mock.data.hookDecodedEventRegistration1) + expect(mockEventsSdkInstance.deleteRegistration).toHaveBeenCalledTimes(0) + }) + + test('test error on delete registrations not part of the config', async () => { + const hook = require('../../src/hooks/post-deploy-event-reg') + expect(typeof hook).toBe('function') + process.env = mock.data.dotEnv + getToken.mockReturnValue('accessToken') + const events = { + registrations: { + 'Event Registration 1': mock.data.sampleEvents.registrations['Event Registration 1'] + } + } + mockEventsSdkInstance.getAllRegistrationsForWorkspace.mockResolvedValue(mock.data.getAllWebhookRegistrationsResponse) + mockEventsSdkInstance.updateRegistration.mockReturnValue(mock.data.createWebhookRegistrationResponse) + mockEventsSdkInstance.deleteRegistration.mockRejectedValueOnce({ + code: 500, + errorDetails: { + message: 'Internal Server Error' + } + }) + const projectWithEmptyEvents = mock.data.sampleProjectWithoutEvents + await expect(hook({ appConfig: { project: projectWithEmptyEvents, events }, force: true })).rejects.toThrowError() + expect(mockEventsSdkInstance.updateRegistration).toBeCalledTimes(1) + expect(mockEventsSdkInstance.deleteRegistration).toHaveBeenCalledWith(CONSUMER_ID, PROJECT_ID, WORKSPACE_ID, 'REGID2') + }) })