diff --git a/frontend/src/utils/collab.ts b/frontend/src/utils/collab.ts index 9b4473fe..24e1f562 100644 --- a/frontend/src/utils/collab.ts +++ b/frontend/src/utils/collab.ts @@ -668,6 +668,10 @@ export function useCollab(storeState: CollabStoreState) { } function sendAwarenessThrottled() { + if (!storeState.permissions.write) { + return; + } + sendEventsThrottled({ type: CollabEventType.AWARENESS, path: storeState.awareness.self.path, diff --git a/frontend/test/collab.test.ts b/frontend/test/collab.test.ts index 92b5d411..7dbb926c 100644 --- a/frontend/test/collab.test.ts +++ b/frontend/test/collab.test.ts @@ -4,6 +4,7 @@ import { v4 as uuid4 } from 'uuid' import { cloneDeep } from 'lodash-es' import { CollabEventType, type CollabEvent, type Comment, type User } from '#imports'; import { ChangeSet, EditorSelection } from 'reportcreator-markdown/editor'; +import { fa } from 'vuetify/locale'; async function createCollab(options?: { collabInitEvent?: Partial }) { @@ -183,6 +184,40 @@ describe('connection', () => { }); +describe('readonly connection', () => { + let { connection, collab, collabInitEvent }: Awaited> = {} as any; + beforeEach(async () => { + const res = await createCollab({ + collabInitEvent: { + permissions: { + read: true, + write: false, + } + } + }); + collab = res.collab; + connection = res.connection; + collabInitEvent = res.collabInitEvent; + }); + + test('no events sent', async () => { + collab.onCollabEvent({ type: CollabEventType.AWARENESS, path: collab.storeState.apiPath + 'field_text'}); + collab.onCollabEvent({ type: CollabEventType.UPDATE_KEY, path: collab.storeState.apiPath + 'field_key', value: 'x' }); + collab.onCollabEvent({ type: CollabEventType.DELETE, path: collab.storeState.apiPath + 'field_list[0]' }); + collab.onCollabEvent({ type: CollabEventType.CREATE, path: collab.storeState.apiPath + 'field_list', value: 'new'}); + collab.onCollabEvent({ + type: CollabEventType.UPDATE_TEXT, + path: collab.storeState.apiPath + 'field_text', + updates: [{changes: ChangeSet.fromJSON([4, [0, 'E']])}] + }); + await vi.runOnlyPendingTimersAsync(); + expect(connection.send).not.toHaveBeenCalled(); + expect(collab.storeState.data).toEqual(collabInitEvent.data); + expect(collab.storeState.awareness.self).toEqual({ path: '' }); + }); +}); + + describe('send and receive', () => { let { collab, connection, collabInitEvent }: Awaited> = {} as any; beforeEach(async () => {