tests: Add setupSingleRoomWithRecording function and refactor recording security tests

This commit is contained in:
juancarmore 2025-05-05 16:39:17 +02:00
parent 46bd1bcca8
commit 5671d58f1f
3 changed files with 100 additions and 32 deletions

View File

@ -90,6 +90,27 @@ export const setupMultiRoomTestContext = async (numRooms: number, withParticipan
};
};
export const setupSingleRoomWithRecording = async (
stopRecordingCond = false,
stopDelay?: StringValue
): Promise<RoomData> => {
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.

View File

@ -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);
});

View File

@ -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 () => {