@geekmidas/client 9.0.2 → 10.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth-fetcher-CBYuL6rx.d.cts +158 -0
- package/dist/auth-fetcher-CBYuL6rx.d.cts.map +1 -0
- package/dist/auth-fetcher-DOj0iz21.mjs +77 -0
- package/dist/auth-fetcher-DOj0iz21.mjs.map +1 -0
- package/dist/auth-fetcher-DxS8zOLc.d.mts +158 -0
- package/dist/auth-fetcher-DxS8zOLc.d.mts.map +1 -0
- package/dist/auth-fetcher-HILABmws.cjs +82 -0
- package/dist/auth-fetcher-HILABmws.cjs.map +1 -0
- package/dist/auth-fetcher.cjs +3 -76
- package/dist/auth-fetcher.d.cts +3 -158
- package/dist/auth-fetcher.d.mts +3 -158
- package/dist/auth-fetcher.mjs +3 -76
- package/dist/endpoint-hooks.d.mts +1 -1
- package/dist/fetcher-C1xtCKpT.d.mts +25 -0
- package/dist/fetcher-C1xtCKpT.d.mts.map +1 -0
- package/dist/fetcher-cDrfwN-Y.d.cts +25 -0
- package/dist/fetcher-cDrfwN-Y.d.cts.map +1 -0
- package/dist/fetcher.d.cts +3 -25
- package/dist/fetcher.d.mts +3 -25
- package/dist/index.cjs +8 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.mjs +6 -0
- package/dist/infer-6KKCgmg1.cjs +0 -0
- package/{src/infer.ts → dist/infer-DfRq5kIb.d.cts} +54 -83
- package/dist/infer-DfRq5kIb.d.cts.map +1 -0
- package/dist/infer-bTirNeNW.d.mts +133 -0
- package/dist/infer-bTirNeNW.d.mts.map +1 -0
- package/dist/infer-uCUq1whM.mjs +0 -0
- package/dist/infer.cjs +1 -0
- package/dist/infer.d.cts +2 -133
- package/dist/infer.d.mts +2 -133
- package/dist/infer.mjs +1 -0
- package/dist/openapi-hooks.cjs.map +1 -1
- package/dist/openapi-hooks.d.cts +3 -3
- package/dist/openapi-hooks.d.cts.map +1 -1
- package/dist/openapi-hooks.d.mts +1 -1
- package/dist/openapi-hooks.d.mts.map +1 -1
- package/dist/openapi-hooks.mjs.map +1 -1
- package/dist/react-query.d.cts +7 -7
- package/dist/react-query.d.mts +1 -1
- package/dist/types-BH8WgGrm.mjs +0 -0
- package/dist/{types-D8Jrl4o3.d.mts → types-BMGM6sZc.d.mts} +1 -1
- package/dist/{types-D8Jrl4o3.d.mts.map → types-BMGM6sZc.d.mts.map} +1 -1
- package/dist/types-a8gm_IaQ.cjs +0 -0
- package/dist/types.cjs +1 -0
- package/dist/types.d.mts +1 -1
- package/dist/types.mjs +1 -0
- package/package.json +8 -5
- package/CHANGELOG.md +0 -146
- package/dist/auth-fetcher.cjs.map +0 -1
- package/dist/auth-fetcher.d.cts.map +0 -1
- package/dist/auth-fetcher.d.mts.map +0 -1
- package/dist/auth-fetcher.mjs.map +0 -1
- package/dist/fetcher.d.cts.map +0 -1
- package/dist/fetcher.d.mts.map +0 -1
- package/dist/infer.d.cts.map +0 -1
- package/dist/infer.d.mts.map +0 -1
- package/src/__tests__/auth-fetcher.spec.ts +0 -505
- package/src/__tests__/endpoint-hooks.spec.tsx +0 -374
- package/src/__tests__/fetcher.spec.ts +0 -580
- package/src/__tests__/infer.integration.spec.ts +0 -188
- package/src/__tests__/infer.spec.ts +0 -189
- package/src/__tests__/method-restrictions.spec.tsx +0 -227
- package/src/__tests__/mutation-inference.spec.tsx +0 -343
- package/src/__tests__/openapi-hooks.spec.tsx +0 -557
- package/src/__tests__/react-query-infinite.spec.tsx +0 -1003
- package/src/__tests__/react-query-invalidation.spec.tsx +0 -239
- package/src/__tests__/react-query.spec.tsx +0 -582
- package/src/__tests__/setup.ts +0 -281
- package/src/__tests__/types.spec.ts +0 -134
- package/src/__tests__/url-parsing.spec.ts +0 -196
- package/src/auth-fetcher.ts +0 -288
- package/src/endpoint-hooks.ts +0 -346
- package/src/fetcher.ts +0 -171
- package/src/openapi-hooks.ts +0 -193
- package/src/openapi-types.d.ts +0 -440
- package/src/openapi.json +0 -595
- package/src/react-query.ts +0 -341
- package/src/types.ts +0 -226
- package/tsconfig.json +0 -12
|
@@ -1,557 +0,0 @@
|
|
|
1
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
2
|
-
/**
|
|
3
|
-
* @vitest-environment jsdom
|
|
4
|
-
*/
|
|
5
|
-
import { renderHook, waitFor } from '@testing-library/react';
|
|
6
|
-
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
7
|
-
import { createOpenAPIHooks } from '../openapi-hooks';
|
|
8
|
-
import './setup';
|
|
9
|
-
|
|
10
|
-
// Test OpenAPI types
|
|
11
|
-
interface TestPaths {
|
|
12
|
-
'/users': {
|
|
13
|
-
get: {
|
|
14
|
-
operationId: 'listUsers';
|
|
15
|
-
parameters?: {
|
|
16
|
-
query?: {
|
|
17
|
-
page?: number;
|
|
18
|
-
limit?: number;
|
|
19
|
-
search?: string;
|
|
20
|
-
};
|
|
21
|
-
};
|
|
22
|
-
responses: {
|
|
23
|
-
200: {
|
|
24
|
-
content: {
|
|
25
|
-
'application/json': {
|
|
26
|
-
users: Array<{
|
|
27
|
-
id: string;
|
|
28
|
-
name: string;
|
|
29
|
-
email: string;
|
|
30
|
-
}>;
|
|
31
|
-
total: number;
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
|
-
post: {
|
|
38
|
-
operationId: 'createUser';
|
|
39
|
-
requestBody: {
|
|
40
|
-
content: {
|
|
41
|
-
'application/json': {
|
|
42
|
-
name: string;
|
|
43
|
-
email: string;
|
|
44
|
-
password: string;
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
responses: {
|
|
49
|
-
201: {
|
|
50
|
-
content: {
|
|
51
|
-
'application/json': {
|
|
52
|
-
id: string;
|
|
53
|
-
name: string;
|
|
54
|
-
email: string;
|
|
55
|
-
};
|
|
56
|
-
};
|
|
57
|
-
};
|
|
58
|
-
};
|
|
59
|
-
};
|
|
60
|
-
};
|
|
61
|
-
'/users/{id}': {
|
|
62
|
-
parameters: {
|
|
63
|
-
path: {
|
|
64
|
-
id: string;
|
|
65
|
-
};
|
|
66
|
-
};
|
|
67
|
-
get: {
|
|
68
|
-
operationId: 'getUser';
|
|
69
|
-
responses: {
|
|
70
|
-
200: {
|
|
71
|
-
content: {
|
|
72
|
-
'application/json': {
|
|
73
|
-
id: string;
|
|
74
|
-
name: string;
|
|
75
|
-
email: string;
|
|
76
|
-
createdAt: string;
|
|
77
|
-
};
|
|
78
|
-
};
|
|
79
|
-
};
|
|
80
|
-
};
|
|
81
|
-
};
|
|
82
|
-
patch: {
|
|
83
|
-
operationId: 'updateUser';
|
|
84
|
-
requestBody: {
|
|
85
|
-
content: {
|
|
86
|
-
'application/json': {
|
|
87
|
-
name?: string;
|
|
88
|
-
email?: string;
|
|
89
|
-
};
|
|
90
|
-
};
|
|
91
|
-
};
|
|
92
|
-
responses: {
|
|
93
|
-
200: {
|
|
94
|
-
content: {
|
|
95
|
-
'application/json': {
|
|
96
|
-
id: string;
|
|
97
|
-
name: string;
|
|
98
|
-
email: string;
|
|
99
|
-
};
|
|
100
|
-
};
|
|
101
|
-
};
|
|
102
|
-
};
|
|
103
|
-
};
|
|
104
|
-
delete: {
|
|
105
|
-
operationId: 'deleteUser';
|
|
106
|
-
responses: {
|
|
107
|
-
204: {};
|
|
108
|
-
};
|
|
109
|
-
};
|
|
110
|
-
};
|
|
111
|
-
'/posts/{postId}': {
|
|
112
|
-
get: {
|
|
113
|
-
operationId: 'getPost';
|
|
114
|
-
parameters: {
|
|
115
|
-
path: {
|
|
116
|
-
postId: string;
|
|
117
|
-
};
|
|
118
|
-
query?: {
|
|
119
|
-
includeAuthor?: boolean;
|
|
120
|
-
};
|
|
121
|
-
};
|
|
122
|
-
responses: {
|
|
123
|
-
200: {
|
|
124
|
-
content: {
|
|
125
|
-
'application/json': {
|
|
126
|
-
id: string;
|
|
127
|
-
title: string;
|
|
128
|
-
content: string;
|
|
129
|
-
authorId: string;
|
|
130
|
-
author?: {
|
|
131
|
-
id: string;
|
|
132
|
-
name: string;
|
|
133
|
-
};
|
|
134
|
-
};
|
|
135
|
-
};
|
|
136
|
-
};
|
|
137
|
-
};
|
|
138
|
-
};
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Note: fetch is mocked by MSW in setup.ts
|
|
143
|
-
|
|
144
|
-
// Test wrapper
|
|
145
|
-
function createWrapper() {
|
|
146
|
-
const queryClient = new QueryClient({
|
|
147
|
-
defaultOptions: {
|
|
148
|
-
queries: { retry: false },
|
|
149
|
-
mutations: { retry: false },
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
return ({ children }: { children: any }) => (
|
|
154
|
-
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
describe('createOpenAPIHooks', () => {
|
|
159
|
-
const operations = {
|
|
160
|
-
listUsers: { path: '/users', method: 'get' },
|
|
161
|
-
createUser: { path: '/users', method: 'post' },
|
|
162
|
-
getUser: { path: '/users/{id}', method: 'get' },
|
|
163
|
-
updateUser: { path: '/users/{id}', method: 'patch' },
|
|
164
|
-
deleteUser: { path: '/users/{id}', method: 'delete' },
|
|
165
|
-
getPost: { path: '/posts/{postId}', method: 'get' },
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
afterEach(() => {
|
|
169
|
-
vi.clearAllMocks();
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
describe('useQuery', () => {
|
|
173
|
-
it('should fetch data for simple GET operation', async () => {
|
|
174
|
-
// MSW will return the predefined response from setup.ts
|
|
175
|
-
|
|
176
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
177
|
-
baseURL: 'https://api.example.com',
|
|
178
|
-
operations,
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
const { result } = renderHook(() => api.useQuery('listUsers'), {
|
|
182
|
-
wrapper: createWrapper(),
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
await waitFor(() => {
|
|
186
|
-
expect(result.current.isSuccess).toBe(true);
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
expect(result.current.data).toEqual({
|
|
190
|
-
users: [
|
|
191
|
-
{ id: '1', name: 'John Doe', email: 'john@example.com' },
|
|
192
|
-
{ id: '2', name: 'Jane Smith', email: 'jane@example.com' },
|
|
193
|
-
],
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
it('should handle query parameters', async () => {
|
|
198
|
-
// MSW will return the predefined response from setup.ts
|
|
199
|
-
|
|
200
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
201
|
-
baseURL: 'https://api.example.com',
|
|
202
|
-
operations,
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
const { result } = renderHook(
|
|
206
|
-
() =>
|
|
207
|
-
api.useQuery('listUsers', {
|
|
208
|
-
// query: { page: 2, limit: 10, search: 'john' },
|
|
209
|
-
}),
|
|
210
|
-
{ wrapper: createWrapper() },
|
|
211
|
-
);
|
|
212
|
-
|
|
213
|
-
await waitFor(() => {
|
|
214
|
-
expect(result.current.isSuccess).toBe(true);
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
// Query parameters are handled by MSW, verify data structure
|
|
218
|
-
expect(result.current.data).toBeDefined();
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
it('should handle path parameters', async () => {
|
|
222
|
-
// MSW will return the predefined response from setup.ts
|
|
223
|
-
|
|
224
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
225
|
-
baseURL: 'https://api.example.com',
|
|
226
|
-
operations,
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
const { result } = renderHook(
|
|
230
|
-
() =>
|
|
231
|
-
api.useQuery('getUser', {
|
|
232
|
-
params: { id: '123' },
|
|
233
|
-
}),
|
|
234
|
-
{ wrapper: createWrapper() },
|
|
235
|
-
);
|
|
236
|
-
|
|
237
|
-
await waitFor(() => {
|
|
238
|
-
expect(result.current.isSuccess).toBe(true);
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
expect(result.current.data).toEqual({
|
|
242
|
-
id: '123',
|
|
243
|
-
name: 'John Doe',
|
|
244
|
-
email: 'john@example.com',
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
it('should handle both path and query parameters', async () => {
|
|
249
|
-
// MSW will return the predefined response from setup.ts
|
|
250
|
-
|
|
251
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
252
|
-
baseURL: 'https://api.example.com',
|
|
253
|
-
operations,
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
const { result } = renderHook(
|
|
257
|
-
() =>
|
|
258
|
-
api.useQuery('getPost', {
|
|
259
|
-
params: { postId: '456' },
|
|
260
|
-
query: { includeAuthor: true },
|
|
261
|
-
}),
|
|
262
|
-
{ wrapper: createWrapper() },
|
|
263
|
-
);
|
|
264
|
-
|
|
265
|
-
await waitFor(() => {
|
|
266
|
-
expect(result.current.isSuccess).toBe(true);
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
expect(result.current.data).toEqual({
|
|
270
|
-
id: '456',
|
|
271
|
-
title: 'Test Post',
|
|
272
|
-
content: 'Test content',
|
|
273
|
-
authorId: '123',
|
|
274
|
-
author: { id: '123', name: 'John' },
|
|
275
|
-
});
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
it('should use proper query key for caching', async () => {
|
|
279
|
-
// MSW will handle the responses
|
|
280
|
-
|
|
281
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
282
|
-
baseURL: 'https://api.example.com',
|
|
283
|
-
operations,
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
const { result: result1 } = renderHook(
|
|
287
|
-
() =>
|
|
288
|
-
api.useQuery('listUsers', {
|
|
289
|
-
query: { page: 1 },
|
|
290
|
-
}),
|
|
291
|
-
{ wrapper: createWrapper() },
|
|
292
|
-
);
|
|
293
|
-
|
|
294
|
-
const { result: result2 } = renderHook(
|
|
295
|
-
() =>
|
|
296
|
-
api.useQuery('listUsers', {
|
|
297
|
-
query: { page: 1 },
|
|
298
|
-
}),
|
|
299
|
-
{ wrapper: createWrapper() },
|
|
300
|
-
);
|
|
301
|
-
|
|
302
|
-
await waitFor(() => {
|
|
303
|
-
expect(result1.current.isSuccess).toBe(true);
|
|
304
|
-
expect(result2.current.isSuccess).toBe(true);
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
// Both queries should have the same data due to caching
|
|
308
|
-
expect(result1.current.data).toEqual(result2.current.data);
|
|
309
|
-
});
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
describe('useMutation', () => {
|
|
313
|
-
it('should handle POST mutation', async () => {
|
|
314
|
-
// MSW will return the predefined response from setup.ts
|
|
315
|
-
|
|
316
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
317
|
-
baseURL: 'https://api.example.com',
|
|
318
|
-
operations,
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
const { result } = renderHook(() => api.useMutation('createUser'), {
|
|
322
|
-
wrapper: createWrapper(),
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
result.current.mutate({
|
|
326
|
-
body: {
|
|
327
|
-
name: 'New User',
|
|
328
|
-
email: 'new@example.com',
|
|
329
|
-
password: 'secret123',
|
|
330
|
-
},
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
await waitFor(() => {
|
|
334
|
-
expect(result.current.isSuccess).toBe(true);
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
expect(result.current.data).toEqual({
|
|
338
|
-
id: '123',
|
|
339
|
-
name: 'New User',
|
|
340
|
-
email: 'new@example.com',
|
|
341
|
-
});
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
it('should handle PATCH mutation with path params', async () => {
|
|
345
|
-
// MSW will return the predefined response from setup.ts
|
|
346
|
-
|
|
347
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
348
|
-
baseURL: 'https://api.example.com',
|
|
349
|
-
operations,
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
const { result } = renderHook(() => api.useMutation('updateUser'), {
|
|
353
|
-
wrapper: createWrapper(),
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
result.current.mutate({
|
|
357
|
-
params: { id: '123' },
|
|
358
|
-
body: { name: 'Updated Name' },
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
await waitFor(() => {
|
|
362
|
-
expect(result.current.isSuccess).toBe(true);
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
expect(result.current.data).toEqual({
|
|
366
|
-
id: '123',
|
|
367
|
-
name: 'Updated Name',
|
|
368
|
-
email: 'john@example.com',
|
|
369
|
-
});
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
it('should handle DELETE mutation returning void', async () => {
|
|
373
|
-
// MSW will return 204 No Content for DELETE
|
|
374
|
-
|
|
375
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
376
|
-
baseURL: 'https://api.example.com',
|
|
377
|
-
operations,
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
const { result } = renderHook(() => api.useMutation('deleteUser'), {
|
|
381
|
-
wrapper: createWrapper(),
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
result.current.mutate({
|
|
385
|
-
params: { id: '123' },
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
await waitFor(() => {
|
|
389
|
-
expect(result.current.isSuccess).toBe(true);
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
expect(result.current.data).toBeUndefined();
|
|
393
|
-
});
|
|
394
|
-
|
|
395
|
-
it('should handle mutation options', async () => {
|
|
396
|
-
// MSW will handle the response
|
|
397
|
-
|
|
398
|
-
const onSuccess = vi.fn();
|
|
399
|
-
const onError = vi.fn();
|
|
400
|
-
|
|
401
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
402
|
-
baseURL: 'https://api.example.com',
|
|
403
|
-
operations,
|
|
404
|
-
});
|
|
405
|
-
|
|
406
|
-
const { result } = renderHook(
|
|
407
|
-
() =>
|
|
408
|
-
api.useMutation('createUser', {
|
|
409
|
-
onSuccess,
|
|
410
|
-
onError,
|
|
411
|
-
}),
|
|
412
|
-
{ wrapper: createWrapper() },
|
|
413
|
-
);
|
|
414
|
-
|
|
415
|
-
result.current.mutate({
|
|
416
|
-
body: {
|
|
417
|
-
name: 'Test',
|
|
418
|
-
email: 'test@test.com',
|
|
419
|
-
password: 'password',
|
|
420
|
-
},
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
await waitFor(() => {
|
|
424
|
-
expect(result.current.isSuccess).toBe(true);
|
|
425
|
-
});
|
|
426
|
-
|
|
427
|
-
expect(onSuccess).toHaveBeenCalled();
|
|
428
|
-
expect(onSuccess.mock.calls[0]?.[0]).toEqual({
|
|
429
|
-
id: '123',
|
|
430
|
-
name: 'Test',
|
|
431
|
-
email: 'test@test.com',
|
|
432
|
-
});
|
|
433
|
-
expect(onError).not.toHaveBeenCalled();
|
|
434
|
-
});
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
describe('buildEndpoint', () => {
|
|
438
|
-
it('should use operation registry when provided', () => {
|
|
439
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
440
|
-
baseURL: 'https://api.example.com',
|
|
441
|
-
operations,
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
// The endpoint should be built correctly based on the registry
|
|
445
|
-
const { result } = renderHook(() => api.useQuery('listUsers'), {
|
|
446
|
-
wrapper: createWrapper(),
|
|
447
|
-
});
|
|
448
|
-
|
|
449
|
-
// Wait for the query to be initiated
|
|
450
|
-
expect(result.current.isLoading).toBe(true);
|
|
451
|
-
});
|
|
452
|
-
|
|
453
|
-
it('should work without operation registry', () => {
|
|
454
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
455
|
-
baseURL: 'https://api.example.com',
|
|
456
|
-
});
|
|
457
|
-
|
|
458
|
-
// Without registry, it should use operationId as fallback
|
|
459
|
-
const { result } = renderHook(() => api.useQuery('listUsers'), {
|
|
460
|
-
wrapper: createWrapper(),
|
|
461
|
-
});
|
|
462
|
-
|
|
463
|
-
expect(result.current.isLoading).toBe(true);
|
|
464
|
-
});
|
|
465
|
-
});
|
|
466
|
-
|
|
467
|
-
describe('type inference', () => {
|
|
468
|
-
it('should infer correct response types', () => {
|
|
469
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
470
|
-
baseURL: 'https://api.example.com',
|
|
471
|
-
operations,
|
|
472
|
-
});
|
|
473
|
-
|
|
474
|
-
const { result } = renderHook(() => api.useQuery('listUsers'), {
|
|
475
|
-
wrapper: createWrapper(),
|
|
476
|
-
});
|
|
477
|
-
|
|
478
|
-
// Type test - this should compile without errors
|
|
479
|
-
if (result.current.data) {
|
|
480
|
-
const users: Array<{ id: string; name: string; email: string }> =
|
|
481
|
-
result.current.data.users;
|
|
482
|
-
const total: number = result.current.data.total;
|
|
483
|
-
expect(users).toBeDefined();
|
|
484
|
-
expect(total).toBeDefined();
|
|
485
|
-
}
|
|
486
|
-
});
|
|
487
|
-
|
|
488
|
-
it('should enforce required parameters', () => {
|
|
489
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
490
|
-
baseURL: 'https://api.example.com',
|
|
491
|
-
operations,
|
|
492
|
-
});
|
|
493
|
-
|
|
494
|
-
// This test is about type checking, not runtime behavior
|
|
495
|
-
// The TypeScript compiler enforces these constraints:
|
|
496
|
-
|
|
497
|
-
// ✓ This compiles - no params required for listUsers
|
|
498
|
-
const listUsersHook = () => api.useQuery('listUsers');
|
|
499
|
-
|
|
500
|
-
// ✓ This compiles - params are provided for getUser
|
|
501
|
-
const getUserHook = () =>
|
|
502
|
-
api.useQuery('getUser', { params: { id: '123' } });
|
|
503
|
-
|
|
504
|
-
// ✗ This would not compile - missing required params
|
|
505
|
-
// const invalidHook = () => api.useQuery('getUser');
|
|
506
|
-
|
|
507
|
-
expect(listUsersHook).toBeDefined();
|
|
508
|
-
expect(getUserHook).toBeDefined();
|
|
509
|
-
});
|
|
510
|
-
|
|
511
|
-
it('should handle optional parameters correctly', () => {
|
|
512
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
513
|
-
baseURL: 'https://api.example.com',
|
|
514
|
-
operations,
|
|
515
|
-
});
|
|
516
|
-
|
|
517
|
-
// All valid ways to call listUsers - wrapped in functions
|
|
518
|
-
const hook1 = () => api.useQuery('listUsers');
|
|
519
|
-
const hook2 = () => api.useQuery('listUsers', {});
|
|
520
|
-
const hook3 = () => api.useQuery('listUsers', { query: {} });
|
|
521
|
-
const hook4 = () => api.useQuery('listUsers', { query: { page: 1 } });
|
|
522
|
-
const hook5 = () =>
|
|
523
|
-
api.useQuery('listUsers', { query: { page: 1, limit: 10 } });
|
|
524
|
-
|
|
525
|
-
expect(hook1).toBeDefined();
|
|
526
|
-
expect(hook2).toBeDefined();
|
|
527
|
-
expect(hook3).toBeDefined();
|
|
528
|
-
expect(hook4).toBeDefined();
|
|
529
|
-
expect(hook5).toBeDefined();
|
|
530
|
-
});
|
|
531
|
-
});
|
|
532
|
-
|
|
533
|
-
describe('error handling', () => {
|
|
534
|
-
it.skip('should handle fetch errors', async () => {
|
|
535
|
-
// This test is skipped because we need a way to trigger actual fetch errors
|
|
536
|
-
// The current implementation always returns successful responses from MSW
|
|
537
|
-
});
|
|
538
|
-
|
|
539
|
-
it('should handle non-ok responses', async () => {
|
|
540
|
-
// MSW will return 404 for user id '404'
|
|
541
|
-
|
|
542
|
-
const api = createOpenAPIHooks<TestPaths>({
|
|
543
|
-
baseURL: 'https://api.example.com',
|
|
544
|
-
operations,
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
const { result } = renderHook(
|
|
548
|
-
() => api.useQuery('getUser', { params: { id: '404' } }),
|
|
549
|
-
{ wrapper: createWrapper() },
|
|
550
|
-
);
|
|
551
|
-
|
|
552
|
-
await waitFor(() => {
|
|
553
|
-
expect(result.current.isError).toBe(true);
|
|
554
|
-
});
|
|
555
|
-
});
|
|
556
|
-
});
|
|
557
|
-
});
|