openvidu/backend/tests/integration/api/rooms/bulk-delete-rooms.test.ts

299 lines
9.4 KiB
TypeScript

import { afterAll, beforeAll, describe, expect, it } from '@jest/globals';
import {
MeetingEndAction,
MeetRoom,
MeetRoomDeletionErrorCode,
MeetRoomDeletionPolicyWithMeeting,
MeetRoomDeletionPolicyWithRecordings,
MeetRoomDeletionSuccessCode,
MeetRoomStatus
} from '../../../../src/typings/ce/room.js';
import { expectValidRoom } from '../../../helpers/assertion-helpers.js';
import {
bulkDeleteRooms,
createRoom,
deleteAllRecordings,
deleteAllRooms,
disconnectFakeParticipants,
endMeeting,
getRoom,
startTestServer
} from '../../../helpers/request-helpers.js';
import { setupSingleRoom, setupSingleRoomWithRecording } from '../../../helpers/test-scenarios.js';
describe('Room API Tests', () => {
beforeAll(() => {
startTestServer();
});
afterAll(async () => {
await disconnectFakeParticipants();
await deleteAllRooms();
await deleteAllRecordings();
});
describe('Bulk Delete Room Tests', () => {
it('should return 200 when all rooms are processed for deletion successfully', async () => {
const { roomId } = await createRoom();
const response = await bulkDeleteRooms([roomId]);
expect(response.status).toBe(200);
expect(response.body).toEqual({
message: 'All rooms successfully processed for deletion',
successful: expect.arrayContaining([
{
roomId,
successCode: MeetRoomDeletionSuccessCode.ROOM_DELETED,
message: expect.any(String)
}
])
});
});
it('should return 400 when some rooms fail to process for deletion', async () => {
const room1 = await createRoom();
const { room: room2 } = await setupSingleRoom(true);
const response = await bulkDeleteRooms([room1.roomId, room2.roomId]);
expect(response.status).toBe(400);
expect(response.body).toEqual({
message: '1 room(s) failed to process while deleting',
successful: expect.arrayContaining([
{
roomId: room1.roomId,
successCode: MeetRoomDeletionSuccessCode.ROOM_DELETED,
message: expect.any(String)
}
]),
failed: expect.arrayContaining([
{
roomId: room2.roomId,
error: MeetRoomDeletionErrorCode.ROOM_HAS_ACTIVE_MEETING,
message: expect.any(String)
}
])
});
});
it('should return 400 when all rooms fail to process for deletion', async () => {
const { room } = await setupSingleRoom(true);
const response = await bulkDeleteRooms([room.roomId]);
expect(response.status).toBe(400);
expect(response.body).toEqual({
message: '1 room(s) failed to process while deleting',
successful: [],
failed: expect.arrayContaining([
{
roomId: room.roomId,
error: MeetRoomDeletionErrorCode.ROOM_HAS_ACTIVE_MEETING,
message: expect.any(String)
}
])
});
});
it('should successfully delete the room requesting the same roomId multiple times', async () => {
const { roomId } = await createRoom();
const response = await bulkDeleteRooms([roomId, roomId, roomId]);
expect(response.status).toBe(200);
expect(response.body).toEqual({
message: 'All rooms successfully processed for deletion',
successful: expect.arrayContaining([
{
roomId,
successCode: MeetRoomDeletionSuccessCode.ROOM_DELETED,
message: expect.any(String)
}
])
});
});
it('should successfully delete valid roomIds while ignoring invalid ones', async () => {
const { roomId } = await createRoom();
const response = await bulkDeleteRooms([roomId, '!!@##$']);
expect(response.status).toBe(200);
expect(response.body).toEqual({
message: 'All rooms successfully processed for deletion',
successful: expect.arrayContaining([
{
roomId,
successCode: MeetRoomDeletionSuccessCode.ROOM_DELETED,
message: expect.any(String)
}
])
});
});
it('should handle a large number of room IDs', async () => {
// Create 20 rooms
const rooms = await Promise.all(
Array.from({ length: 20 }, (_, i) => createRoom({ roomName: `bulk-${i}` }))
);
const response = await bulkDeleteRooms(rooms.map((r) => r.roomId));
expect(response.status).toBe(200);
expect(response.body).toEqual({
message: 'All rooms successfully processed for deletion',
successful: expect.arrayContaining(
rooms.map((room) => ({
roomId: room.roomId,
successCode: MeetRoomDeletionSuccessCode.ROOM_DELETED,
message: expect.any(String)
}))
)
});
// Verify all rooms are deleted
for (const room of rooms) {
const getResponse = await getRoom(room.roomId);
expect(getResponse.status).toBe(404);
}
});
it('should handle deletion when specifying withMeeting and withRecordings parameters', async () => {
const [room1, { room: room2 }, { room: room3 }, { room: room4, moderatorCookie }] = await Promise.all([
createRoom(), // Room without active meeting or recordings
setupSingleRoom(true), // Room with active meeting
setupSingleRoomWithRecording(true), // Room with active meeting and recordings
setupSingleRoomWithRecording(true) // Room with recordings
]);
await endMeeting(room4.roomId, moderatorCookie);
const fakeRoomId = 'fakeRoomId'; // Non-existing room
const response = await bulkDeleteRooms(
[room1.roomId, room2.roomId, room3.roomId, room4.roomId, fakeRoomId],
MeetRoomDeletionPolicyWithMeeting.WHEN_MEETING_ENDS,
MeetRoomDeletionPolicyWithRecordings.CLOSE
);
expect(response.status).toBe(400);
expect(response.body).toEqual({
message: '1 room(s) failed to process while deleting',
successful: expect.arrayContaining([
{
roomId: room1.roomId,
successCode: MeetRoomDeletionSuccessCode.ROOM_DELETED,
message: expect.any(String)
},
{
roomId: room2.roomId,
successCode: MeetRoomDeletionSuccessCode.ROOM_WITH_ACTIVE_MEETING_SCHEDULED_TO_BE_DELETED,
message: expect.any(String),
room: expect.any(Object)
},
{
roomId: room3.roomId,
successCode: MeetRoomDeletionSuccessCode.ROOM_WITH_ACTIVE_MEETING_SCHEDULED_TO_BE_CLOSED,
message: expect.any(String),
room: expect.any(Object)
},
{
roomId: room4.roomId,
successCode: MeetRoomDeletionSuccessCode.ROOM_CLOSED,
message: expect.any(String),
room: expect.any(Object)
}
]),
failed: expect.arrayContaining([
{
roomId: fakeRoomId,
error: 'Room Error',
message: expect.stringContaining('does not exist')
}
])
});
// Check successful rooms properties
const successfulRoom2 = response.body.successful.find(
(s: { roomId: string; successCode: MeetRoomDeletionSuccessCode; message: string; room?: MeetRoom }) =>
s.room?.roomId === room2.roomId
);
expectValidRoom(
successfulRoom2.room,
successfulRoom2.room.roomName,
undefined,
undefined,
undefined,
MeetRoomStatus.ACTIVE_MEETING,
MeetingEndAction.DELETE
);
const successfulRoom3 = response.body.successful.find(
(r: { roomId: string; successCode: MeetRoomDeletionSuccessCode; message: string; room?: MeetRoom }) =>
r.room?.roomId === room3.roomId
);
expectValidRoom(
successfulRoom3.room,
successfulRoom3.room.roomName,
undefined,
undefined,
undefined,
MeetRoomStatus.ACTIVE_MEETING,
MeetingEndAction.CLOSE
);
const successfulRoom4 = response.body.successful.find(
(r: { roomId: string; successCode: MeetRoomDeletionSuccessCode; message: string; room?: MeetRoom }) =>
r.room?.roomId === room4.roomId
);
expectValidRoom(
successfulRoom4.room,
successfulRoom4.room.roomName,
undefined,
undefined,
undefined,
MeetRoomStatus.CLOSED,
MeetingEndAction.NONE
);
});
});
describe('Bulk delete Room Validation failures', () => {
it('should handle empty roomIds array (no rooms deleted)', async () => {
const response = await bulkDeleteRooms([]);
expect(response.status).toBe(422);
expect(response.body.error).toContain('Unprocessable Entity');
expect(JSON.stringify(response.body.details)).toContain(
'At least one valid roomId is required after sanitization'
);
});
it('should fail when roomIds contains an ID that becomes empty after sanitization', async () => {
const response = await bulkDeleteRooms([',,,,']);
expect(response.status).toBe(422);
expect(response.body.error).toContain('Unprocessable Entity');
expect(JSON.stringify(response.body.details)).toContain(
'At least one valid roomId is required after sanitization'
);
});
it('should validate roomIds and return 422 when all are invalid', async () => {
const response = await bulkDeleteRooms(['!!@##$', '!!@##$', ',', '.,-------}{¡$#<+']);
expect(response.status).toBe(422);
expect(response.body.error).toContain('Unprocessable Entity');
expect(JSON.stringify(response.body.details)).toContain(
'At least one valid roomId is required after sanitization'
);
});
it('should fail when withMeeting parameter is invalid', async () => {
const response = await bulkDeleteRooms(['testRoom'], 'invalid_value');
expect(response.status).toBe(422);
expect(response.body.error).toContain('Unprocessable Entity');
expect(JSON.stringify(response.body.details)).toContain('Invalid enum value');
});
it('should fail when withRecordings parameter is invalid', async () => {
const response = await bulkDeleteRooms(['testRoom'], 'force', 'invalid_value');
expect(response.status).toBe(422);
expect(response.body.error).toContain('Unprocessable Entity');
expect(JSON.stringify(response.body.details)).toContain('Invalid enum value');
});
});
});