From 5671d58f1f0db1dcf375eb2571fac83ad8daffca Mon Sep 17 00:00:00 2001 From: juancarmore Date: Mon, 5 May 2025 16:39:17 +0200 Subject: [PATCH] tests: Add setupSingleRoomWithRecording function and refactor recording security tests --- backend/tests/helpers/test-scenarios.ts | 21 ++++ .../api/security/participant-security.test.ts | 5 +- .../api/security/recording-security.test.ts | 106 +++++++++++++----- 3 files changed, 100 insertions(+), 32 deletions(-) diff --git a/backend/tests/helpers/test-scenarios.ts b/backend/tests/helpers/test-scenarios.ts index 7a4b7da..857a199 100644 --- a/backend/tests/helpers/test-scenarios.ts +++ b/backend/tests/helpers/test-scenarios.ts @@ -90,6 +90,27 @@ export const setupMultiRoomTestContext = async (numRooms: number, withParticipan }; }; +export const setupSingleRoomWithRecording = async ( + stopRecordingCond = false, + stopDelay?: StringValue +): Promise => { + const roomData = await setupSingleRoom(true); + const response = await startRecording(roomData.room.roomId, roomData.moderatorCookie); + expectValidStartRecordingResponse(response, roomData.room.roomId); + roomData.recordingId = response.body.recordingId; + + // Wait for the configured delay before stopping the recording + if (stopRecordingCond && stopDelay) { + await sleep(stopDelay); + } + + if (stopRecordingCond) { + await stopRecording(roomData.recordingId!, roomData.moderatorCookie); + } + + return roomData; +}; + /** * Quickly creates multiple recordings * Allows customizing how many recordings to start and how many to stop after a delay. diff --git a/backend/tests/integration/api/security/participant-security.test.ts b/backend/tests/integration/api/security/participant-security.test.ts index ab4fb6b..63ca654 100644 --- a/backend/tests/integration/api/security/participant-security.test.ts +++ b/backend/tests/integration/api/security/participant-security.test.ts @@ -19,7 +19,6 @@ describe('Participant API Security Tests', () => { let app: Express; let userCookie: string; - let roomData: RoomData; beforeAll(async () => { app = startTestServer(); @@ -32,6 +31,8 @@ describe('Participant API Security Tests', () => { }); describe('Generate Participant Token Tests', () => { + let roomData: RoomData; + beforeAll(async () => { roomData = await setupSingleRoom(); }); @@ -137,6 +138,8 @@ describe('Participant API Security Tests', () => { }); describe('Refresh Participant Token Tests', () => { + let roomData: RoomData; + beforeAll(async () => { roomData = await setupSingleRoom(true); }); diff --git a/backend/tests/integration/api/security/recording-security.test.ts b/backend/tests/integration/api/security/recording-security.test.ts index bdb71b3..017c1cf 100644 --- a/backend/tests/integration/api/security/recording-security.test.ts +++ b/backend/tests/integration/api/security/recording-security.test.ts @@ -1,11 +1,20 @@ -import { afterAll, beforeAll, describe, expect, it } from '@jest/globals'; +import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from '@jest/globals'; import { Express } from 'express'; import request from 'supertest'; import INTERNAL_CONFIG from '../../../../src/config/internal-config.js'; import { MEET_API_KEY } from '../../../../src/environment.js'; import { UserRole } from '../../../../src/typings/ce/index.js'; -import { deleteAllRooms, loginUserAsRole, startTestServer } from '../../../helpers/request-helpers.js'; -import { RoomData, setupSingleRoom } from '../../../helpers/test-scenarios.js'; +import { expectValidStopRecordingResponse } from '../../../helpers/assertion-helpers.js'; +import { + deleteAllRecordings, + deleteAllRooms, + disconnectFakeParticipants, + loginUserAsRole, + startTestServer, + stopAllRecordings, + stopRecording +} from '../../../helpers/request-helpers.js'; +import { RoomData, setupSingleRoom, setupSingleRoomWithRecording } from '../../../helpers/test-scenarios.js'; const RECORDINGS_PATH = `${INTERNAL_CONFIG.API_BASE_PATH_V1}/recordings`; const INTERNAL_RECORDINGS_PATH = `${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/recordings`; @@ -16,35 +25,38 @@ describe('Recording API Security Tests', () => { let userCookie: string; let adminCookie: string; - let roomData: RoomData; - let recordingId: string; - beforeAll(async () => { app = startTestServer(); // Get cookies for admin and user userCookie = await loginUserAsRole(UserRole.USER); adminCookie = await loginUserAsRole(UserRole.ADMIN); - - // Create a room and extract the roomId - roomData = await setupSingleRoom(); - recordingId = `${roomData.room.roomId}--EG_recordingId--uid`; }); afterAll(async () => { + await disconnectFakeParticipants(); await deleteAllRooms(); + await deleteAllRecordings(); }); describe('Start Recording Tests', () => { + let roomData: RoomData; + + beforeAll(async () => { + roomData = await setupSingleRoom(true); + }); + it('should succeed when participant is moderator', async () => { const response = await request(app) .post(INTERNAL_RECORDINGS_PATH) .send({ roomId: roomData.room.roomId }) .set('Cookie', roomData.moderatorCookie); + expect(response.status).toBe(201); - // The response code should be 409 to consider a success - // This is because there is no real participant inside the room and the recording will fail - expect(response.status).toBe(409); + // Stop recording to clean up + const recordingId = response.body.recordingId; + const stopResponse = await stopRecording(recordingId, roomData.moderatorCookie); + expectValidStopRecordingResponse(stopResponse, recordingId, roomData.room.roomId); }); it('should fail when participant is moderator of a different room', async () => { @@ -67,26 +79,35 @@ describe('Recording API Security Tests', () => { }); describe('Stop Recording Tests', () => { + let roomData: RoomData; + + beforeEach(async () => { + roomData = await setupSingleRoomWithRecording(); + }); + + afterEach(async () => { + await stopAllRecordings(roomData.moderatorCookie); + }); + it('should succeed when participant is moderator', async () => { const response = await request(app) - .post(`${INTERNAL_RECORDINGS_PATH}/${recordingId}/stop`) + .post(`${INTERNAL_RECORDINGS_PATH}/${roomData.recordingId}/stop`) .set('Cookie', roomData.moderatorCookie); - // The response code should be 404 to consider a success because the recording does not exist - expect(response.status).toBe(404); + expect(response.status).toBe(202); }); it('should fail when participant is moderator of a different room', async () => { const newRoomData = await setupSingleRoom(); const response = await request(app) - .post(`${INTERNAL_RECORDINGS_PATH}/${recordingId}/stop`) + .post(`${INTERNAL_RECORDINGS_PATH}/${roomData.recordingId}/stop`) .set('Cookie', newRoomData.moderatorCookie); expect(response.status).toBe(403); }); it('should fail when participant is publisher', async () => { const response = await request(app) - .post(`${INTERNAL_RECORDINGS_PATH}/${recordingId}/stop`) + .post(`${INTERNAL_RECORDINGS_PATH}/${roomData.recordingId}/stop`) .set('Cookie', roomData.publisherCookie); expect(response.status).toBe(403); }); @@ -115,18 +136,23 @@ describe('Recording API Security Tests', () => { }); describe('Get Recording Tests', () => { + let recordingId: string; + + beforeAll(async () => { + const roomData = await setupSingleRoomWithRecording(true); + recordingId = roomData.recordingId!; + }); + it('should succeed when request includes API key', async () => { const response = await request(app) .get(`${RECORDINGS_PATH}/${recordingId}`) .set(INTERNAL_CONFIG.API_KEY_HEADER, MEET_API_KEY); - // The response code should be 404 to consider a success because the recording does not exist - expect(response.status).toBe(404); + expect(response.status).toBe(200); }); it('should succeed when user is authenticated as admin', async () => { const response = await request(app).get(`${RECORDINGS_PATH}/${recordingId}`).set('Cookie', adminCookie); - // The response code should be 404 to consider a success because the recording does not exist - expect(response.status).toBe(404); + expect(response.status).toBe(200); }); it('should fail when user is authenticated as user', async () => { @@ -141,18 +167,23 @@ describe('Recording API Security Tests', () => { }); describe('Delete Recording Tests', () => { + let recordingId: string; + + beforeEach(async () => { + const roomData = await setupSingleRoomWithRecording(true); + recordingId = roomData.recordingId!; + }); + it('should succeed when request includes API key', async () => { const response = await request(app) .delete(`${RECORDINGS_PATH}/${recordingId}`) .set(INTERNAL_CONFIG.API_KEY_HEADER, MEET_API_KEY); - // The response code should be 404 to consider a success because the recording does not exist - expect(response.status).toBe(404); + expect(response.status).toBe(204); }); it('should succeed when user is authenticated as admin', async () => { const response = await request(app).delete(`${RECORDINGS_PATH}/${recordingId}`).set('Cookie', adminCookie); - // The response code should be 404 to consider a success because the recording does not exist - expect(response.status).toBe(404); + expect(response.status).toBe(204); }); it('should fail when user is authenticated as user', async () => { @@ -167,12 +198,19 @@ describe('Recording API Security Tests', () => { }); describe('Bulk Delete Recordings Tests', () => { + let recordingId: string; + + beforeEach(async () => { + const roomData = await setupSingleRoomWithRecording(true); + recordingId = roomData.recordingId!; + }); + it('should succeed when request includes API key', async () => { const response = await request(app) .delete(RECORDINGS_PATH) .query({ recordingIds: [recordingId] }) .set(INTERNAL_CONFIG.API_KEY_HEADER, MEET_API_KEY); - expect(response.status).toBe(200); + expect(response.status).toBe(204); }); it('should succeed when user is authenticated as admin', async () => { @@ -180,7 +218,7 @@ describe('Recording API Security Tests', () => { .delete(RECORDINGS_PATH) .query({ recordingIds: [recordingId] }) .set('Cookie', adminCookie); - expect(response.status).toBe(200); + expect(response.status).toBe(204); }); it('should fail when user is authenticated as user', async () => { @@ -199,13 +237,19 @@ describe('Recording API Security Tests', () => { }); }); - describe('Stream Recording Tests', () => { + describe('Get Recording Media Tests', () => { + let recordingId: string; + + beforeAll(async () => { + const roomData = await setupSingleRoomWithRecording(true); + recordingId = roomData.recordingId!; + }); + it('should succeed when user is authenticated as admin', async () => { const response = await request(app) .get(`${RECORDINGS_PATH}/${recordingId}/media`) .set('Cookie', adminCookie); - // The response code should be 404 to consider a success because the recording does not exist - expect(response.status).toBe(404); + expect(response.status).toBe(200); }); it('should fail when user is authenticated as user', async () => {