From ae03c87b4135935f197cad67c7af021aa0b3f284 Mon Sep 17 00:00:00 2001 From: Thenkei Date: Tue, 16 May 2023 10:09:36 +0200 Subject: [PATCH] test: add some tests --- .../src/events-subscription/index.ts | 4 +- .../src/permissions/action-permission.ts | 5 +- .../src/permissions/user-permission.ts | 2 + .../test/events-subscription/index.test.ts | 93 +++++++++++++++++++ .../permissions/rendering-permission.test.ts | 84 +++++++++++++++++ 5 files changed, 185 insertions(+), 3 deletions(-) diff --git a/packages/forestadmin-client/src/events-subscription/index.ts b/packages/forestadmin-client/src/events-subscription/index.ts index c96a9fb290..199ca95f11 100644 --- a/packages/forestadmin-client/src/events-subscription/index.ts +++ b/packages/forestadmin-client/src/events-subscription/index.ts @@ -56,6 +56,8 @@ export default class EventsSubscriptionService { private async handleSeverEventRefreshRenderings(event: ServerEvent) { if (!event.data) { this.options.logger('Debug', 'Server Event - RefreshRenderings missing required data.'); + + return; } const { renderingIds } = JSON.parse(event.data as unknown as string); @@ -73,7 +75,7 @@ export default class EventsSubscriptionService { } if (event.message) - this.options.logger('Debug', `Server Event - Error: ${JSON.stringify(event)}`); + this.options.logger('Warn', `Server Event - Error: ${JSON.stringify(event)}`); } private onEventOpen() { diff --git a/packages/forestadmin-client/src/permissions/action-permission.ts b/packages/forestadmin-client/src/permissions/action-permission.ts index 6ef24625c6..a5eea100ef 100644 --- a/packages/forestadmin-client/src/permissions/action-permission.ts +++ b/packages/forestadmin-client/src/permissions/action-permission.ts @@ -55,8 +55,7 @@ export default class ActionPermissionService { this.options.logger( 'Debug', - `User ${roleId} is ${isAllowed ? '' : 'not '}allowed to perform - }${actionName}`, + `User ${roleId} is ${isAllowed ? '' : 'not '}allowed to perform ${actionName}`, ); return isAllowed; @@ -142,6 +141,8 @@ export default class ActionPermissionService { } public invalidateCache() { + this.options.logger('Debug', 'Invalidating roles permissions cache..'); + this.permissionsPromise = undefined; this.permissionExpirationTimestamp = undefined; } diff --git a/packages/forestadmin-client/src/permissions/user-permission.ts b/packages/forestadmin-client/src/permissions/user-permission.ts index bc41a18c01..7b51926974 100644 --- a/packages/forestadmin-client/src/permissions/user-permission.ts +++ b/packages/forestadmin-client/src/permissions/user-permission.ts @@ -38,6 +38,8 @@ export default class UserPermissionService { } public invalidateCache() { + this.options.logger('Debug', 'Invalidating users permissions cache..'); + this.userInfoById = undefined; this.cacheExpirationTimestamp = undefined; } diff --git a/packages/forestadmin-client/test/events-subscription/index.test.ts b/packages/forestadmin-client/test/events-subscription/index.test.ts index 820a8f030a..f82f47bf05 100644 --- a/packages/forestadmin-client/test/events-subscription/index.test.ts +++ b/packages/forestadmin-client/test/events-subscription/index.test.ts @@ -46,6 +46,19 @@ describe('EventsSubscriptionService', () => { expect.any(Function), ); }); + + describe('when server events are deactivated', () => { + test('should not do anything', async () => { + const eventsSubscriptionService = new EventsSubscriptionService( + { ...options, useServerEvents: false }, + refreshEventsHandlerService, + ); + + eventsSubscriptionService.subscribeEvents(); + + expect(addEventListener).not.toHaveBeenCalled(); + }); + }); }); describe('handleSeverEvents', () => { @@ -115,6 +128,86 @@ describe('EventsSubscriptionService', () => { expect(refreshEventsHandlerService.refreshRenderings).toHaveBeenCalled(); expect(refreshEventsHandlerService.refreshRenderings).toHaveBeenCalledWith(['13', 24]); }); + describe('on malformed event', () => { + test('should not do anything', async () => { + const eventsSubscriptionService = new EventsSubscriptionService( + options, + refreshEventsHandlerService, + ); + eventsSubscriptionService.subscribeEvents(); + + // eslint-disable-next-line @typescript-eslint/dot-notation + events[ServerEventType.RefreshRenderings]({ + data: null, + }); + + expect(refreshEventsHandlerService.refreshRenderings).not.toHaveBeenCalled(); + }); + }); + }); + }); + + describe('onEventOpen', () => { + test('should refreshEverything using refreshEventsHandlerService', async () => { + const eventsSubscriptionService = new EventsSubscriptionService( + options, + refreshEventsHandlerService, + ); + + eventsSubscriptionService.subscribeEvents(); + + // eslint-disable-next-line @typescript-eslint/dot-notation + events['open'](); + + expect(refreshEventsHandlerService.refreshEverything).toHaveBeenCalled(); + + expect(options.logger).toHaveBeenCalledWith( + 'Debug', + 'Server Event - Open EventSource (SSE) connection with Forest Admin servers', + ); + }); + }); + + describe('onEventError', () => { + describe('when error status is Bad Gateway (502)', () => { + test('should delegate to refreshEventsHandlerService', async () => { + const eventsSubscriptionService = new EventsSubscriptionService( + options, + refreshEventsHandlerService, + ); + + eventsSubscriptionService.subscribeEvents(); + + // eslint-disable-next-line @typescript-eslint/dot-notation + events['error']({ status: 502 }); + + expect(options.logger).toHaveBeenCalledWith( + 'Debug', + 'Server Event - Connection lost (ForestAdmin servers are restarting)', + ); + }); + }); + + describe('other error case', () => { + test('should delegate to refreshEventsHandlerService', async () => { + const eventsSubscriptionService = new EventsSubscriptionService( + options, + refreshEventsHandlerService, + ); + + eventsSubscriptionService.subscribeEvents(); + + // eslint-disable-next-line @typescript-eslint/dot-notation + events['error']({ + status: 404, + message: 'some error message that might help customer to track issues', + }); + expect(options.logger).toHaveBeenCalledWith( + 'Warn', + 'Server Event - Error: {"status":404,"message":"some error message that' + + ' might help customer to track issues"}', + ); + }); }); }); }); diff --git a/packages/forestadmin-client/test/permissions/rendering-permission.test.ts b/packages/forestadmin-client/test/permissions/rendering-permission.test.ts index a32d0c8b52..46cc50be5a 100644 --- a/packages/forestadmin-client/test/permissions/rendering-permission.test.ts +++ b/packages/forestadmin-client/test/permissions/rendering-permission.test.ts @@ -762,6 +762,90 @@ describe('RenderingPermissionService', () => { }); }); + describe('invalidateAllCache', () => { + it('should invalidate the cache for all renderings', async () => { + const { + renderingPermission, + getUserInfoMock, + serverInterface, + hashServerChartsMock, + hashChartRequestMock, + } = setup(); + + const userInfo = { + id: 42, + firstName: 'Jane', + lastName: 'Doe', + email: 'jane@forest.com', + permissionLevel: PermissionLevel.User, + }; + + getUserInfoMock.mockResolvedValue(userInfo); + + const stats = { lines: [{ type: 'Line' }] }; + serverInterface.getRenderingPermissions = jest.fn().mockResolvedValue({ + collections: {}, + stats, + team: {}, + }); + hashServerChartsMock.mockReturnValue(new Set(['HASH'])); + hashChartRequestMock.mockReturnValue('HASH'); + + const resultA1 = await renderingPermission.canExecuteChart({ + renderingId: 60, + chartRequest: { + type: ChartType.Value, + sourceCollectionName: 'jedi', + aggregateFieldName: 'strength', + aggregator: 'Sum', + }, + userId: 42, + }); + + const resultB1 = await renderingPermission.canExecuteChart({ + renderingId: 63, + chartRequest: { + type: ChartType.Value, + sourceCollectionName: 'jedi', + aggregateFieldName: 'strength', + aggregator: 'Sum', + }, + userId: 42, + }); + + renderingPermission.invalidateAllCache(); + + const resultA2 = await renderingPermission.canExecuteChart({ + renderingId: 60, + chartRequest: { + type: ChartType.Value, + sourceCollectionName: 'jedi', + aggregateFieldName: 'strength', + aggregator: 'Sum', + }, + userId: 42, + }); + + const resultB2 = await renderingPermission.canExecuteChart({ + renderingId: 63, + chartRequest: { + type: ChartType.Value, + sourceCollectionName: 'jedi', + aggregateFieldName: 'strength', + aggregator: 'Sum', + }, + userId: 42, + }); + + expect(resultA1).toBe(true); + expect(resultA2).toBe(true); + expect(resultB1).toBe(true); + expect(resultB2).toBe(true); + + expect(serverInterface.getRenderingPermissions).toHaveBeenCalledTimes(4); + }); + }); + describe('canExecuteSegmentQuery', () => { it('should return true if the segment query is allowed', async () => { const {