Skip to content

Commit 327b734

Browse files
🧪 testing improvement: add missing tests for API error paths (#44)
Adds test coverage for the `query` function in `src/api.ts` verifying the correct error behavior when `runtimeFetch` throws (e.g. network failure), returns non-JSON bodies on 200 responses, and returns non-200 HTTP status codes. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: sunnylqm <615282+sunnylqm@users.noreply.github.com>
1 parent ca81e2e commit 327b734

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

‎tests/api.test.ts‎

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ import {
1010
import fs from 'fs';
1111
import {
1212
closeSession,
13+
get,
1314
getApiToken,
1415
getSession,
1516
loadSession,
1617
replaceSession,
1718
saveSession,
1819
setApiToken,
1920
} from '../src/api';
21+
import * as runtime from '../src/utils/runtime';
2022

2123
describe('api.ts session management', () => {
2224
let originalConsoleError: typeof console.error;
@@ -137,3 +139,89 @@ describe('api.ts token management', () => {
137139
existsSyncSpy.mockRestore();
138140
});
139141
});
142+
143+
describe('api.ts query API methods', () => {
144+
let runtimeFetchSpy: ReturnType<typeof spyOn>;
145+
let originalConsoleWarn: typeof console.warn;
146+
let getBaseUrlSpy: ReturnType<typeof spyOn>;
147+
let _httpHelperBaseUrl: any;
148+
149+
beforeEach(() => {
150+
originalConsoleWarn = console.warn;
151+
console.warn = mock(() => {});
152+
});
153+
154+
afterEach(() => {
155+
console.warn = originalConsoleWarn;
156+
runtimeFetchSpy?.mockRestore();
157+
getBaseUrlSpy?.mockRestore();
158+
});
159+
160+
test('query throws correctly formatted error on network failure', async () => {
161+
runtimeFetchSpy = spyOn(runtime, 'runtimeFetch').mockImplementation(
162+
async () => {
163+
throw new Error('Network disconnected');
164+
},
165+
);
166+
167+
let error: any;
168+
try {
169+
await get('/test-endpoint');
170+
} catch (e) {
171+
error = e;
172+
}
173+
174+
expect(error).toBeDefined();
175+
expect(error.message).toContain('Network disconnected');
176+
expect(error.message).toContain('URL:');
177+
});
178+
179+
test('query warns on 200 status with non-JSON body', async () => {
180+
const nonJsonText = 'Not a JSON response';
181+
runtimeFetchSpy = spyOn(runtime, 'runtimeFetch').mockImplementation(
182+
async () =>
183+
({
184+
status: 200,
185+
statusText: 'OK',
186+
text: async () => nonJsonText,
187+
}) as any,
188+
);
189+
190+
let _error: any;
191+
try {
192+
await get('/test-endpoint');
193+
} catch (e) {
194+
_error = e;
195+
}
196+
197+
expect(console.warn).toHaveBeenCalled();
198+
const warnMessage = (console.warn as import('bun:test').Mock<any>).mock
199+
.calls[0][0];
200+
expect(warnMessage).toContain(
201+
'Warning: API returned 200 with non-JSON body',
202+
);
203+
expect(warnMessage).toContain(String(nonJsonText.length));
204+
});
205+
206+
test('query throws on non-200 HTTP status', async () => {
207+
runtimeFetchSpy = spyOn(runtime, 'runtimeFetch').mockImplementation(
208+
async () =>
209+
({
210+
status: 500,
211+
statusText: 'Internal Server Error',
212+
text: async () => JSON.stringify({ message: 'Database failure' }),
213+
}) as any,
214+
);
215+
216+
let error: any;
217+
try {
218+
await get('/test-endpoint');
219+
} catch (e) {
220+
error = e;
221+
}
222+
223+
expect(error).toBeDefined();
224+
expect(error.message).toContain('Database failure');
225+
expect(error.status).toBe(500);
226+
});
227+
});

0 commit comments

Comments
 (0)