/ src / lib / app / api-client.test.ts
api-client.test.ts
 1  import test from 'node:test'
 2  import assert from 'node:assert/strict'
 3  
 4  import { api } from './api-client'
 5  
 6  const originalFetch = global.fetch
 7  
 8  test.afterEach(() => {
 9    global.fetch = originalFetch
10  })
11  
12  test('dedupes concurrent GET requests for the same path', async () => {
13    let calls = 0
14    global.fetch = (async () => {
15      calls += 1
16      await new Promise((resolve) => setTimeout(resolve, 25))
17      return new Response(JSON.stringify({ ok: true }), {
18        headers: { 'content-type': 'application/json' },
19        status: 200,
20      })
21    }) as unknown as typeof fetch
22  
23    const [first, second] = await Promise.all([
24      api<{ ok: boolean }>('GET', '/dedupe-check'),
25      api<{ ok: boolean }>('GET', '/dedupe-check'),
26    ])
27  
28    assert.deepEqual(first, { ok: true })
29    assert.deepEqual(second, { ok: true })
30    assert.equal(calls, 1)
31  })
32  
33  test('does not dedupe non-GET requests', async () => {
34    let calls = 0
35    global.fetch = (async () => {
36      calls += 1
37      return new Response(JSON.stringify({ ok: true }), {
38        headers: { 'content-type': 'application/json' },
39        status: 200,
40      })
41    }) as unknown as typeof fetch
42  
43    await Promise.all([
44      api<{ ok: boolean }>('POST', '/dedupe-check', { hello: 'one' }),
45      api<{ ok: boolean }>('POST', '/dedupe-check', { hello: 'two' }),
46    ])
47  
48    assert.equal(calls, 2)
49  })
50  
51  test('retries GET requests that fail with TimeoutError', async () => {
52    let calls = 0
53    global.fetch = (async () => {
54      calls += 1
55      if (calls === 1) {
56        const error = new Error('Request timed out after 12000ms')
57        error.name = 'TimeoutError'
58        throw error
59      }
60      return new Response(JSON.stringify({ ok: true }), {
61        headers: { 'content-type': 'application/json' },
62        status: 200,
63      })
64    }) as unknown as typeof fetch
65  
66    const result = await api<{ ok: boolean }>('GET', '/timeout-retry')
67  
68    assert.deepEqual(result, { ok: true })
69    assert.equal(calls, 2)
70  })