Watch party presentation mode: share a website, Google Slides/Docs or PDF; everyone sees it, Slides and PDFs follow the presenter's page

This commit is contained in:
Jonathan Sykes
2026-10-15 19:15:04 +08:00
parent 32d1f6891b
commit ca042ccbe3
5 changed files with 138 additions and 4 deletions

View File

@@ -127,6 +127,25 @@ test('DJ suggestions and votes are broadcast, host consumes approved songs', asy
h.ws.close(); g.ws.close();
});
describe('watch party presenting', () => {
test('host shares a link that guests and late joiners see; junk and guest attempts are ignored', async () => {
const host = client({ role: 'host', pid: 'hostpid0010', name: 'H' });
const { code } = await host.next('hello');
const g = client({ role: 'guest', pid: 'guestpid0011', key: 'k'.repeat(36), name: 'G', code });
await g.next('hello');
g.send({ type: 'present', present: { url: 'https://evil.example/' } });
host.send({ type: 'present', present: { url: 'javascript:alert(1)' } });
host.send({ type: 'present', present: { url: 'https://docs.google.com/presentation/d/abc/edit', page: 3 } });
const shown = await g.next('present');
expect(shown.present).toMatchObject({ url: 'https://docs.google.com/presentation/d/abc/edit', page: 3, by: 'H' });
const late = client({ role: 'guest', pid: 'guestpid0012', key: 'l'.repeat(36), name: 'L', code });
expect((await late.next('hello')).present.page).toBe(3);
host.send({ type: 'present', present: null });
expect((await g.next('present')).present).toBe(null);
host.send({ type: 'end' }); await host.closed;
});
});
describe('watch party seat rules', () => {
test('unknown code closes with 4004 (no reconnect loop)', async () => {
const bad = client({ role: 'guest', pid: 'guestpid7777', name: 'X', code: 'YYYYYY' });