-
-
Notifications
You must be signed in to change notification settings - Fork 72
Expand file tree
/
Copy pathapiResponse.test.ts
More file actions
69 lines (61 loc) · 2.16 KB
/
Copy pathapiResponse.test.ts
File metadata and controls
69 lines (61 loc) · 2.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { describe, it, expect, vi } from 'vitest';
import { ok, fail } from './apiResponse.js';
import type { Response } from 'express';
function makeMockRes(): Response {
const res = {
json: vi.fn(),
status: vi.fn(),
} as unknown as Response;
// status() must return the same res for chaining
(res.status as ReturnType<typeof vi.fn>).mockReturnValue(res);
(res.json as ReturnType<typeof vi.fn>).mockReturnValue(res);
return res;
}
describe('ok()', () => {
it('wraps a payload under data', () => {
const res = makeMockRes();
const result = ok(res, { a: 1 });
expect(res.json).toHaveBeenCalledWith({ success: true, data: { a: 1 } });
expect(result).toBe(res);
});
it('emits { success: true } with no data key when called without a second argument', () => {
const res = makeMockRes();
ok(res);
const body = (res.json as ReturnType<typeof vi.fn>).mock.calls[0][0] as Record<string, unknown>;
expect(body).toEqual({ success: true });
expect('data' in body).toBe(false);
});
it('includes data: null when null is passed (null is a real payload, not absence)', () => {
const res = makeMockRes();
ok(res, null);
expect(res.json).toHaveBeenCalledWith({ success: true, data: null });
});
it('returns the res object for chaining', () => {
const res = makeMockRes();
expect(ok(res, 42)).toBe(res);
});
});
describe('fail()', () => {
it('sets the status and emits the error envelope', () => {
const res = makeMockRes();
const result = fail(res, 400, 'BAD', 'nope');
expect(res.status).toHaveBeenCalledWith(400);
expect(res.json).toHaveBeenCalledWith({ success: false, error: 'nope', code: 'BAD' });
expect(result).toBe(res);
});
it('spreads extra fields into the top-level body', () => {
const res = makeMockRes();
fail(res, 500, 'X', 'boom', { details: 'd', retryAfterSeconds: 3 });
expect(res.json).toHaveBeenCalledWith({
success: false,
error: 'boom',
code: 'X',
details: 'd',
retryAfterSeconds: 3,
});
});
it('returns the res object for chaining', () => {
const res = makeMockRes();
expect(fail(res, 500, 'E', 'err')).toBe(res);
});
});