import { describe, expect, it } from 'vitest'; import { ActivityPublisher } from './activity'; const track = { id: '00000000-0000-4000-8000-000000000001' }; const device = '00000000-0000-4000-8000-000000000002'; describe('listening activity leases', () => { it('publishes actual playback, throttles progress, and clears on pause', async () => { let now = 1000; const sent: unknown[] = []; const publisher = new ActivityPublisher(async value => { sent.push(value); }, device, () => now); publisher.update({ track, playing: false, context: null }); await publisher.idle(); expect(sent).toEqual([]); publisher.update({ track, playing: true, context: { type: 'wave' }, positionMs: 123 }); await publisher.idle(); expect(sent[0]).toMatchObject({ context: 'wave', track_id: track.id, sequence: 1, position_ms: 123 }); publisher.update({ track, playing: true, context: { type: 'wave' }, positionMs: 900 }); await publisher.idle(); expect(sent).toHaveLength(1); now += 20_001; publisher.update({ track, playing: true, context: { type: 'wave' }, positionMs: 20123 }); await publisher.idle(); expect(sent).toHaveLength(2); publisher.update({ track, playing: false, context: null }); await publisher.idle(); expect(sent.at(-1)).toMatchObject({ playing: false, sequence: 3 }); publisher.dispose(); await publisher.idle(); }); it('serializes an in-flight play and a final stop without replaying intermediate tracks', async () => { let release!: () => void; const waiting = new Promise(r => { release = r; }); const sent: { playing: boolean; sequence: number }[] = []; const publisher = new ActivityPublisher(async value => { sent.push(value); if (sent.length === 1) await waiting; }, device); publisher.update({ track, playing: true, context: null }); publisher.update({ track: { id: device }, playing: true, context: null }); publisher.dispose(); release(); await publisher.idle(); expect(sent.map(v => [v.playing, v.sequence])).toEqual([[true, 1], [false, 2]]); }); it('only treats UUID collection contexts as playlists', async () => { const sent: { context: string }[] = []; const publisher = new ActivityPublisher(async v => { sent.push(v); }, device); publisher.update({ track, playing: true, context: { type: 'collection', id: 'likes' } }); await publisher.idle(); expect(sent[0]?.context).toBe('other'); publisher.update({ track, playing: true, context: { type: 'collection', id: device } }); await publisher.idle(); expect(sent[1]?.context).toBe('playlist'); publisher.dispose(); await publisher.idle(); }); });