From 2f59869e122b4f2a4bc0cbeb1bd17532e66ea6ab Mon Sep 17 00:00:00 2001 From: Tilman Vatteroth Date: Tue, 9 May 2023 11:19:57 +0200 Subject: [PATCH] fix: retrieve read-only state for realtime user status adapter from connection Signed-off-by: Tilman Vatteroth --- .../realtime-note/realtime-connection.spec.ts | 36 +++++++++++-------- .../realtime-note/realtime-connection.ts | 2 +- .../realtime-user-status-adapter.ts | 12 +++---- .../test-utils/mock-connection.ts | 3 +- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/backend/src/realtime/realtime-note/realtime-connection.spec.ts b/backend/src/realtime/realtime-note/realtime-connection.spec.ts index 181a90dda..4146212f7 100644 --- a/backend/src/realtime/realtime-note/realtime-connection.spec.ts +++ b/backend/src/realtime/realtime-note/realtime-connection.spec.ts @@ -68,21 +68,29 @@ describe('websocket connection', () => { expect(sut.getRealtimeNote()).toBe(mockedRealtimeNote); }); - it('returns the correct realtime user status', () => { - const realtimeUserStatus = Mock.of(); - jest - .spyOn(RealtimeUserStatusModule, 'RealtimeUserStatusAdapter') - .mockImplementation(() => realtimeUserStatus); + it.each([true, false])( + 'returns the correct realtime user status with acceptEdits %s', + (acceptEdits) => { + const realtimeUserStatus = Mock.of(); + jest + .spyOn(RealtimeUserStatusModule, 'RealtimeUserStatusAdapter') + .mockImplementation( + (username, displayName, connection, acceptCursorUpdateProvider) => { + expect(acceptCursorUpdateProvider()).toBe(acceptEdits); + return realtimeUserStatus; + }, + ); - const sut = new RealtimeConnection( - mockedMessageTransporter, - mockedUser, - mockedRealtimeNote, - true, - ); + const sut = new RealtimeConnection( + mockedMessageTransporter, + mockedUser, + mockedRealtimeNote, + acceptEdits, + ); - expect(sut.getRealtimeUserStateAdapter()).toBe(realtimeUserStatus); - }); + expect(sut.getRealtimeUserStateAdapter()).toBe(realtimeUserStatus); + }, + ); it.each([true, false])( 'creates a sync adapter with acceptEdits %s', @@ -91,7 +99,7 @@ describe('websocket connection', () => { jest .spyOn(HedgeDocCommonsModule, 'YDocSyncServerAdapter') .mockImplementation((messageTransporter, doc, acceptEditsProvider) => { - expect((acceptEditsProvider as () => boolean)()).toBe(acceptEdits); + expect(acceptEditsProvider()).toBe(acceptEdits); return yDocSyncServerAdapter; }); diff --git a/backend/src/realtime/realtime-note/realtime-connection.ts b/backend/src/realtime/realtime-note/realtime-connection.ts index db6d77284..fc0799b9f 100644 --- a/backend/src/realtime/realtime-note/realtime-connection.ts +++ b/backend/src/realtime/realtime-note/realtime-connection.ts @@ -51,7 +51,7 @@ export class RealtimeConnection { this.user?.username ?? null, this.getDisplayName(), this, - acceptEdits, + () => acceptEdits, ); } diff --git a/backend/src/realtime/realtime-note/realtime-user-status-adapter.ts b/backend/src/realtime/realtime-note/realtime-user-status-adapter.ts index ac3c329f5..2fe83db08 100644 --- a/backend/src/realtime/realtime-note/realtime-user-status-adapter.ts +++ b/backend/src/realtime/realtime-note/realtime-user-status-adapter.ts @@ -19,7 +19,7 @@ export class RealtimeUserStatusAdapter { username: string | null, displayName: string, private connection: RealtimeConnection, - private acceptCursorUpdate: boolean, + private acceptCursorUpdateProvider: () => boolean, ) { this.realtimeUser = this.createInitialRealtimeUserState( username, @@ -53,7 +53,7 @@ export class RealtimeUserStatusAdapter { const transporterMessagesListener = connection.getTransporter().on( MessageType.REALTIME_USER_SINGLE_UPDATE, (message: Message) => { - if (this.isAcceptingCursorUpdates()) { + if (this.acceptCursorUpdateProvider()) { this.realtimeUser.cursor = message.payload; this.sendRealtimeUserStatusUpdateEvent(connection); } @@ -84,7 +84,7 @@ export class RealtimeUserStatusAdapter { MessageType.REALTIME_USER_SET_ACTIVITY, (message: Message) => { if ( - !this.isAcceptingCursorUpdates() || + !this.acceptCursorUpdateProvider() || this.realtimeUser.active === message.payload.active ) { return; @@ -116,7 +116,7 @@ export class RealtimeUserStatusAdapter { receivingClient.getRealtimeUserStateAdapter().realtimeUser; const realtimeUsers = this.collectAllConnectionsExcept(receivingClient) .filter((client) => - client.getRealtimeUserStateAdapter().isAcceptingCursorUpdates(), + client.getRealtimeUserStateAdapter().acceptCursorUpdateProvider(), ) .map((client) => client.getRealtimeUserStateAdapter().realtimeUser) .filter((realtimeUser) => realtimeUser !== null); @@ -133,10 +133,6 @@ export class RealtimeUserStatusAdapter { }); } - private isAcceptingCursorUpdates(): boolean { - return this.acceptCursorUpdate; - } - private collectAllConnectionsExcept( exceptClient: RealtimeConnection, ): RealtimeConnection[] { diff --git a/backend/src/realtime/realtime-note/test-utils/mock-connection.ts b/backend/src/realtime/realtime-note/test-utils/mock-connection.ts index ffde2d2ac..a24c929e6 100644 --- a/backend/src/realtime/realtime-note/test-utils/mock-connection.ts +++ b/backend/src/realtime/realtime-note/test-utils/mock-connection.ts @@ -112,7 +112,8 @@ export class MockConnectionBuilder { this.username ?? null, displayName, connection, - this.includeRealtimeUserStatus === RealtimeUserState.WITH_READWRITE, + () => + this.includeRealtimeUserStatus === RealtimeUserState.WITH_READWRITE, ); }