138 lines
4.5 KiB
JavaScript
138 lines
4.5 KiB
JavaScript
import assert from 'assert';
|
|
|
|
import { createTestContext } from './helpers/test_context.js';
|
|
import { isAvailablePresence } from './helpers/xmpp_utils.js';
|
|
|
|
// mod_muc_domain_mapper rewrites JIDs between:
|
|
// external: room@conference.subdomain.localhost (what clients send/receive)
|
|
// internal: [subdomain]room@conference.localhost (what Prosody routes)
|
|
//
|
|
// Both focus and regular clients use the external subdomain JID. The mapper
|
|
// rewrites 'to' on the way in (before routing) and 'from' on the way out
|
|
// (before the client sees it), so the subdomain format is transparent.
|
|
|
|
const CONFERENCE_SUB = 'conference.subdomain.localhost';
|
|
const CONFERENCE = 'conference.localhost';
|
|
|
|
let _roomCounter = 0;
|
|
const subRoom = () => `mapper-${++_roomCounter}@${CONFERENCE_SUB}`;
|
|
const baseRoom = () => `mapper-base-${++_roomCounter}@${CONFERENCE}`;
|
|
|
|
describe('mod_muc_domain_mapper', () => {
|
|
|
|
let ctx;
|
|
|
|
beforeEach(() => {
|
|
ctx = createTestContext();
|
|
});
|
|
|
|
afterEach(() => ctx.cleanup());
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Subdomain room join
|
|
// -------------------------------------------------------------------------
|
|
describe('subdomain room join', () => {
|
|
|
|
it('focus can join a subdomain room', async () => {
|
|
// connectFocus throws on timeout if the join fails.
|
|
await ctx.connectFocus(subRoom());
|
|
});
|
|
|
|
it('regular user receives available self-presence with subdomain from-JID', async () => {
|
|
const r = subRoom();
|
|
|
|
await ctx.connectFocus(r);
|
|
const c = await ctx.connect();
|
|
const presence = await c.joinRoom(r);
|
|
|
|
assert.ok(isAvailablePresence(presence),
|
|
'join must succeed');
|
|
assert.ok(
|
|
presence.attrs.from?.startsWith(`${r}/`),
|
|
`from must use the subdomain JID (got ${presence.attrs.from})`
|
|
);
|
|
});
|
|
|
|
it('non-subdomain room still works after mapper is loaded', async () => {
|
|
const r = baseRoom();
|
|
|
|
await ctx.connectFocus(r);
|
|
const c = await ctx.connect();
|
|
const presence = await c.joinRoom(r);
|
|
|
|
assert.ok(isAvailablePresence(presence),
|
|
'plain conference.localhost join must still succeed');
|
|
});
|
|
|
|
});
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Presence exchange between occupants
|
|
// -------------------------------------------------------------------------
|
|
describe('occupant presence exchange', () => {
|
|
|
|
it('two clients in the same subdomain room receive each other\'s presence', async () => {
|
|
const r = subRoom();
|
|
|
|
await ctx.connectFocus(r);
|
|
|
|
const c1 = await ctx.connect();
|
|
const c2 = await ctx.connect();
|
|
|
|
await c1.joinRoom(r);
|
|
await c2.joinRoom(r);
|
|
|
|
// c1 must receive c2's join presence with the subdomain from-JID
|
|
const p = await c1.waitForPresenceFrom(`${r}/${c2.nick}`);
|
|
|
|
assert.ok(isAvailablePresence(p),
|
|
'c1 must see c2 as available');
|
|
assert.equal(p.attrs.from, `${r}/${c2.nick}`,
|
|
'from must be the subdomain JID of c2');
|
|
});
|
|
|
|
it('two clients in different subdomain rooms do not see each other', async () => {
|
|
const r1 = subRoom();
|
|
const r2 = subRoom();
|
|
|
|
await ctx.connectFocus(r1);
|
|
await ctx.connectFocus(r2);
|
|
|
|
const c1 = await ctx.connect();
|
|
const c2 = await ctx.connect();
|
|
|
|
await c1.joinRoom(r1);
|
|
await c2.joinRoom(r2);
|
|
|
|
await assert.rejects(
|
|
() => c1.waitForPresenceFrom(`${r1}/${c2.nick}`, { timeout: 1000 }),
|
|
/Timeout/,
|
|
'c1 must not see c2 who joined a different room'
|
|
);
|
|
});
|
|
|
|
});
|
|
|
|
// -------------------------------------------------------------------------
|
|
// IQ routing through subdomain
|
|
// -------------------------------------------------------------------------
|
|
describe('IQ routing', () => {
|
|
|
|
it('disco#info to a subdomain room JID returns a result', async () => {
|
|
const r = subRoom();
|
|
|
|
await ctx.connectFocus(r);
|
|
const c = await ctx.connect();
|
|
|
|
await c.joinRoom(r);
|
|
|
|
const iq = await c.sendDiscoInfo(r);
|
|
|
|
assert.equal(iq.attrs.type, 'result',
|
|
'disco#info to subdomain room must return a result IQ');
|
|
});
|
|
|
|
});
|
|
|
|
});
|