b6f8a0c390
useEventsDispatcher subscribes to player.current/state via \$effect: on first transition to playing for a new track, POSTs play_started and caches the id; on track-id change while a play is open, closes the prior row as play_skipped; on natural completion (state playing→paused with position >= duration > 0), POSTs play_ended; on pagehide, navigator.sendBeacon fires a final play_skipped. Stable per-tab client_id from sessionStorage.
20 lines
650 B
TypeScript
20 lines
650 B
TypeScript
import { afterEach, beforeEach, describe, expect, test } from 'vitest';
|
|
import { getOrCreateClientId } from './clientId';
|
|
|
|
beforeEach(() => sessionStorage.clear());
|
|
afterEach(() => sessionStorage.clear());
|
|
|
|
describe('getOrCreateClientId', () => {
|
|
test('generates a UUID on first call and persists it in sessionStorage', () => {
|
|
const id = getOrCreateClientId();
|
|
expect(id).toMatch(/^[0-9a-f-]{36}$/);
|
|
expect(sessionStorage.getItem('minstrel.client_id')).toBe(id);
|
|
});
|
|
|
|
test('returns the same id on subsequent calls', () => {
|
|
const a = getOrCreateClientId();
|
|
const b = getOrCreateClientId();
|
|
expect(a).toBe(b);
|
|
});
|
|
});
|