forked from Lilly-Protocol/lily-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlifecycle-hooks.test.ts
More file actions
145 lines (133 loc) · 4.49 KB
/
Copy pathlifecycle-hooks.test.ts
File metadata and controls
145 lines (133 loc) · 4.49 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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import { describe, it, expect, vi } from 'vitest';
import {
type RequestLifecycleHooks,
composeHooks,
} from '../src/http/lifecycle-hooks';
import type { HttpRequest, HttpResponse } from '../src/http/types';
describe('RequestLifecycleHooks (issue #64)', () => {
const sampleRequest: HttpRequest = {
method: 'GET',
path: '/v1/agents',
};
const sampleResponse: HttpResponse = {
status: 200,
headers: new Headers(),
data: { ok: true },
};
describe('beforeRequest', () => {
it('calls beforeRequest hook before the request', async () => {
const calls: string[] = [];
const hooks: RequestLifecycleHooks = {
beforeRequest: () => {
calls.push('before');
},
};
await hooks.beforeRequest?.(sampleRequest);
expect(calls).toEqual(['before']);
});
it('receives the request object', async () => {
let received: HttpRequest | undefined;
const hooks: RequestLifecycleHooks = {
beforeRequest: (req) => {
received = req;
},
};
await hooks.beforeRequest?.(sampleRequest);
expect(received).toBe(sampleRequest);
});
});
describe('afterResponse', () => {
it('calls afterResponse with request and response', async () => {
let receivedReq: HttpRequest | undefined;
let receivedRes: HttpResponse | undefined;
const hooks: RequestLifecycleHooks = {
afterResponse: (req, res) => {
receivedReq = req;
receivedRes = res;
},
};
await hooks.afterResponse?.(sampleRequest, sampleResponse);
expect(receivedReq).toBe(sampleRequest);
expect(receivedRes).toBe(sampleResponse);
});
});
describe('onError', () => {
it('calls onError with request and error', async () => {
let receivedReq: HttpRequest | undefined;
let receivedErr: Error | undefined;
const testError = new Error('test');
const hooks: RequestLifecycleHooks = {
onError: (req, err) => {
receivedReq = req;
receivedErr = err;
},
};
await hooks.onError?.(sampleRequest, testError);
expect(receivedReq).toBe(sampleRequest);
expect(receivedErr).toBe(testError);
});
});
describe('onRetry', () => {
it('calls onRetry with attempt and delay', async () => {
let receivedAttempt: number | undefined;
let receivedDelay: number | undefined;
const hooks: RequestLifecycleHooks = {
onRetry: (_req, attempt, delayMs) => {
receivedAttempt = attempt;
receivedDelay = delayMs;
},
};
await hooks.onRetry?.(sampleRequest, 1, 250);
expect(receivedAttempt).toBe(1);
expect(receivedDelay).toBe(250);
});
});
describe('composeHooks', () => {
it('calls all composed beforeRequest hooks in order', async () => {
const calls: string[] = [];
const hooks1: RequestLifecycleHooks = {
beforeRequest: () => calls.push('1'),
};
const hooks2: RequestLifecycleHooks = {
beforeRequest: () => calls.push('2'),
};
const composed = composeHooks(hooks1, hooks2);
await composed.beforeRequest?.(sampleRequest);
expect(calls).toEqual(['1', '2']);
});
it('swallows errors in hooks', async () => {
const badHooks: RequestLifecycleHooks = {
beforeRequest: () => {
throw new Error('boom');
},
};
const goodHooks: RequestLifecycleHooks = {
beforeRequest: () => {},
};
const composed = composeHooks(badHooks, goodHooks);
await expect(composed.beforeRequest?.(sampleRequest)).resolves.toBeUndefined();
});
it('calls all composed afterResponse hooks', async () => {
const calls: string[] = [];
const composed = composeHooks(
{ afterResponse: () => calls.push('a') },
{ afterResponse: () => calls.push('b') },
);
await composed.afterResponse?.(sampleRequest, sampleResponse);
expect(calls).toEqual(['a', 'b']);
});
it('calls all composed onError hooks', async () => {
const calls: string[] = [];
const composed = composeHooks(
{ onError: () => calls.push('e1') },
{ onError: () => calls.push('e2') },
);
await composed.onError?.(sampleRequest, new Error('test'));
expect(calls).toEqual(['e1', 'e2']);
});
it('handles empty hook sets gracefully', async () => {
const composed = composeHooks();
await expect(composed.beforeRequest?.(sampleRequest)).resolves.toBeUndefined();
});
});
});