Skip to content

Commit 359fe24

Browse files
committed
test(fetcher): cover JSON parsing error catch block
- Add test case for when error response JSON parsing fails - Ensures the catch block fallback to default error message is covered - Now at 77 total tests with complete line coverage - Fixes missing coverage on line 59 in src/api/fetcher.ts This should finally achieve true 100% coverage on Codecov! 🎯
1 parent 53806fe commit 359fe24

File tree

1 file changed

+40
-29
lines changed

1 file changed

+40
-29
lines changed

tests/api/fetcher.test.ts

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,59 @@
1-
import { describe, it, expect, vi } from 'vitest';
2-
import { fetcher } from '../../src/api/fetcher';
1+
import { describe, it, expect, vi } from 'vitest'
2+
import { fetcher } from '../../src/api/fetcher'
33

4-
const DUMMY_URL = 'https://api.example.com/test';
5-
const DUMMY_TOKEN = 'dummy-token';
4+
const DUMMY_URL = 'https://api.example.com/test'
5+
const DUMMY_TOKEN = 'dummy-token'
66

77
// Helper to mock fetch
8-
function mockFetch(response: Partial<Response> & { json?: () => any }, ok = true) {
8+
function mockFetch(
9+
response: Partial<Response> & { json?: () => any },
10+
ok = true
11+
) {
912
global.fetch = vi.fn().mockResolvedValue({
1013
ok,
1114
json: response.json || (() => Promise.resolve(response)),
1215
...response,
13-
}) as any;
16+
}) as any
1417
}
1518

1619
describe('fetcher', () => {
1720
afterEach(() => {
18-
vi.resetAllMocks();
19-
});
21+
vi.resetAllMocks()
22+
})
2023

2124
it('throws if token is missing', async () => {
22-
await expect(fetcher(DUMMY_URL, ''))
23-
.rejects.toThrow(/token/i);
24-
});
25+
await expect(fetcher(DUMMY_URL, '')).rejects.toThrow(/token/i)
26+
})
2527

2628
it('returns JSON on success', async () => {
27-
const data = { foo: 'bar' };
28-
mockFetch({ json: () => Promise.resolve(data) });
29-
const result = await fetcher(DUMMY_URL, DUMMY_TOKEN);
30-
expect(result).toEqual(data);
31-
expect(global.fetch).toHaveBeenCalledWith(DUMMY_URL, expect.objectContaining({
32-
headers: expect.objectContaining({
33-
'X-FIGMA-TOKEN': DUMMY_TOKEN,
34-
'Content-Type': 'application/json',
35-
}),
36-
}));
37-
});
29+
const data = { foo: 'bar' }
30+
mockFetch({ json: () => Promise.resolve(data) })
31+
const result = await fetcher(DUMMY_URL, DUMMY_TOKEN)
32+
expect(result).toEqual(data)
33+
expect(global.fetch).toHaveBeenCalledWith(
34+
DUMMY_URL,
35+
expect.objectContaining({
36+
headers: expect.objectContaining({
37+
'X-FIGMA-TOKEN': DUMMY_TOKEN,
38+
'Content-Type': 'application/json',
39+
}),
40+
})
41+
)
42+
})
3843

3944
it('throws with error message if response is not ok and error message exists', async () => {
40-
mockFetch({ json: () => Promise.resolve({ message: 'fail!' }) }, false);
41-
await expect(fetcher(DUMMY_URL, DUMMY_TOKEN)).rejects.toThrow('fail!');
42-
});
45+
mockFetch({ json: () => Promise.resolve({ message: 'fail!' }) }, false)
46+
await expect(fetcher(DUMMY_URL, DUMMY_TOKEN)).rejects.toThrow('fail!')
47+
})
4348

4449
it('throws with fallback error if response is not ok and no message', async () => {
45-
mockFetch({ json: () => Promise.resolve({}) }, false);
46-
await expect(fetcher(DUMMY_URL, DUMMY_TOKEN)).rejects.toThrow(/fetch/i);
47-
});
48-
});
50+
mockFetch({ json: () => Promise.resolve({}) }, false)
51+
await expect(fetcher(DUMMY_URL, DUMMY_TOKEN)).rejects.toThrow(/fetch/i)
52+
})
53+
54+
it('throws with fallback error if response is not ok and JSON parsing fails', async () => {
55+
// Mock a response that fails JSON parsing
56+
mockFetch({ json: () => Promise.reject(new Error('Invalid JSON')) }, false)
57+
await expect(fetcher(DUMMY_URL, DUMMY_TOKEN)).rejects.toThrow(/fetch/i)
58+
})
59+
})

0 commit comments

Comments
 (0)