From f01ec31c1b76aad7b1f4e8cd4d2ae467d4ade54d Mon Sep 17 00:00:00 2001 From: juancarmore Date: Thu, 5 Feb 2026 12:21:37 +0100 Subject: [PATCH] test: update room member token response validation and permissions handling --- .../tests/helpers/assertion-helpers.ts | 90 +++++++++---------- .../api/meetings/kick-participant.test.ts | 8 +- .../api/meetings/update-participant.test.ts | 17 ++-- .../api/security/meeting-security.test.ts | 5 +- 4 files changed, 53 insertions(+), 67 deletions(-) diff --git a/meet-ce/backend/tests/helpers/assertion-helpers.ts b/meet-ce/backend/tests/helpers/assertion-helpers.ts index ce710fec..78836240 100644 --- a/meet-ce/backend/tests/helpers/assertion-helpers.ts +++ b/meet-ce/backend/tests/helpers/assertion-helpers.ts @@ -618,12 +618,27 @@ export const expectValidGetRecordingUrlResponse = (response: Response, recording export const expectValidRoomMemberTokenResponse = ( response: Response, - roomId: string, - baseRole: MeetRoomMemberRole, - joinMeeting = false, - participantName?: string, - participantIdentityPrefix?: string + validations: { + roomId: string; + memberId?: string; + baseRole: MeetRoomMemberRole; + customPermissions?: Partial; + effectivePermissions: MeetRoomMemberPermissions; + joinMeeting?: boolean; + participantName?: string; + participantIdentityPrefix?: string; + } ) => { + const { + roomId, + memberId, + baseRole, + effectivePermissions, + customPermissions, + joinMeeting = false, + participantName, + participantIdentityPrefix + } = validations; expect(response.status).toBe(200); expect(response.body).toHaveProperty('token'); @@ -639,8 +654,8 @@ export const expectValidRoomMemberTokenResponse = ( expect(decodedToken.sub?.startsWith(participantIdentityPrefix)).toBe(true); } - // const livekitPermissions = getLiveKitPermissions(roomId, getPermissions(baseRole)); - expect(decodedToken).toHaveProperty('video'); + const livekitPermissions = getLiveKitPermissions(roomId, effectivePermissions); + expect(decodedToken).toHaveProperty('video', livekitPermissions); } else { expect(decodedToken).not.toHaveProperty('name'); expect(decodedToken).not.toHaveProperty('sub'); @@ -649,65 +664,40 @@ export const expectValidRoomMemberTokenResponse = ( expect(decodedToken).toHaveProperty('metadata'); const metadata = JSON.parse(decodedToken.metadata || '{}'); + expect(metadata).toHaveProperty('iat'); expect(metadata).toHaveProperty('livekitUrl'); + expect(metadata).toHaveProperty('roomId', roomId); expect(metadata).toHaveProperty('baseRole', baseRole); - const permissions = getPermissions(baseRole); - expect(metadata).toHaveProperty('effectivePermissions', permissions); -}; -export const getPermissions = (role: MeetRoomMemberRole): MeetRoomMemberPermissions => { - switch (role) { - case MeetRoomMemberRole.MODERATOR: - return { - canRecord: true, - canRetrieveRecordings: true, - canDeleteRecordings: true, - canJoinMeeting: true, - canShareAccessLinks: true, - canMakeModerator: true, - canKickParticipants: true, - canEndMeeting: true, - canPublishVideo: true, - canPublishAudio: true, - canShareScreen: true, - canReadChat: true, - canWriteChat: true, - canChangeVirtualBackground: true - }; - case MeetRoomMemberRole.SPEAKER: - return { - canRecord: false, - canRetrieveRecordings: true, - canDeleteRecordings: false, - canJoinMeeting: true, - canShareAccessLinks: false, - canMakeModerator: false, - canKickParticipants: false, - canEndMeeting: false, - canPublishVideo: true, - canPublishAudio: true, - canShareScreen: true, - canReadChat: true, - canWriteChat: true, - canChangeVirtualBackground: true - }; + if (memberId) { + expect(metadata).toHaveProperty('memberId', memberId); + } else { + expect(metadata).not.toHaveProperty('memberId'); } + + if (customPermissions) { + expect(metadata).toHaveProperty('customPermissions', customPermissions); + } else { + expect(metadata).not.toHaveProperty('customPermissions'); + } + + expect(metadata).toHaveProperty('effectivePermissions', effectivePermissions); }; const getLiveKitPermissions = (roomId: string, permissions: MeetRoomMemberPermissions): LiveKitPermissions => { const canPublishSources: TrackSource[] = []; if (permissions.canPublishAudio) { - canPublishSources.push(TrackSource.MICROPHONE); + canPublishSources.push('microphone' as unknown as TrackSource); } if (permissions.canPublishVideo) { - canPublishSources.push(TrackSource.CAMERA); + canPublishSources.push('camera' as unknown as TrackSource); } if (permissions.canShareScreen) { - canPublishSources.push(TrackSource.SCREEN_SHARE); - canPublishSources.push(TrackSource.SCREEN_SHARE_AUDIO); + canPublishSources.push('screen_share' as unknown as TrackSource); + canPublishSources.push('screen_share_audio' as unknown as TrackSource); } const livekitPermissions: LiveKitPermissions = { diff --git a/meet-ce/backend/tests/integration/api/meetings/kick-participant.test.ts b/meet-ce/backend/tests/integration/api/meetings/kick-participant.test.ts index ece3211c..7e2c054d 100644 --- a/meet-ce/backend/tests/integration/api/meetings/kick-participant.test.ts +++ b/meet-ce/backend/tests/integration/api/meetings/kick-participant.test.ts @@ -43,11 +43,9 @@ describe('Meetings API Tests', () => { expect(response.status).toBe(200); // Check if the participant has been removed from LiveKit - try { - await livekitService.getParticipant(roomData.room.roomId, participantIdentity); - } catch (error) { - expect((error as OpenViduMeetError).statusCode).toBe(404); - } + await expect(livekitService.getParticipant(roomData.room.roomId, participantIdentity)).rejects.toThrow( + OpenViduMeetError + ); }); it('should fail with 404 if participant does not exist', async () => { diff --git a/meet-ce/backend/tests/integration/api/meetings/update-participant.test.ts b/meet-ce/backend/tests/integration/api/meetings/update-participant.test.ts index dcdaab82..7e884ff0 100644 --- a/meet-ce/backend/tests/integration/api/meetings/update-participant.test.ts +++ b/meet-ce/backend/tests/integration/api/meetings/update-participant.test.ts @@ -4,7 +4,6 @@ import { container } from '../../../../src/config/dependency-injector.config.js' import { MEET_ENV } from '../../../../src/environment.js'; import { FrontendEventService } from '../../../../src/services/frontend-event.service.js'; import { LiveKitService } from '../../../../src/services/livekit.service.js'; -import { getPermissions } from '../../../helpers/assertion-helpers.js'; import { deleteAllRooms, disconnectFakeParticipants, @@ -32,15 +31,15 @@ describe('Meetings API Tests', () => { }); describe('Update Participant Tests', () => { - const setParticipantMetadata = async (roomId: string, baseRole: MeetRoomMemberRole) => { + const setParticipantMetadata = async (roomData: RoomData, baseRole: MeetRoomMemberRole) => { const metadata: MeetRoomMemberTokenMetadata = { iat: Date.now(), livekitUrl: MEET_ENV.LIVEKIT_URL, - roomId, + roomId: roomData.room.roomId, baseRole, - effectivePermissions: getPermissions(baseRole) + effectivePermissions: roomData.room.roles[baseRole].permissions }; - await updateParticipantMetadata(roomId, participantIdentity, metadata); + await updateParticipantMetadata(roomData.room.roomId, participantIdentity, metadata); }; beforeEach(async () => { @@ -51,7 +50,7 @@ describe('Meetings API Tests', () => { const frontendEventService = container.get(FrontendEventService); const sendSignalSpy = jest.spyOn(frontendEventService as any, 'sendSignal'); - await setParticipantMetadata(roomData.room.roomId, MeetRoomMemberRole.SPEAKER); + await setParticipantMetadata(roomData, MeetRoomMemberRole.SPEAKER); const response = await updateParticipant( roomData.room.roomId, @@ -68,7 +67,7 @@ describe('Meetings API Tests', () => { const metadata = JSON.parse(participant.metadata || '{}'); expect(metadata).toHaveProperty('roomId', roomData.room.roomId); expect(metadata).toHaveProperty('baseRole', MeetRoomMemberRole.MODERATOR); - const permissions = getPermissions(MeetRoomMemberRole.MODERATOR); + const permissions = roomData.room.roles.moderator.permissions; expect(metadata).toHaveProperty('effectivePermissions', permissions); // Verify sendSignal method has been called twice @@ -108,7 +107,7 @@ describe('Meetings API Tests', () => { }); it('should update participant role from moderator to speaker', async () => { - await setParticipantMetadata(roomData.room.roomId, MeetRoomMemberRole.MODERATOR); + await setParticipantMetadata(roomData, MeetRoomMemberRole.MODERATOR); const response = await updateParticipant( roomData.room.roomId, @@ -125,7 +124,7 @@ describe('Meetings API Tests', () => { const metadata = JSON.parse(participant.metadata || '{}'); expect(metadata).toHaveProperty('roomId', roomData.room.roomId); expect(metadata).toHaveProperty('baseRole', MeetRoomMemberRole.SPEAKER); - const permissions = getPermissions(MeetRoomMemberRole.SPEAKER); + const permissions = roomData.room.roles.speaker.permissions; expect(metadata).toHaveProperty('effectivePermissions', permissions); }); diff --git a/meet-ce/backend/tests/integration/api/security/meeting-security.test.ts b/meet-ce/backend/tests/integration/api/security/meeting-security.test.ts index 15eb16d6..bdc80471 100644 --- a/meet-ce/backend/tests/integration/api/security/meeting-security.test.ts +++ b/meet-ce/backend/tests/integration/api/security/meeting-security.test.ts @@ -4,7 +4,6 @@ import { Express } from 'express'; import request from 'supertest'; import { INTERNAL_CONFIG } from '../../../../src/config/internal-config.js'; import { MEET_ENV } from '../../../../src/environment.js'; -import { getPermissions } from '../../../helpers/assertion-helpers.js'; import { deleteAllRooms, disconnectFakeParticipants, @@ -33,7 +32,7 @@ describe('Meeting API Security Tests', () => { app = await startTestServer(); ({ accessToken: rootAdminAccessToken } = await loginRootAdmin()); - roomData = await setupSingleRoom(); + roomData = await setupSingleRoom(true); roomId = roomData.room.roomId; roomMember = await setupRoomMember(roomId, { name: 'External Member', @@ -105,7 +104,7 @@ describe('Meeting API Security Tests', () => { livekitUrl: MEET_ENV.LIVEKIT_URL, roomId, baseRole: MeetRoomMemberRole.SPEAKER, - effectivePermissions: getPermissions(MeetRoomMemberRole.SPEAKER) + effectivePermissions: roomData.room.roles.speaker.permissions }; await updateParticipantMetadata(roomId, participantIdentity, metadata); };