index.test.ts68 lines · main
1import { afterEach, describe, expect, test } from 'bun:test';
2
3import { createBrivenClient } from './index.js';
4
5const realFetch = globalThis.fetch;
6
7afterEach(() => {
8 globalThis.fetch = realFetch;
9});
10
11function client() {
12 return createBrivenClient({ projectId: 'p_test', apiOrigin: 'https://api.test' });
13}
14
15describe('invoke() never throws — always returns an InvokeFrame', () => {
16 test('non-JSON gateway body (502 HTML) → network_error frame, not a SyntaxError', async () => {
17 globalThis.fetch = (async () =>
18 new Response('<html>502 Bad Gateway</html>', {
19 status: 502,
20 headers: { 'content-type': 'text/html' },
21 })) as typeof fetch;
22
23 const frame = await client().invoke('listNotes');
24 expect(frame.ok).toBe(false);
25 if (!frame.ok) {
26 expect(frame.code).toBe('network_error');
27 expect(typeof frame.message).toBe('string');
28 expect(frame.durationMs).toBe(0);
29 }
30 });
31
32 test('a valid JSON error frame (422) is returned as-is', async () => {
33 globalThis.fetch = (async () =>
34 new Response(JSON.stringify({ ok: false, code: 'validation_failed', message: 'bad', durationMs: 3 }), {
35 status: 422,
36 headers: { 'content-type': 'application/json' },
37 })) as typeof fetch;
38
39 const frame = await client().invoke('createTodo', {});
40 expect(frame.ok).toBe(false);
41 if (!frame.ok) {
42 expect(frame.code).toBe('validation_failed');
43 expect(frame.message).toBe('bad');
44 }
45 });
46
47 test('a network failure (fetch throws) → network_error frame', async () => {
48 globalThis.fetch = (async () => {
49 throw new TypeError('Failed to fetch');
50 }) as typeof fetch;
51
52 const frame = await client().invoke('listNotes');
53 expect(frame.ok).toBe(false);
54 if (!frame.ok) expect(frame.code).toBe('network_error');
55 });
56
57 test('a valid success frame passes through', async () => {
58 globalThis.fetch = (async () =>
59 new Response(JSON.stringify({ ok: true, value: [1, 2, 3], durationMs: 5 }), {
60 status: 200,
61 headers: { 'content-type': 'application/json' },
62 })) as typeof fetch;
63
64 const frame = await client().invoke('listNotes');
65 expect(frame.ok).toBe(true);
66 if (frame.ok) expect(frame.value).toEqual([1, 2, 3]);
67 });
68});