diff --git a/backend/openapi/components/responses/success-get-room.yaml b/backend/openapi/components/responses/success-get-room.yaml index f00fd5c..8369c97 100644 --- a/backend/openapi/components/responses/success-get-room.yaml +++ b/backend/openapi/components/responses/success-get-room.yaml @@ -8,7 +8,7 @@ content: summary: Full room details response value: roomId: 'room-123' - roomIdPrefix: 'room' + roomName: 'room' creationDate: 1620000000000 autoDeletionDate: 1900000000000 preferences: @@ -26,11 +26,11 @@ content: value: roomId: 'room-123' - fields=roomId,roomIdPrefix,creationDate,autoDeletionDate,preferences: - summary: Room details with roomId, roomIdPrefix, creationDate, autoDeletionDate, and preferences + fields=roomId,roomName,creationDate,autoDeletionDate,preferences: + summary: Room details with roomId, roomName, creationDate, autoDeletionDate, and preferences value: roomId: 'room-123' - roomIdPrefix: 'room' + roomName: 'room' creationDate: 1620000000000 autoDeletionDate: 1900000000000 preferences: diff --git a/backend/openapi/components/responses/success-get-rooms.yaml b/backend/openapi/components/responses/success-get-rooms.yaml index c25be43..9c78449 100644 --- a/backend/openapi/components/responses/success-get-rooms.yaml +++ b/backend/openapi/components/responses/success-get-rooms.yaml @@ -17,7 +17,7 @@ content: value: rooms: - roomId: 'room-123' - roomIdPrefix: 'room' + roomName: 'room' creationDate: 1620000000000 autoDeletionDate: 1900000000000 preferences: @@ -30,7 +30,7 @@ content: moderatorURL: 'http://localhost:6080/room/room-123?secret=123456' publisherURL: 'http://localhost:6080/room/room-123?secret=654321' - roomId: 'room-456' - roomIdPrefix: 'room' + roomName: 'room' creationDate: 1620001000000 autoDeletionDate: 1900000000000 preferences: @@ -55,12 +55,12 @@ content: isTruncated: false maxItems: 10 - fields=roomId,roomIdPrefix,creationDate,autoDeletionDate,preferences: + fields=roomId,roomName,creationDate,autoDeletionDate,preferences: summary: Room details including preferences but no URLs value: rooms: - roomId: 'room-123' - roomIdPrefix: 'room' + roomName: 'room' creationDate: 1620000000000 autoDeletionDate: 1900000000000 preferences: @@ -71,7 +71,7 @@ content: virtualBackgroundPreferences: enabled: true - roomId: 'room-456' - roomIdPrefix: 'room' + roomName: 'room' creationDate: 1620001000000 autoDeletionDate: 1900000000000 preferences: diff --git a/backend/openapi/components/schemas/meet-room-options.yaml b/backend/openapi/components/schemas/meet-room-options.yaml index adc0a82..ecd6942 100644 --- a/backend/openapi/components/schemas/meet-room-options.yaml +++ b/backend/openapi/components/schemas/meet-room-options.yaml @@ -1,5 +1,14 @@ type: object properties: + roomName: + type: [string, 'null'] + maxLength: 50 + example: 'room' + default: 'Room' + description: | + The display name of the room, used to identify it in a user-friendly way. This value does not need to be unique. + + Maximum length: 50 characters. If not provided, the default value "Room" will be used. autoDeletionDate: type: [number, 'null'] example: 1900000000000 @@ -11,12 +20,6 @@ properties: It will be removed after the last participant leaves (graceful deletion). If not set, the room remains active until manually deleted. - roomIdPrefix: - type: string - example: 'room' - description: > - A prefix to be used for the room ID. The room ID will be generated by concatenating this prefix with an unique identifier. - The maximum length of the room ID is 50 characters. # maxParticipants: # type: integer # example: 10 diff --git a/backend/openapi/components/schemas/meet-room.yaml b/backend/openapi/components/schemas/meet-room.yaml index 5f169d7..2891f7d 100644 --- a/backend/openapi/components/schemas/meet-room.yaml +++ b/backend/openapi/components/schemas/meet-room.yaml @@ -4,12 +4,16 @@ properties: type: string example: 'room-123' description: > - The unique identifier of the room. This ID is generated when the room is created. - roomIdPrefix: - type: string + The unique identifier of the room. This ID is generated by combining the room name with a unique identifier. + roomName: + type: [string, 'null'] + maxLength: 50 example: 'room' - description: > - The prefix used for the room ID. This prefix is used to generate the room ID. + default: 'Room' + description: | + The display name of the room, used to identify it in a user-friendly way. This value does not need to be unique. + + Maximum length: 50 characters. If not provided, the default value "Room" will be used. creationDate: type: number example: 1620000000000 diff --git a/backend/src/helpers/room.helper.ts b/backend/src/helpers/room.helper.ts index 45e3f2e..fcf729c 100644 --- a/backend/src/helpers/room.helper.ts +++ b/backend/src/helpers/room.helper.ts @@ -14,10 +14,10 @@ export class MeetRoomHelper { */ static toOpenViduOptions(room: MeetRoom): MeetRoomOptions { return { + roomName: room.roomName, autoDeletionDate: room.autoDeletionDate, - // maxParticipants: room.maxParticipants, - preferences: room.preferences, - roomIdPrefix: room.roomIdPrefix + preferences: room.preferences + // maxParticipants: room.maxParticipants }; } diff --git a/backend/src/middlewares/request-validators/room-validator.middleware.ts b/backend/src/middlewares/request-validators/room-validator.middleware.ts index 0e9578a..2b8d881 100644 --- a/backend/src/middlewares/request-validators/room-validator.middleware.ts +++ b/backend/src/middlewares/request-validators/room-validator.middleware.ts @@ -13,6 +13,25 @@ import { z } from 'zod'; import INTERNAL_CONFIG from '../../config/internal-config.js'; import { rejectUnprocessableRequest } from '../../models/error.model.js'; +/** + * Sanitizes a room name by removing invalid characters and normalizing format. + * + * @param val The string to sanitize + * @returns A sanitized string safe for use as a room name + */ +const sanitizeRoomName = (val: string): string => { + return val + .trim() // Remove leading/trailing spaces + .replace(/[^a-zA-Z0-9_-\s]/g, '') // Allow alphanumeric, underscores, hyphens and spaces + .replace(/\s+/g, ' ') // Replace multiple consecutive spaces with a single space + .replace(/-+/g, '-') // Replace multiple consecutive hyphens with a single hyphen + .replace(/_+/g, '_') // Replace multiple consecutive underscores with a single underscore + .replace(/-+$/, '') // Remove trailing hyphens + .replace(/_+$/, '') // Remove trailing underscores + .replace(/^-+/, '') // Remove leading hyphens + .replace(/^_+/, ''); // Remove leading underscores +}; + /** * Sanitizes an identifier by removing/replacing invalid characters * and normalizing format. @@ -21,19 +40,7 @@ import { rejectUnprocessableRequest } from '../../models/error.model.js'; * @returns A sanitized string safe for use as an identifier */ const sanitizeRoomId = (val: string): string => { - let transformed = val - .trim() // Remove leading/trailing spaces - .replace(/\s+/g, '') // Remove all spaces - .replace(/[^a-zA-Z0-9_-]/g, '') // Allow alphanumeric, underscores and hyphens - .replace(/-+/g, '-') // Replace multiple consecutive hyphens - .replace(/-+$/, ''); // Remove trailing hyphens - - // Remove leading hyphens - if (transformed.startsWith('-')) { - transformed = transformed.substring(1); - } - - return transformed; + return sanitizeRoomName(val).replace(/\s+/g, ''); // Remove all spaces }; export const nonEmptySanitizedRoomId = (fieldName: string) => @@ -94,6 +101,12 @@ const RoomPreferencesSchema: z.ZodType = z.object({ }); const RoomRequestOptionsSchema: z.ZodType = z.object({ + roomName: z + .string() + .max(50, 'roomName cannot exceed 50 characters') + .transform(sanitizeRoomName) + .optional() + .default('Room'), autoDeletionDate: z .number() .positive('autoDeletionDate must be a positive integer') @@ -102,12 +115,6 @@ const RoomRequestOptionsSchema: z.ZodType = z.object({ `autoDeletionDate must be at least ${INTERNAL_CONFIG.MIN_FUTURE_TIME_FOR_ROOM_AUTODELETION_DATE} in the future` ) .optional(), - roomIdPrefix: z - .string() - .max(50, 'roomIdPrefix cannot exceed 50 characters') - .transform(sanitizeRoomId) - .optional() - .default(''), preferences: RoomPreferencesSchema.optional().default({ recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER }, chatPreferences: { enabled: true }, @@ -185,6 +192,7 @@ export const withValidRoomOptions = (req: Request, res: Response, next: NextFunc return rejectUnprocessableRequest(res, error); } + console.log('VALID ROOM OPTIONS', data); req.body = data; next(); }; diff --git a/backend/src/routes/room.routes.ts b/backend/src/routes/room.routes.ts index 9d831f3..cfe92ea 100644 --- a/backend/src/routes/room.routes.ts +++ b/backend/src/routes/room.routes.ts @@ -50,7 +50,6 @@ roomRouter.get( configureRoomAuthorization, roomCtrl.getRoom ); - roomRouter.put( '/:roomId', withAuth(apiKeyValidator, tokenAndRoleValidator(UserRole.ADMIN)), diff --git a/backend/src/services/room.service.ts b/backend/src/services/room.service.ts index 2ee2850..fb26520 100644 --- a/backend/src/services/room.service.ts +++ b/backend/src/services/room.service.ts @@ -69,12 +69,13 @@ export class RoomService { * */ async createMeetRoom(baseUrl: string, roomOptions: MeetRoomOptions): Promise { - const { preferences, autoDeletionDate, roomIdPrefix } = roomOptions; - const roomId = roomIdPrefix ? `${roomIdPrefix}-${uid(15)}` : uid(15); + const { roomName, autoDeletionDate, preferences } = roomOptions; + const roomIdPrefix = roomName!.replace(/\s+/g, ''); // Remove all spaces + const roomId = `${roomIdPrefix}-${uid(15)}`; // Generate a unique room ID based on the room name const meetRoom: MeetRoom = { roomId, - roomIdPrefix, + roomName: roomName!, creationDate: Date.now(), // maxParticipants, autoDeletionDate, diff --git a/backend/tests/helpers/assertion-helpers.ts b/backend/tests/helpers/assertion-helpers.ts index 0df4c5d..3e54528 100644 --- a/backend/tests/helpers/assertion-helpers.ts +++ b/backend/tests/helpers/assertion-helpers.ts @@ -86,12 +86,12 @@ export const expectSuccessRoomsResponse = ( export const expectSuccessRoomResponse = ( response: any, - idPrefix: string, + roomName: string, autoDeletionDate?: number, preferences?: MeetRoomPreferences ) => { expect(response.status).toBe(200); - expectValidRoom(response.body, idPrefix, autoDeletionDate, preferences); + expectValidRoom(response.body, roomName, autoDeletionDate, preferences); }; export const expectSuccessRoomPreferencesResponse = (response: any, preferences: MeetRoomPreferences) => { @@ -102,7 +102,7 @@ export const expectSuccessRoomPreferencesResponse = (response: any, preferences: export const expectValidRoom = ( room: MeetRoom, - idPrefix: string, + name: string, autoDeletionDate?: number, preferences?: MeetRoomPreferences, markedForDeletion?: boolean @@ -110,10 +110,10 @@ export const expectValidRoom = ( expect(room).toBeDefined(); expect(room.roomId).toBeDefined(); - expect(room.roomIdPrefix).toBeDefined(); - expect(room.roomIdPrefix).toBe(idPrefix); + expect(room.roomName).toBeDefined(); + expect(room.roomName).toBe(name); expect(room.roomId).not.toBe(''); - expect(room.roomId).toContain(room.roomIdPrefix); + expect(room.roomId).toContain(room.roomName.replace(/\s+/g, '')); // Ensure roomId contains the name without spaces expect(room.creationDate).toBeDefined(); if (autoDeletionDate !== undefined) { diff --git a/backend/tests/helpers/test-scenarios.ts b/backend/tests/helpers/test-scenarios.ts index b7cf0e7..39993ae 100644 --- a/backend/tests/helpers/test-scenarios.ts +++ b/backend/tests/helpers/test-scenarios.ts @@ -34,15 +34,17 @@ export interface TestContext { * Creates a single room with optional participant. * * @param withParticipant Whether to join a fake participant in the room. + * @param roomName Name of the room to create. + * @param preferences Optional room preferences. * @returns Room data including secrets and cookies. */ export const setupSingleRoom = async ( withParticipant = false, - roomPrefix = 'TEST_ROOM', + roomName = 'TEST_ROOM', preferences?: MeetRoomPreferences ): Promise => { const room = await createRoom({ - roomIdPrefix: roomPrefix, + roomName, preferences }); diff --git a/backend/tests/integration/api/rooms/bulk-delete-rooms.test.ts b/backend/tests/integration/api/rooms/bulk-delete-rooms.test.ts index 77d7fe9..dba7aa8 100644 --- a/backend/tests/integration/api/rooms/bulk-delete-rooms.test.ts +++ b/backend/tests/integration/api/rooms/bulk-delete-rooms.test.ts @@ -31,7 +31,7 @@ describe('Room API Tests', () => { }); it('should delete room (204) with invalid force parameter when no participants exist', async () => { - const { roomId } = await createRoom({ roomIdPrefix: 'test-invalid-force' }); + const { roomId } = await createRoom({ roomName: 'test-invalid-force' }); const response = await bulkDeleteRooms([roomId]); @@ -41,7 +41,7 @@ describe('Room API Tests', () => { }); it('should mark room for deletion (202) with invalid force parameter when participants exist', async () => { - const { roomId } = await createRoom({ roomIdPrefix: 'test-invalid-force' }); + const { roomId } = await createRoom({ roomName: 'test-invalid-force' }); await joinFakeParticipant(roomId, 'test-participant-1'); @@ -53,7 +53,7 @@ describe('Room API Tests', () => { }); it('should delete room (204) with force=true parameter when no participants exist', async () => { - const { roomId } = await createRoom({ roomIdPrefix: 'test-force' }); + const { roomId } = await createRoom({ roomName: 'test-force' }); const response = await bulkDeleteRooms([roomId], true); @@ -63,7 +63,7 @@ describe('Room API Tests', () => { }); it('should delete room (204) with force=true parameter when participants exist', async () => { - const { roomId } = await createRoom({ roomIdPrefix: 'test-force' }); + const { roomId } = await createRoom({ roomName: 'test-force' }); await joinFakeParticipant(roomId, 'test-participant-1'); @@ -75,7 +75,7 @@ describe('Room API Tests', () => { }); it('should successfully delete the room requesting the same roomId multiple times', async () => { - const { roomId } = await createRoom({ roomIdPrefix: 'test-duplicate' }); + const { roomId } = await createRoom({ roomName: 'test-duplicate' }); const response = await bulkDeleteRooms([roomId, roomId, roomId], true); @@ -84,7 +84,7 @@ describe('Room API Tests', () => { }); it('should successfully delete valid roomIds while ignoring invalid ones', async () => { - const { roomId } = await createRoom({ roomIdPrefix: 'test-invalid-force' }); + const { roomId } = await createRoom({ roomName: 'test-invalid-force' }); const response = await bulkDeleteRooms([roomId, '!!@##$']); @@ -95,8 +95,8 @@ describe('Room API Tests', () => { it('should successfully delete multiple rooms with valid roomIds', async () => { // Create test rooms const [room1, room2] = await Promise.all([ - createRoom({ roomIdPrefix: 'test-bulk-1' }), - createRoom({ roomIdPrefix: 'test-bulk-2' }) + createRoom({ roomName: 'test-bulk-1' }), + createRoom({ roomName: 'test-bulk-2' }) ]); // Delete both rooms @@ -117,8 +117,8 @@ describe('Room API Tests', () => { it('should successfully marked for deletion multiple rooms with valid roomIds', async () => { // Create test rooms const [room1, room2] = await Promise.all([ - createRoom({ roomIdPrefix: 'test-bulk-1' }), - createRoom({ roomIdPrefix: 'test-bulk-2' }) + createRoom({ roomName: 'test-bulk-1' }), + createRoom({ roomName: 'test-bulk-2' }) ]); await Promise.all([ @@ -147,7 +147,7 @@ describe('Room API Tests', () => { it('should sanitize roomIds before deleting', async () => { // Create a test room - const { roomId } = await createRoom({ roomIdPrefix: 'test-sanitize' }); + const { roomId } = await createRoom({ roomName: 'test-sanitize' }); const response = await bulkDeleteRooms([roomId + '!!@##$']); expect(response.status).toBe(204); @@ -160,8 +160,8 @@ describe('Room API Tests', () => { it('should delete rooms when force=true and participants exist', async () => { // Create test rooms const [room1, room2] = await Promise.all([ - createRoom({ roomIdPrefix: 'test-bulk-1' }), - createRoom({ roomIdPrefix: 'test-bulk-2' }) + createRoom({ roomName: 'test-bulk-1' }), + createRoom({ roomName: 'test-bulk-2' }) ]); // Join a participant to the rooms @@ -188,8 +188,8 @@ describe('Room API Tests', () => { it('should return mixed results (200) when some rooms are deleted and others marked for deletion', async () => { // Create rooms - const room1 = await createRoom({ roomIdPrefix: 'empty-room' }); - const room2 = await createRoom({ roomIdPrefix: 'occupied-room' }); + const room1 = await createRoom({ roomName: 'empty-room' }); + const room2 = await createRoom({ roomName: 'occupied-room' }); // Add participant to only one room await joinFakeParticipant(room2.roomId, 'test-participant'); @@ -214,7 +214,7 @@ describe('Room API Tests', () => { it('should handle a large number of room IDs', async () => { // Create 20+ rooms and test deletion const rooms = await Promise.all( - Array.from({ length: 20 }, (_, i) => createRoom({ roomIdPrefix: `bulk-${i}` })) + Array.from({ length: 20 }, (_, i) => createRoom({ roomName: `bulk-${i}` })) ); const response = await bulkDeleteRooms(rooms.map((r) => r.roomId)); @@ -230,7 +230,7 @@ describe('Room API Tests', () => { it('should handle a large number of room IDs with mixed valid and invalid IDs', async () => { // Create 20+ rooms and test deletion const rooms = await Promise.all( - Array.from({ length: 20 }, (_, i) => createRoom({ roomIdPrefix: `bulk-${i}` })) + Array.from({ length: 20 }, (_, i) => createRoom({ roomName: `bulk-${i}` })) ); await joinFakeParticipant(rooms[0].roomId, 'test-participant-1'); diff --git a/backend/tests/integration/api/rooms/create-room.test.ts b/backend/tests/integration/api/rooms/create-room.test.ts index b60a213..722c07d 100644 --- a/backend/tests/integration/api/rooms/create-room.test.ts +++ b/backend/tests/integration/api/rooms/create-room.test.ts @@ -27,23 +27,23 @@ describe('Room API Tests', () => { describe('Room Creation Tests', () => { it('Should create a room without autoDeletionDate (default behavior)', async () => { const room = await createRoom({ - roomIdPrefix: ' Test Room ' + roomName: ' Test Room ' }); - expectValidRoom(room, 'TestRoom'); + expectValidRoom(room, 'Test Room'); }); it('Should create a room with a valid autoDeletionDate', async () => { const room = await createRoom({ autoDeletionDate: validAutoDeletionDate, - roomIdPrefix: ' .,-------}{¡$#<+My Room *123 ' + roomName: ' .,-------}{¡$#<+My Room *123 ' }); - expectValidRoom(room, 'MyRoom123', validAutoDeletionDate); + expectValidRoom(room, 'My Room 123', validAutoDeletionDate); }); it('Should create a room when sending full valid payload', async () => { const payload = { - roomIdPrefix: ' =Example Room&/ ', + roomName: ' =Example Room&/ ', autoDeletionDate: validAutoDeletionDate, preferences: { recordingPreferences: { @@ -57,7 +57,7 @@ describe('Room API Tests', () => { const room = await createRoom(payload); - expectValidRoom(room, 'ExampleRoom', validAutoDeletionDate, payload.preferences); + expectValidRoom(room, 'Example Room', validAutoDeletionDate, payload.preferences); }); }); @@ -65,7 +65,7 @@ describe('Room API Tests', () => { it('should fail when autoDeletionDate is negative', async () => { const payload = { autoDeletionDate: -5000, - roomIdPrefix: 'TestRoom' + roomName: 'TestRoom' }; const response = await request(app).post(ROOMS_PATH).set('Cookie', adminCookie).send(payload).expect(422); @@ -78,7 +78,7 @@ describe('Room API Tests', () => { it('should fail when autoDeletionDate is less than 1 hour in the future', async () => { const payload = { autoDeletionDate: Date.now() + ms('30m'), - roomIdPrefix: 'TestRoom' + roomName: 'TestRoom' }; const response = await request(app).post(ROOMS_PATH).set('Cookie', adminCookie).send(payload).expect(422); @@ -92,7 +92,7 @@ describe('Room API Tests', () => { it('should fail when autoDeletionDate is not a number (string provided)', async () => { const payload = { autoDeletionDate: 'not-a-number', - roomIdPrefix: 'TestRoom' + roomName: 'TestRoom' }; const response = await request(app).post(ROOMS_PATH).set('Cookie', adminCookie).send(payload).expect(422); @@ -103,7 +103,7 @@ describe('Room API Tests', () => { it('should fail when autoDeletionDate is a boolean', async () => { const payload = { autoDeletionDate: true, - roomIdPrefix: 'TestRoom' + roomName: 'TestRoom' }; const response = await request(app).post(ROOMS_PATH).set('Cookie', adminCookie).send(payload).expect(422); @@ -114,7 +114,7 @@ describe('Room API Tests', () => { it('should fail when autoDeletionDate is omitted but provided as null', async () => { const payload = { autoDeletionDate: null, - roomIdPrefix: 'TestRoom' + roomName: 'TestRoom' }; const response = await request(app).post(ROOMS_PATH).set('Cookie', adminCookie).send(payload).expect(422); @@ -122,9 +122,9 @@ describe('Room API Tests', () => { expect(JSON.stringify(response.body.details)).toContain('Expected number'); }); - it('should fail when roomIdPrefix is not a string (number provided)', async () => { + it('should fail when roomName is not a string (number provided)', async () => { const payload = { - roomIdPrefix: 12345, + roomName: 12345, autoDeletionDate: validAutoDeletionDate }; @@ -133,9 +133,9 @@ describe('Room API Tests', () => { expect(JSON.stringify(response.body.details)).toContain('Expected string'); }); - it('should fail when roomIdPrefix is a boolean', async () => { + it('should fail when roomName is a boolean', async () => { const payload = { - roomIdPrefix: false, + roomName: false, autoDeletionDate: validAutoDeletionDate }; @@ -146,7 +146,7 @@ describe('Room API Tests', () => { it('should fail when preferences is not an object (string provided)', async () => { const payload = { - roomIdPrefix: 'TestRoom', + roomName: 'TestRoom', autoDeletionDate: validAutoDeletionDate, preferences: 'invalid-preferences' }; @@ -160,7 +160,7 @@ describe('Room API Tests', () => { // Assuming preferences expects each sub-property to be an object with a boolean "enabled", // here we deliberately use an invalid structure. const payload = { - roomIdPrefix: 'TestRoom', + roomName: 'TestRoom', autoDeletionDate: validAutoDeletionDate, preferences: { recordingPreferences: { @@ -183,23 +183,23 @@ describe('Room API Tests', () => { .post(ROOMS_PATH) .set('Cookie', adminCookie) .set('Content-Type', 'application/json') - .send('{"roomIdPrefix": "TestRoom",') // invalid JSON syntax + .send('{"roomName": "TestRoom",') // invalid JSON syntax .expect(400); expect(response.body.error).toContain('Bad Request'); expect(response.body.message).toContain('Malformed body'); }); - it('should fail when roomIdPrefix is too long', async () => { + it('should fail when roomName is too long', async () => { const longRoomId = 'a'.repeat(51); const payload = { - roomIdPrefix: longRoomId, + roomName: longRoomId, autoDeletionDate: validAutoDeletionDate }; const response = await request(app).post(ROOMS_PATH).set('Cookie', adminCookie).send(payload).expect(422); - expect(JSON.stringify(response.body.details)).toContain('roomIdPrefix cannot exceed 50 characters'); + expect(JSON.stringify(response.body.details)).toContain('roomName cannot exceed 50 characters'); }); }); }); diff --git a/backend/tests/integration/api/rooms/delete-room.test.ts b/backend/tests/integration/api/rooms/delete-room.test.ts index 6e7955f..a981d11 100644 --- a/backend/tests/integration/api/rooms/delete-room.test.ts +++ b/backend/tests/integration/api/rooms/delete-room.test.ts @@ -36,7 +36,7 @@ describe('Room API Tests', () => { it('should default to force=false when force parameter is invalid', async () => { // Create a room first const { roomId } = await createRoom({ - roomIdPrefix: 'test-room' + roomName: 'test-room' }); const response = await deleteRoom(roomId, { force: 'not-a-boolean' }); @@ -49,7 +49,7 @@ describe('Room API Tests', () => { it('should mark room for deletion when participants exist and force parameter is invalid', async () => { // Create a room first const { roomId } = await createRoom({ - roomIdPrefix: 'test-room' + roomName: 'test-room' }); await joinFakeParticipant(roomId, 'test-participant'); @@ -70,7 +70,7 @@ describe('Room API Tests', () => { }); it('should delete an empty room completely (204)', async () => { - const { roomId } = await createRoom({ roomIdPrefix: 'test-room' }); + const { roomId } = await createRoom({ roomName: 'test-room' }); const response = await deleteRoom(roomId); @@ -84,7 +84,7 @@ describe('Room API Tests', () => { it('should sanitize roomId with spaces and special characters before deletion', async () => { // Create a room first const createdRoom = await createRoom({ - roomIdPrefix: 'test-mixed' + roomName: 'test-mixed' }); // Add some spaces and special chars to the valid roomId @@ -101,7 +101,7 @@ describe('Room API Tests', () => { it('should handle explicit force=true for room with no participants', async () => { const createdRoom = await createRoom({ - roomIdPrefix: 'test-room' + roomName: 'test-room' }); const response = await deleteRoom(createdRoom.roomId, { force: true }); @@ -116,7 +116,7 @@ describe('Room API Tests', () => { it('should mark room for deletion (202) when participants exist and force=false', async () => { const autoDeletionDate = Date.now() + ms('5h'); const { roomId } = await createRoom({ - roomIdPrefix: 'test-room', + roomName: 'test-room', autoDeletionDate }); @@ -133,7 +133,7 @@ describe('Room API Tests', () => { it('should delete a room marked for deletion when the webhook room_finished is received', async () => { const autoDeletionDate = Date.now() + ms('5h'); const { roomId } = await createRoom({ - roomIdPrefix: 'test-room', + roomName: 'test-room', autoDeletionDate }); @@ -166,7 +166,7 @@ describe('Room API Tests', () => { it('should force delete (204) room with active participants when force=true', async () => { const { roomId } = await createRoom({ - roomIdPrefix: 'test-room' + roomName: 'test-room' }); await joinFakeParticipant(roomId, 'test-participant'); @@ -182,7 +182,7 @@ describe('Room API Tests', () => { }); it('should successfully delete a room already marked for deletion', async () => { - const { roomId } = await createRoom({ roomIdPrefix: 'test-marked' }); + const { roomId } = await createRoom({ roomName: 'test-marked' }); // First mark it for deletion await joinFakeParticipant(roomId, 'test-participant'); @@ -195,7 +195,7 @@ describe('Room API Tests', () => { }); it('should handle repeated deletion of the same room gracefully', async () => { - const { roomId } = await createRoom({ roomIdPrefix: 'test-idempotent' }); + const { roomId } = await createRoom({ roomName: 'test-idempotent' }); // Delete first time const response1 = await deleteRoom(roomId); diff --git a/backend/tests/integration/api/rooms/garbage-collector.test.ts b/backend/tests/integration/api/rooms/garbage-collector.test.ts index d670746..2ea981c 100644 --- a/backend/tests/integration/api/rooms/garbage-collector.test.ts +++ b/backend/tests/integration/api/rooms/garbage-collector.test.ts @@ -31,7 +31,7 @@ describe('Room Garbage Collector Tests', () => { it('should delete a room with a past auto-deletion date if no participant is present', async () => { const createdRoom = await createRoom({ - roomIdPrefix: 'test-gc', + roomName: 'test-gc', autoDeletionDate: Date.now() + ms('1s') }); @@ -50,7 +50,7 @@ describe('Room Garbage Collector Tests', () => { it('should mark room for deletion but not delete when expiration date has passed and participants exist', async () => { const createdRoom = await createRoom({ - roomIdPrefix: 'test-gc-participants', + roomName: 'test-gc-participants', autoDeletionDate: Date.now() + ms('1s') }); @@ -66,7 +66,7 @@ describe('Room Garbage Collector Tests', () => { it('should not touch a room with a future auto-deletion date', async () => { const createdRoom = await createRoom({ - roomIdPrefix: 'test-gc-future', + roomName: 'test-gc-future', autoDeletionDate: Date.now() + ms('1h') }); @@ -79,7 +79,7 @@ describe('Room Garbage Collector Tests', () => { it('should delete a room after the last participant leaves when it was marked for deletion', async () => { const { roomId } = await createRoom({ - roomIdPrefix: 'test-gc-lifecycle', + roomName: 'test-gc-lifecycle', autoDeletionDate: Date.now() + ms('1s') }); @@ -118,7 +118,7 @@ describe('Room Garbage Collector Tests', () => { it('should never delete a room without an auto-deletion date', async () => { const createdRoom = await createRoom({ - roomIdPrefix: 'test-gc-no-date' + roomName: 'test-gc-no-date' }); await runRoomGarbageCollector(); @@ -135,16 +135,16 @@ describe('Room Garbage Collector Tests', () => { it('should handle multiple expired rooms in one batch', async () => { const rooms = await Promise.all([ - createRoom({ roomIdPrefix: 'test-gc-multi-1', autoDeletionDate: Date.now() + ms('1s') }), - createRoom({ roomIdPrefix: 'test-gc-multi-2', autoDeletionDate: Date.now() + ms('1s') }), - createRoom({ roomIdPrefix: 'test-gc-multi-3', autoDeletionDate: Date.now() + ms('1s') }), - createRoom({ roomIdPrefix: 'test-gc-multi-4', autoDeletionDate: Date.now() + ms('1h') }), - createRoom({ roomIdPrefix: 'test-gc-multi-5', autoDeletionDate: Date.now() + ms('1h') }), - createRoom({ roomIdPrefix: 'test-gc-multi-6', autoDeletionDate: Date.now() + ms('1s') }), - createRoom({ roomIdPrefix: 'test-gc-multi-7', autoDeletionDate: Date.now() + ms('1s') }), - createRoom({ roomIdPrefix: 'test-gc-multi-8', autoDeletionDate: Date.now() + ms('1s') }), - createRoom({ roomIdPrefix: 'test-gc-multi-9', autoDeletionDate: Date.now() + ms('1s') }), - createRoom({ roomIdPrefix: 'test-gc-multi-10', autoDeletionDate: Date.now() + ms('1s') }) + createRoom({ roomName: 'test-gc-multi-1', autoDeletionDate: Date.now() + ms('1s') }), + createRoom({ roomName: 'test-gc-multi-2', autoDeletionDate: Date.now() + ms('1s') }), + createRoom({ roomName: 'test-gc-multi-3', autoDeletionDate: Date.now() + ms('1s') }), + createRoom({ roomName: 'test-gc-multi-4', autoDeletionDate: Date.now() + ms('1h') }), + createRoom({ roomName: 'test-gc-multi-5', autoDeletionDate: Date.now() + ms('1h') }), + createRoom({ roomName: 'test-gc-multi-6', autoDeletionDate: Date.now() + ms('1s') }), + createRoom({ roomName: 'test-gc-multi-7', autoDeletionDate: Date.now() + ms('1s') }), + createRoom({ roomName: 'test-gc-multi-8', autoDeletionDate: Date.now() + ms('1s') }), + createRoom({ roomName: 'test-gc-multi-9', autoDeletionDate: Date.now() + ms('1s') }), + createRoom({ roomName: 'test-gc-multi-10', autoDeletionDate: Date.now() + ms('1s') }) ]); // Make sure all rooms are expired diff --git a/backend/tests/integration/api/rooms/get-room-preferences.test.ts b/backend/tests/integration/api/rooms/get-room-preferences.test.ts index ace1795..2c28c69 100644 --- a/backend/tests/integration/api/rooms/get-room-preferences.test.ts +++ b/backend/tests/integration/api/rooms/get-room-preferences.test.ts @@ -35,7 +35,7 @@ describe('Room API Tests', () => { it('should retrieve custom room preferences', async () => { const payload = { - roomIdPrefix: 'custom-prefs', + roomName: 'custom-prefs', preferences: { recordingPreferences: { enabled: true, @@ -46,7 +46,7 @@ describe('Room API Tests', () => { } }; - const roomData = await setupSingleRoom(false, payload.roomIdPrefix, payload.preferences); + const roomData = await setupSingleRoom(false, payload.roomName, payload.preferences); const roomId = roomData.room.roomId; const cookie = roomData.moderatorCookie; diff --git a/backend/tests/integration/api/rooms/get-room.test.ts b/backend/tests/integration/api/rooms/get-room.test.ts index 5da4865..cc6ea63 100644 --- a/backend/tests/integration/api/rooms/get-room.test.ts +++ b/backend/tests/integration/api/rooms/get-room.test.ts @@ -22,7 +22,7 @@ describe('Room API Tests', () => { describe('Get Room Tests', () => { it('should successfully retrieve a room by its ID', async () => { const createdRoom = await createRoom({ - roomIdPrefix: 'test-room' + roomName: 'test-room' }); expectValidRoom(createdRoom, 'test-room'); @@ -33,7 +33,7 @@ describe('Room API Tests', () => { it('should retrieve a room with custom preferences', async () => { const payload = { - roomIdPrefix: 'custom-prefs', + roomName: 'custom-prefs', preferences: { recordingPreferences: { enabled: true, @@ -55,22 +55,22 @@ describe('Room API Tests', () => { it('should retrieve only specified fields when using fields parameter', async () => { // Create a room const createdRoom = await createRoom({ - roomIdPrefix: 'field-filtered' + roomName: 'field-filtered' }); // Get the room with field filtering - const response = await getRoom(createdRoom.roomId, 'roomId,roomIdPrefix'); + const response = await getRoom(createdRoom.roomId, 'roomId,roomName'); // Verify that only the requested fields are returned expect(response.status).toBe(200); - expectValidRoomWithFields(response.body, ['roomId', 'roomIdPrefix']); + expectValidRoomWithFields(response.body, ['roomId', 'roomName']); }); it('should handle roomId with characters that need sanitization', async () => { // Create a room const createdRoom = await createRoom({ - roomIdPrefix: 'test-room' + roomName: 'test-room' }); const dirtyRoomId = ' ' + createdRoom.roomId + ' '; // Add spaces that should be trimmed @@ -86,7 +86,7 @@ describe('Room API Tests', () => { // Create a room with autoDeletionDate const createdRoom = await createRoom({ - roomIdPrefix: 'deletion-date', + roomName: 'deletion-date', autoDeletionDate: validAutoDeletionDate }); diff --git a/backend/tests/integration/api/rooms/get-rooms.test.ts b/backend/tests/integration/api/rooms/get-rooms.test.ts index 142a69f..e7415ed 100644 --- a/backend/tests/integration/api/rooms/get-rooms.test.ts +++ b/backend/tests/integration/api/rooms/get-rooms.test.ts @@ -30,7 +30,7 @@ describe('Room API Tests', () => { it('should return a list of rooms', async () => { await createRoom({ - roomIdPrefix: 'test-room' + roomName: 'test-room' }); const response = await getRooms(); @@ -41,7 +41,7 @@ describe('Room API Tests', () => { it('should return a list of rooms applying fields filter', async () => { await createRoom({ - roomIdPrefix: 'test-room', + roomName: 'test-room', autoDeletionDate: validAutoDeletionDate }); @@ -56,7 +56,7 @@ describe('Room API Tests', () => { it('should return a list of rooms with pagination', async () => { const promises = [0, 1, 2, 3, 4, 5].map((i) => { return createRoom({ - roomIdPrefix: `test-room-${i}`, + roomName: `test-room-${i}`, autoDeletionDate: validAutoDeletionDate }); }); diff --git a/backend/tests/integration/api/rooms/update-room.test.ts b/backend/tests/integration/api/rooms/update-room.test.ts index 04eba72..f30b166 100644 --- a/backend/tests/integration/api/rooms/update-room.test.ts +++ b/backend/tests/integration/api/rooms/update-room.test.ts @@ -32,7 +32,7 @@ describe('Room API Tests', () => { it('should successfully update room preferences', async () => { const sendSignalSpy = jest.spyOn(frontendEventService as any, 'sendSignal'); const createdRoom = await createRoom({ - roomIdPrefix: 'update-test', + roomName: 'update-test', preferences: { recordingPreferences: { enabled: true, @@ -81,7 +81,7 @@ describe('Room API Tests', () => { it('should allow partial preference updates', async () => { // Create a room first with all preferences enabled const createdRoom = await createRoom({ - roomIdPrefix: 'partial-update', + roomName: 'partial-update', preferences: { recordingPreferences: { enabled: true, @@ -118,7 +118,7 @@ describe('Room API Tests', () => { describe('Update Room Validation failures', () => { it('should fail when preferences have incorrect structure', async () => { const { roomId } = await createRoom({ - roomIdPrefix: 'validation-test' + roomName: 'validation-test' }); // Invalid preferences (missing required fields) @@ -139,7 +139,7 @@ describe('Room API Tests', () => { it('should fail when preferences have incorrect types', async () => { const createdRoom = await createRoom({ - roomIdPrefix: 'type-test' + roomName: 'type-test' }); // Invalid preferences (wrong types) @@ -161,7 +161,7 @@ describe('Room API Tests', () => { it('should fail when preferences are missing required properties', async () => { const createdRoom = await createRoom({ - roomIdPrefix: 'missing-props' + roomName: 'missing-props' }); const emptyPreferences = {}; @@ -174,7 +174,7 @@ describe('Room API Tests', () => { it('should fail when recording is enabled but allowAccessTo is missing', async () => { const createdRoom = await createRoom({ - roomIdPrefix: 'missing-access' + roomName: 'missing-access' }); const invalidPreferences = { recordingPreferences: {