166 lines
4.8 KiB
JavaScript
166 lines
4.8 KiB
JavaScript
import assert from 'assert';
|
|
|
|
import { createTestContext } from './helpers/test_context.js';
|
|
import { getRoomState, setBreakoutRoomsActive } from './helpers/test_observer.js';
|
|
|
|
const CONFERENCE = 'conference.localhost';
|
|
|
|
let _roomCounter = 0;
|
|
const room = () => `cleanup-svc-${++_roomCounter}@${CONFERENCE}`;
|
|
|
|
/** Resolves after ms milliseconds. */
|
|
const sleep = ms => new Promise(r => setTimeout(r, ms));
|
|
|
|
// services_empty_meeting_timeout is set to 1 s in prosody.cfg.lua.
|
|
// We wait TIMER_MS + BUFFER_MS to be sure the timer has either fired or not.
|
|
const TIMER_MS = 1000;
|
|
const BUFFER_MS = 1000;
|
|
|
|
describe('mod_muc_cleanup_backend_services', () => {
|
|
let ctx;
|
|
|
|
beforeEach(() => {
|
|
ctx = createTestContext();
|
|
});
|
|
|
|
afterEach(() => ctx.cleanup());
|
|
|
|
it('destroys room when last regular user leaves and only jibri remains', async () => {
|
|
const r = room();
|
|
|
|
await ctx.connectFocus(r);
|
|
await ctx.connectJibri(r);
|
|
const user = await ctx.connect();
|
|
|
|
await user.joinRoom(r);
|
|
await user.disconnect();
|
|
|
|
await sleep(TIMER_MS + BUFFER_MS);
|
|
|
|
const state = await getRoomState(r);
|
|
|
|
assert.equal(state, null, 'room should be destroyed after timeout');
|
|
});
|
|
|
|
it('destroys room when last regular user leaves and only transcriber remains', async () => {
|
|
const r = room();
|
|
|
|
await ctx.connectFocus(r);
|
|
await ctx.connectTranscriber(r);
|
|
const user = await ctx.connect();
|
|
|
|
await user.joinRoom(r);
|
|
await user.disconnect();
|
|
|
|
await sleep(TIMER_MS + BUFFER_MS);
|
|
|
|
const state = await getRoomState(r);
|
|
|
|
assert.equal(state, null, 'room should be destroyed after timeout');
|
|
});
|
|
|
|
it('does not destroy room when a second regular user is still present', async () => {
|
|
const r = room();
|
|
|
|
await ctx.connectFocus(r);
|
|
await ctx.connectJibri(r);
|
|
const user1 = await ctx.connect();
|
|
const user2 = await ctx.connect();
|
|
|
|
await user1.joinRoom(r);
|
|
await user2.joinRoom(r);
|
|
await user1.disconnect();
|
|
|
|
await sleep(TIMER_MS + BUFFER_MS);
|
|
|
|
const state = await getRoomState(r);
|
|
|
|
assert.ok(state, 'room should still exist — user2 is still a regular participant');
|
|
});
|
|
|
|
it('cancels the destroy timer when a regular user joins after timer starts', async () => {
|
|
const r = room();
|
|
|
|
await ctx.connectFocus(r);
|
|
await ctx.connectJibri(r);
|
|
const user = await ctx.connect();
|
|
|
|
await user.joinRoom(r);
|
|
|
|
// user leaves — timer starts counting down
|
|
await user.disconnect();
|
|
|
|
// a new regular user joins immediately, which must cancel the timer
|
|
const user2 = await ctx.connect();
|
|
|
|
await user2.joinRoom(r);
|
|
|
|
await sleep(TIMER_MS + BUFFER_MS);
|
|
|
|
const state = await getRoomState(r);
|
|
|
|
assert.ok(state, 'room should survive — destroy timer was cancelled by user2 joining');
|
|
});
|
|
|
|
it('does not start timer when jibri leaves and a regular user is still present', async () => {
|
|
const r = room();
|
|
|
|
await ctx.connectFocus(r);
|
|
const jibri = await ctx.connectJibri(r);
|
|
const user = await ctx.connect();
|
|
|
|
await user.joinRoom(r);
|
|
|
|
// jibri leaves — muc-occupant-left hook returns early (leaver is jibri)
|
|
await jibri.disconnect();
|
|
|
|
await sleep(TIMER_MS + BUFFER_MS);
|
|
|
|
const state = await getRoomState(r);
|
|
|
|
assert.ok(state, 'room should survive — timer is not started when jibri is the leaver');
|
|
});
|
|
|
|
it('does not start timer when focus (admin) leaves', async () => {
|
|
const r = room();
|
|
|
|
const focus = await ctx.connectFocus(r);
|
|
|
|
await ctx.connectJibri(r);
|
|
const user = await ctx.connect();
|
|
|
|
await user.joinRoom(r);
|
|
|
|
// admin leaves — muc-occupant-left hook returns early (leaver is admin)
|
|
await focus.disconnect();
|
|
|
|
await sleep(TIMER_MS + BUFFER_MS);
|
|
|
|
const state = await getRoomState(r);
|
|
|
|
assert.ok(state, 'room should survive — timer is not started when an admin leaves');
|
|
});
|
|
|
|
it('does not start timer when breakout rooms are active', async () => {
|
|
const r = room();
|
|
|
|
await ctx.connectFocus(r);
|
|
await ctx.connectJibri(r);
|
|
const user = await ctx.connect();
|
|
|
|
await user.joinRoom(r);
|
|
|
|
// Simulate active breakout rooms — hook returns early when this flag is set.
|
|
await setBreakoutRoomsActive(r, true);
|
|
|
|
// user leaves — would normally start the timer, but breakout_rooms_active prevents it
|
|
await user.disconnect();
|
|
|
|
await sleep(TIMER_MS + BUFFER_MS);
|
|
|
|
const state = await getRoomState(r);
|
|
|
|
assert.ok(state, 'room should survive — breakout_rooms_active prevents the destroy timer');
|
|
});
|
|
});
|