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

370 lines
13 KiB
TypeScript

import { afterAll, beforeAll, beforeEach, describe, expect, it } from '@jest/globals';
import {
MeetingEndAction,
MeetRoomDeletionErrorCode,
MeetRoomDeletionPolicyWithMeeting,
MeetRoomDeletionPolicyWithRecordings,
MeetRoomDeletionSuccessCode,
MeetRoomStatus
} from '../../../../src/typings/ce/room.js';
import { expectSuccessListRecordingResponse, expectValidRoom } from '../../../helpers/assertion-helpers.js';
import {
createRoom,
deleteAllRecordings,
deleteAllRooms,
deleteRoom,
disconnectFakeParticipants,
endMeeting,
getAllRecordings,
getRoom,
startTestServer
} from '../../../helpers/request-helpers.js';
import { setupSingleRoom, setupSingleRoomWithRecording } from '../../../helpers/test-scenarios.js';
describe('Room API Tests', () => {
beforeAll(() => {
startTestServer();
});
afterAll(async () => {
// Remove all rooms created
await disconnectFakeParticipants();
await deleteAllRooms();
await deleteAllRecordings();
});
describe('Delete Room Tests', () => {
describe('without active meeting or recordings', () => {
it('should return 200 with successCode=room_deleted', async () => {
const { roomId } = await createRoom();
const response = await deleteRoom(roomId);
expect(response.status).toBe(200);
expect(response.body).toHaveProperty('successCode', MeetRoomDeletionSuccessCode.ROOM_DELETED);
// Check room is deleted
const getResponse = await getRoom(roomId);
expect(getResponse.status).toBe(404);
});
});
describe('with active meeting but no recordings', () => {
let roomId: string;
let roomName: string;
let moderatorCookie: string;
beforeEach(async () => {
// Create a room with an active meeting
const { room, moderatorCookie: cookie } = await setupSingleRoom(true);
roomId = room.roomId;
roomName = room.roomName;
moderatorCookie = cookie;
});
it('should return 200 with successCode=room_with_active_meeting_deleted when withMeeting=force', async () => {
const response = await deleteRoom(roomId, {
withMeeting: MeetRoomDeletionPolicyWithMeeting.FORCE
});
expect(response.status).toBe(200);
expect(response.body).toHaveProperty(
'successCode',
MeetRoomDeletionSuccessCode.ROOM_WITH_ACTIVE_MEETING_DELETED
);
// Check room is deleted
const getResponse = await getRoom(roomId);
expect(getResponse.status).toBe(404);
});
it('should return 202 with successCode=room_with_active_meeting_scheduled_to_be_deleted when withMeeting=when_meeting_ends', async () => {
const response = await deleteRoom(roomId, {
withMeeting: MeetRoomDeletionPolicyWithMeeting.WHEN_MEETING_ENDS
});
expect(response.status).toBe(202);
expect(response.body).toHaveProperty(
'successCode',
MeetRoomDeletionSuccessCode.ROOM_WITH_ACTIVE_MEETING_SCHEDULED_TO_BE_DELETED
);
expectValidRoom(
response.body.room,
roomName,
undefined,
undefined,
undefined,
MeetRoomStatus.ACTIVE_MEETING,
MeetingEndAction.DELETE
);
// End meeting and check the room is deleted
await endMeeting(roomId, moderatorCookie);
const getResponse = await getRoom(roomId);
expect(getResponse.status).toBe(404);
});
it('should return 409 with error=room_has_active_meeting when withMeeting=fail', async () => {
const response = await deleteRoom(roomId, { withMeeting: MeetRoomDeletionPolicyWithMeeting.FAIL });
expect(response.status).toBe(409);
expect(response.body).toHaveProperty('error', MeetRoomDeletionErrorCode.ROOM_HAS_ACTIVE_MEETING);
});
});
describe('with recordings but no active meeting', () => {
let roomId: string;
let roomName: string;
beforeEach(async () => {
// Create a room with recordings and end the meeting
const { room, moderatorCookie } = await setupSingleRoomWithRecording(true);
roomId = room.roomId;
roomName = room.roomName;
await endMeeting(roomId, moderatorCookie);
});
it('should return 200 with successCode=room_and_recordings_deleted when withRecording=force', async () => {
const response = await deleteRoom(roomId, {
withRecordings: MeetRoomDeletionPolicyWithRecordings.FORCE
});
expect(response.status).toBe(200);
expect(response.body).toHaveProperty(
'successCode',
MeetRoomDeletionSuccessCode.ROOM_AND_RECORDINGS_DELETED
);
// Check the room and recordings are deleted
const roomResponse = await getRoom(roomId);
expect(roomResponse.status).toBe(404);
const recordingsResponse = await getAllRecordings({ roomId, maxItems: 1 });
expectSuccessListRecordingResponse(recordingsResponse, 0, false, false, 1);
});
it('should return 200 with successCode=room_closed when withRecording=close', async () => {
const response = await deleteRoom(roomId, {
withRecordings: MeetRoomDeletionPolicyWithRecordings.CLOSE
});
expect(response.status).toBe(200);
expect(response.body).toHaveProperty('successCode', MeetRoomDeletionSuccessCode.ROOM_CLOSED);
// Check that the room is closed and recordings are not deleted
expectValidRoom(
response.body.room,
roomName,
undefined,
undefined,
undefined,
MeetRoomStatus.CLOSED,
MeetingEndAction.NONE
);
const recordingsResponse = await getAllRecordings({ roomId, maxItems: 1 });
expectSuccessListRecordingResponse(recordingsResponse, 1, false, false, 1);
});
it('should return 409 with error=room_has_recordings when withRecording=fail', async () => {
const response = await deleteRoom(roomId, {
withRecordings: MeetRoomDeletionPolicyWithRecordings.FAIL
});
expect(response.status).toBe(409);
expect(response.body).toHaveProperty('error', MeetRoomDeletionErrorCode.ROOM_HAS_RECORDINGS);
});
});
describe('with active meeting and recordings', () => {
let roomId: string;
let roomName: string;
let moderatorCookie: string;
beforeEach(async () => {
// Create a room with recordings, keep the meeting active
const { room, moderatorCookie: cookie } = await setupSingleRoomWithRecording(true);
roomId = room.roomId;
roomName = room.roomName;
moderatorCookie = cookie;
});
it('should return 200 with successCode=room_with_active_meeting_and_recordings_deleted when withMeeting=force and withRecording=force', async () => {
const response = await deleteRoom(roomId, {
withMeeting: MeetRoomDeletionPolicyWithMeeting.FORCE,
withRecordings: MeetRoomDeletionPolicyWithRecordings.FORCE
});
expect(response.status).toBe(200);
expect(response.body).toHaveProperty(
'successCode',
MeetRoomDeletionSuccessCode.ROOM_WITH_ACTIVE_MEETING_AND_RECORDINGS_DELETED
);
// Check the room and recordings are deleted
const roomResponse = await getRoom(roomId);
expect(roomResponse.status).toBe(404);
const recordingsResponse = await getAllRecordings({ roomId, maxItems: 1 });
expectSuccessListRecordingResponse(recordingsResponse, 0, false, false, 1);
});
it('should return 200 with successCode=room_with_active_meeting_closed when withMeeting=force and withRecording=close', async () => {
const response = await deleteRoom(roomId, {
withMeeting: MeetRoomDeletionPolicyWithMeeting.FORCE,
withRecordings: MeetRoomDeletionPolicyWithRecordings.CLOSE
});
expect(response.status).toBe(200);
expect(response.body).toHaveProperty(
'successCode',
MeetRoomDeletionSuccessCode.ROOM_WITH_ACTIVE_MEETING_CLOSED
);
expectValidRoom(
response.body.room,
roomName,
undefined,
undefined,
undefined,
MeetRoomStatus.ACTIVE_MEETING,
MeetingEndAction.CLOSE
);
// Check that the room is closed and recordings are not deleted
const roomResponse = await getRoom(roomId);
expect(roomResponse.status).toBe(200);
expectValidRoom(
roomResponse.body,
roomName,
undefined,
undefined,
undefined,
MeetRoomStatus.CLOSED,
MeetingEndAction.NONE
);
const recordingsResponse = await getAllRecordings({ roomId, maxItems: 1 });
expectSuccessListRecordingResponse(recordingsResponse, 1, false, false, 1);
});
it('should return 409 with error=room_with_active_meeting_has_recordings when withMeeting=force and withRecording=fail', async () => {
const response = await deleteRoom(roomId, {
withMeeting: MeetRoomDeletionPolicyWithMeeting.FORCE,
withRecordings: MeetRoomDeletionPolicyWithRecordings.FAIL
});
expect(response.status).toBe(409);
expect(response.body).toHaveProperty(
'error',
MeetRoomDeletionErrorCode.ROOM_WITH_ACTIVE_MEETING_HAS_RECORDINGS
);
});
it('should return 202 with successCode=room_with_active_meeting_and_recordings_scheduled_to_be_deleted when withMeeting=when_meeting_ends and withRecording=force', async () => {
const response = await deleteRoom(roomId, {
withMeeting: MeetRoomDeletionPolicyWithMeeting.WHEN_MEETING_ENDS,
withRecordings: MeetRoomDeletionPolicyWithRecordings.FORCE
});
expect(response.status).toBe(202);
expect(response.body).toHaveProperty(
'successCode',
MeetRoomDeletionSuccessCode.ROOM_WITH_ACTIVE_MEETING_AND_RECORDINGS_SCHEDULED_TO_BE_DELETED
);
expectValidRoom(
response.body.room,
roomName,
undefined,
undefined,
undefined,
MeetRoomStatus.ACTIVE_MEETING,
MeetingEndAction.DELETE
);
// End meeting and check the room and recordings are deleted
await endMeeting(roomId, moderatorCookie);
const roomResponse = await getRoom(roomId);
expect(roomResponse.status).toBe(404);
const recordingsResponse = await getAllRecordings({ roomId, maxItems: 1 });
expectSuccessListRecordingResponse(recordingsResponse, 0, false, false, 1);
});
it('should return 202 with successCode=room_with_active_meeting_scheduled_to_be_closed when withMeeting=when_meeting_ends and withRecording=close', async () => {
const response = await deleteRoom(roomId, {
withMeeting: MeetRoomDeletionPolicyWithMeeting.WHEN_MEETING_ENDS,
withRecordings: MeetRoomDeletionPolicyWithRecordings.CLOSE
});
expect(response.status).toBe(202);
expect(response.body).toHaveProperty(
'successCode',
MeetRoomDeletionSuccessCode.ROOM_WITH_ACTIVE_MEETING_SCHEDULED_TO_BE_CLOSED
);
expectValidRoom(
response.body.room,
roomName,
undefined,
undefined,
undefined,
MeetRoomStatus.ACTIVE_MEETING,
MeetingEndAction.CLOSE
);
// End meeting and check that the room is closed and recordings are not deleted
await endMeeting(roomId, moderatorCookie);
const roomResponse = await getRoom(roomId);
expect(roomResponse.status).toBe(200);
expectValidRoom(
roomResponse.body,
roomName,
undefined,
undefined,
undefined,
MeetRoomStatus.CLOSED,
MeetingEndAction.NONE
);
const recordingsResponse = await getAllRecordings({ roomId, maxItems: 1 });
expectSuccessListRecordingResponse(recordingsResponse, 1, false, false, 1);
});
it('should return 409 with error=room_with_active_meeting_has_recordings_cannot_schedule_deletion when withMeeting=when_meeting_ends and withRecording=fail', async () => {
const response = await deleteRoom(roomId, {
withMeeting: MeetRoomDeletionPolicyWithMeeting.WHEN_MEETING_ENDS,
withRecordings: MeetRoomDeletionPolicyWithRecordings.FAIL
});
expect(response.status).toBe(409);
expect(response.body).toHaveProperty(
'error',
MeetRoomDeletionErrorCode.ROOM_WITH_ACTIVE_MEETING_HAS_RECORDINGS_CANNOT_SCHEDULE_DELETION
);
});
it('should return 409 with error=room_with_recordings_has_active_meeting when withMeeting=fail', async () => {
const response = await deleteRoom(roomId, {
withMeeting: MeetRoomDeletionPolicyWithMeeting.FAIL,
withRecordings: MeetRoomDeletionPolicyWithRecordings.FORCE
});
expect(response.status).toBe(409);
expect(response.body).toHaveProperty(
'error',
MeetRoomDeletionErrorCode.ROOM_WITH_RECORDINGS_HAS_ACTIVE_MEETING
);
});
});
});
describe('Delete Room Validation failures', () => {
it('should fail when roomId becomes empty after sanitization', async () => {
const response = await deleteRoom('!!-*!@#$%^&*()_+{}|:"<>?');
expect(response.status).toBe(422);
// Expect an error message indicating the resulting roomId is empty.
expect(response.body.error).toContain('Unprocessable Entity');
expect(JSON.stringify(response.body.details)).toContain('roomId cannot be empty after sanitization');
});
it('should fail when withMeeting parameter is invalid', async () => {
const response = await deleteRoom('testRoom', { withMeeting: '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 deleteRoom('testRoom', { withRecordings: 'invalid_value' });
expect(response.status).toBe(422);
expect(response.body.error).toContain('Unprocessable Entity');
expect(JSON.stringify(response.body.details)).toContain('Invalid enum value');
});
});
});