fix: retrieve read-only state for realtime user status adapter from connection

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2023-05-09 11:19:57 +02:00
parent f012282a41
commit 2f59869e12
4 changed files with 29 additions and 24 deletions

View file

@ -68,21 +68,29 @@ describe('websocket connection', () => {
expect(sut.getRealtimeNote()).toBe(mockedRealtimeNote); expect(sut.getRealtimeNote()).toBe(mockedRealtimeNote);
}); });
it('returns the correct realtime user status', () => { it.each([true, false])(
const realtimeUserStatus = Mock.of<RealtimeUserStatusAdapter>(); 'returns the correct realtime user status with acceptEdits %s',
jest (acceptEdits) => {
.spyOn(RealtimeUserStatusModule, 'RealtimeUserStatusAdapter') const realtimeUserStatus = Mock.of<RealtimeUserStatusAdapter>();
.mockImplementation(() => realtimeUserStatus); jest
.spyOn(RealtimeUserStatusModule, 'RealtimeUserStatusAdapter')
.mockImplementation(
(username, displayName, connection, acceptCursorUpdateProvider) => {
expect(acceptCursorUpdateProvider()).toBe(acceptEdits);
return realtimeUserStatus;
},
);
const sut = new RealtimeConnection( const sut = new RealtimeConnection(
mockedMessageTransporter, mockedMessageTransporter,
mockedUser, mockedUser,
mockedRealtimeNote, mockedRealtimeNote,
true, acceptEdits,
); );
expect(sut.getRealtimeUserStateAdapter()).toBe(realtimeUserStatus); expect(sut.getRealtimeUserStateAdapter()).toBe(realtimeUserStatus);
}); },
);
it.each([true, false])( it.each([true, false])(
'creates a sync adapter with acceptEdits %s', 'creates a sync adapter with acceptEdits %s',
@ -91,7 +99,7 @@ describe('websocket connection', () => {
jest jest
.spyOn(HedgeDocCommonsModule, 'YDocSyncServerAdapter') .spyOn(HedgeDocCommonsModule, 'YDocSyncServerAdapter')
.mockImplementation((messageTransporter, doc, acceptEditsProvider) => { .mockImplementation((messageTransporter, doc, acceptEditsProvider) => {
expect((acceptEditsProvider as () => boolean)()).toBe(acceptEdits); expect(acceptEditsProvider()).toBe(acceptEdits);
return yDocSyncServerAdapter; return yDocSyncServerAdapter;
}); });

View file

@ -51,7 +51,7 @@ export class RealtimeConnection {
this.user?.username ?? null, this.user?.username ?? null,
this.getDisplayName(), this.getDisplayName(),
this, this,
acceptEdits, () => acceptEdits,
); );
} }

View file

@ -19,7 +19,7 @@ export class RealtimeUserStatusAdapter {
username: string | null, username: string | null,
displayName: string, displayName: string,
private connection: RealtimeConnection, private connection: RealtimeConnection,
private acceptCursorUpdate: boolean, private acceptCursorUpdateProvider: () => boolean,
) { ) {
this.realtimeUser = this.createInitialRealtimeUserState( this.realtimeUser = this.createInitialRealtimeUserState(
username, username,
@ -53,7 +53,7 @@ export class RealtimeUserStatusAdapter {
const transporterMessagesListener = connection.getTransporter().on( const transporterMessagesListener = connection.getTransporter().on(
MessageType.REALTIME_USER_SINGLE_UPDATE, MessageType.REALTIME_USER_SINGLE_UPDATE,
(message: Message<MessageType.REALTIME_USER_SINGLE_UPDATE>) => { (message: Message<MessageType.REALTIME_USER_SINGLE_UPDATE>) => {
if (this.isAcceptingCursorUpdates()) { if (this.acceptCursorUpdateProvider()) {
this.realtimeUser.cursor = message.payload; this.realtimeUser.cursor = message.payload;
this.sendRealtimeUserStatusUpdateEvent(connection); this.sendRealtimeUserStatusUpdateEvent(connection);
} }
@ -84,7 +84,7 @@ export class RealtimeUserStatusAdapter {
MessageType.REALTIME_USER_SET_ACTIVITY, MessageType.REALTIME_USER_SET_ACTIVITY,
(message: Message<MessageType.REALTIME_USER_SET_ACTIVITY>) => { (message: Message<MessageType.REALTIME_USER_SET_ACTIVITY>) => {
if ( if (
!this.isAcceptingCursorUpdates() || !this.acceptCursorUpdateProvider() ||
this.realtimeUser.active === message.payload.active this.realtimeUser.active === message.payload.active
) { ) {
return; return;
@ -116,7 +116,7 @@ export class RealtimeUserStatusAdapter {
receivingClient.getRealtimeUserStateAdapter().realtimeUser; receivingClient.getRealtimeUserStateAdapter().realtimeUser;
const realtimeUsers = this.collectAllConnectionsExcept(receivingClient) const realtimeUsers = this.collectAllConnectionsExcept(receivingClient)
.filter((client) => .filter((client) =>
client.getRealtimeUserStateAdapter().isAcceptingCursorUpdates(), client.getRealtimeUserStateAdapter().acceptCursorUpdateProvider(),
) )
.map((client) => client.getRealtimeUserStateAdapter().realtimeUser) .map((client) => client.getRealtimeUserStateAdapter().realtimeUser)
.filter((realtimeUser) => realtimeUser !== null); .filter((realtimeUser) => realtimeUser !== null);
@ -133,10 +133,6 @@ export class RealtimeUserStatusAdapter {
}); });
} }
private isAcceptingCursorUpdates(): boolean {
return this.acceptCursorUpdate;
}
private collectAllConnectionsExcept( private collectAllConnectionsExcept(
exceptClient: RealtimeConnection, exceptClient: RealtimeConnection,
): RealtimeConnection[] { ): RealtimeConnection[] {

View file

@ -112,7 +112,8 @@ export class MockConnectionBuilder {
this.username ?? null, this.username ?? null,
displayName, displayName,
connection, connection,
this.includeRealtimeUserStatus === RealtimeUserState.WITH_READWRITE, () =>
this.includeRealtimeUserStatus === RealtimeUserState.WITH_READWRITE,
); );
} }