Skip to content
File

Blob: worker/src/client/radio/api.test.ts

typescript53 lines
1import assert from 'node:assert/strict';
2import { test } from 'node:test';
3import { ApiError, createRadioApi } from './api.ts';
4 
5test('status operations reject malformed successful responses before exposing state', async () => {
6 const api = createRadioApi(async () => Response.json({ online: true, viewers: 'many' }));
7 await assert.rejects(
8 api.getStatus(),
9 (error: unknown) => error instanceof ApiError && error.status === 502,
10 );
11});
12 
13test('viewer answers send the session capability and validate channel settings', async () => {
14 const member = { id: 'viewer', viewerToken: 'viewer-capability' };
15 const answer = { type: 'answer' as const, sdp: 'v=0' };
16 let conflicting = false;
17 const api = createRadioApi(async (url, init) => {
18 assert.equal(url, '/api/viewers/viewer/answer');
19 assert.equal(init?.method, 'POST');
20 assert.equal(init?.credentials, 'same-origin');
21 assert.equal(new Headers(init?.headers).get('X-Viewer-Token'), member.viewerToken);
22 assert.deepEqual(JSON.parse(String(init?.body)), { sessionDescription: answer });
23 return Response.json({
24 channels: [
25 { id: 1, dataChannelName: 'robot', ...(conflicting ? { ordered: false } : {}) },
26 { id: 3, dataChannelName: 'spectrum' },
27 ],
28 });
29 });
30 assert.deepEqual((await api.answerViewer(member, answer)).channels, [
31 { id: 1, dataChannelName: 'robot', ordered: true },
32 { id: 3, dataChannelName: 'spectrum', ordered: false, maxRetransmits: 0 },
33 ]);
34 conflicting = true;
35 await assert.rejects(api.answerViewer(member, answer), ApiError);
36});
37 
38test('API failures preserve authentication status and handle non-JSON errors', async () => {
39 const unauthorized = createRadioApi(async () =>
40 Response.json({ error: 'Access required.' }, { status: 401 }),
41 );
42 await assert.rejects(
43 unauthorized.getStatus(),
44 (error: unknown) =>
45 error instanceof ApiError && error.status === 401 && error.message === 'Access required.',
46 );
47 const unavailable = createRadioApi(async () => new Response('Unavailable', { status: 503 }));
48 await assert.rejects(
49 unavailable.getStatus(),
50 (error: unknown) => error instanceof ApiError && error.status === 503,
51 );
52});