@stratal/testing 0.0.11 → 0.0.12
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/core/env/test-env.js +1 -1
- package/dist/core/env/test-env.js.map +1 -1
- package/dist/core/http/index.d.ts +1 -1
- package/dist/core/http/index.js +1 -1
- package/dist/core/http/mock-fetch.d.ts +88 -0
- package/dist/core/http/mock-fetch.d.ts.map +1 -0
- package/dist/core/http/mock-fetch.js +111 -0
- package/dist/core/http/mock-fetch.js.map +1 -0
- package/dist/core/override/provider-override-builder.d.ts +1 -0
- package/dist/core/override/provider-override-builder.d.ts.map +1 -1
- package/dist/core/override/provider-override-builder.js.map +1 -1
- package/dist/core/testing-module-builder.js +2 -2
- package/dist/core/testing-module-builder.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/vitest-plugin/index.d.ts +2 -0
- package/dist/vitest-plugin/index.d.ts.map +1 -0
- package/dist/vitest-plugin/index.js +2 -0
- package/dist/vitest-plugin/index.js.map +1 -0
- package/dist/vitest-plugin/stratal-test.d.ts +28 -0
- package/dist/vitest-plugin/stratal-test.d.ts.map +1 -0
- package/dist/vitest-plugin/stratal-test.js +47 -0
- package/dist/vitest-plugin/stratal-test.js.map +1 -0
- package/package.json +17 -10
- package/dist/core/http/fetch-mock.d.ts +0 -236
- package/dist/core/http/fetch-mock.d.ts.map +0 -1
- package/dist/core/http/fetch-mock.js +0 -290
- package/dist/core/http/fetch-mock.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-env.js","sourceRoot":"","sources":["../../../src/core/env/test-env.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"test-env.js","sourceRoot":"","sources":["../../../src/core/env/test-env.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEzD;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,SAA+B;IACxD,OAAO;QACL,GAAG,aAAa;QAChB,GAAG,SAAS;KACC,CAAA;AACjB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { TestHttpClient } from './test-http-client';
|
|
2
2
|
export { TestHttpRequest } from './test-http-request';
|
|
3
3
|
export { TestResponse } from './test-response';
|
|
4
|
-
export {
|
|
4
|
+
export { MockFetch, createMockFetch } from './mock-fetch';
|
|
5
5
|
export type { MockJsonOptions, MockErrorOptions } from './fetch-mock.types';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/core/http/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { TestHttpClient } from './test-http-client';
|
|
2
2
|
export { TestHttpRequest } from './test-http-request';
|
|
3
3
|
export { TestResponse } from './test-response';
|
|
4
|
-
export {
|
|
4
|
+
export { MockFetch, createMockFetch } from './mock-fetch';
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type RequestHandler } from 'msw';
|
|
2
|
+
import type { MockErrorOptions, MockJsonOptions } from './fetch-mock.types';
|
|
3
|
+
/**
|
|
4
|
+
* MSW-based fetch mock for declarative HTTP mocking in tests.
|
|
5
|
+
*
|
|
6
|
+
* Replaces the old Cloudflare `fetchMock` (undici MockAgent) with MSW's `setupServer`.
|
|
7
|
+
* Works in both Node.js and workerd test environments.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { createMockFetch } from '@stratal/testing'
|
|
12
|
+
*
|
|
13
|
+
* const mock = createMockFetch()
|
|
14
|
+
*
|
|
15
|
+
* beforeAll(() => mock.listen())
|
|
16
|
+
* afterEach(() => mock.reset())
|
|
17
|
+
* afterAll(() => mock.close())
|
|
18
|
+
*
|
|
19
|
+
* it('should mock external API', async () => {
|
|
20
|
+
* mock.mockJsonResponse('https://api.example.com/data', { success: true })
|
|
21
|
+
*
|
|
22
|
+
* const response = await fetch('https://api.example.com/data')
|
|
23
|
+
* const json = await response.json()
|
|
24
|
+
*
|
|
25
|
+
* expect(json.success).toBe(true)
|
|
26
|
+
* })
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare class MockFetch {
|
|
30
|
+
private server;
|
|
31
|
+
constructor(handlers?: RequestHandler[]);
|
|
32
|
+
/** Start intercepting. Call in beforeAll/beforeEach. */
|
|
33
|
+
listen(): void;
|
|
34
|
+
/** Reset runtime handlers. Call in afterEach. */
|
|
35
|
+
reset(): void;
|
|
36
|
+
/** Stop intercepting. Call in afterAll. */
|
|
37
|
+
close(): void;
|
|
38
|
+
/** Add runtime handler(s) for a single test. */
|
|
39
|
+
use(...handlers: RequestHandler[]): void;
|
|
40
|
+
/**
|
|
41
|
+
* Mock a JSON response.
|
|
42
|
+
*
|
|
43
|
+
* @param url - Full URL to mock (e.g., 'https://api.example.com/users')
|
|
44
|
+
* @param data - JSON data to return
|
|
45
|
+
* @param options - HTTP method, status code, headers
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* mock.mockJsonResponse('https://api.example.com/users', { users: [] })
|
|
50
|
+
* mock.mockJsonResponse('https://api.example.com/users', { created: true }, { method: 'POST', status: 201 })
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
mockJsonResponse(url: string, data: Record<string, unknown> | unknown[], options?: MockJsonOptions): void;
|
|
54
|
+
/**
|
|
55
|
+
* Mock an error response.
|
|
56
|
+
*
|
|
57
|
+
* @param url - Full URL to mock
|
|
58
|
+
* @param status - HTTP error status code
|
|
59
|
+
* @param message - Optional error message
|
|
60
|
+
* @param options - HTTP method, headers
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* mock.mockError('https://api.example.com/fail', 401, 'Unauthorized')
|
|
65
|
+
* mock.mockError('https://api.example.com/fail', 500, 'Server Error', { method: 'POST' })
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
mockError(url: string, status: number, message?: string, options?: MockErrorOptions): void;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Factory function to create a new MockFetch instance
|
|
72
|
+
*
|
|
73
|
+
* @param handlers - Optional initial MSW request handlers
|
|
74
|
+
* @returns A new MockFetch instance
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* import { createMockFetch } from '@stratal/testing'
|
|
79
|
+
*
|
|
80
|
+
* const mock = createMockFetch()
|
|
81
|
+
*
|
|
82
|
+
* beforeAll(() => mock.listen())
|
|
83
|
+
* afterEach(() => mock.reset())
|
|
84
|
+
* afterAll(() => mock.close())
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function createMockFetch(handlers?: RequestHandler[]): MockFetch;
|
|
88
|
+
//# sourceMappingURL=mock-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-fetch.d.ts","sourceRoot":"","sources":["../../../src/core/http/mock-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAA;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAI3E;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAa;gBAEf,QAAQ,GAAE,cAAc,EAAO;IAI3C,wDAAwD;IACxD,MAAM;IAIN,iDAAiD;IACjD,KAAK;IAIL,2CAA2C;IAC3C,KAAK;IAIL,gDAAgD;IAChD,GAAG,CAAC,GAAG,QAAQ,EAAE,cAAc,EAAE;IAIjC;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EAAE,EAAE,OAAO,GAAE,eAAoB;IAWtG;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;CASxF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,cAAc,EAAE,GAAG,SAAS,CAEtE"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { http, HttpResponse } from 'msw';
|
|
2
|
+
import { setupServer } from 'msw/node';
|
|
3
|
+
/**
|
|
4
|
+
* MSW-based fetch mock for declarative HTTP mocking in tests.
|
|
5
|
+
*
|
|
6
|
+
* Replaces the old Cloudflare `fetchMock` (undici MockAgent) with MSW's `setupServer`.
|
|
7
|
+
* Works in both Node.js and workerd test environments.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { createMockFetch } from '@stratal/testing'
|
|
12
|
+
*
|
|
13
|
+
* const mock = createMockFetch()
|
|
14
|
+
*
|
|
15
|
+
* beforeAll(() => mock.listen())
|
|
16
|
+
* afterEach(() => mock.reset())
|
|
17
|
+
* afterAll(() => mock.close())
|
|
18
|
+
*
|
|
19
|
+
* it('should mock external API', async () => {
|
|
20
|
+
* mock.mockJsonResponse('https://api.example.com/data', { success: true })
|
|
21
|
+
*
|
|
22
|
+
* const response = await fetch('https://api.example.com/data')
|
|
23
|
+
* const json = await response.json()
|
|
24
|
+
*
|
|
25
|
+
* expect(json.success).toBe(true)
|
|
26
|
+
* })
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export class MockFetch {
|
|
30
|
+
server;
|
|
31
|
+
constructor(handlers = []) {
|
|
32
|
+
this.server = setupServer(...handlers);
|
|
33
|
+
}
|
|
34
|
+
/** Start intercepting. Call in beforeAll/beforeEach. */
|
|
35
|
+
listen() {
|
|
36
|
+
this.server.listen({ onUnhandledRequest: 'error' });
|
|
37
|
+
}
|
|
38
|
+
/** Reset runtime handlers. Call in afterEach. */
|
|
39
|
+
reset() {
|
|
40
|
+
this.server.resetHandlers();
|
|
41
|
+
}
|
|
42
|
+
/** Stop intercepting. Call in afterAll. */
|
|
43
|
+
close() {
|
|
44
|
+
this.server.close();
|
|
45
|
+
}
|
|
46
|
+
/** Add runtime handler(s) for a single test. */
|
|
47
|
+
use(...handlers) {
|
|
48
|
+
this.server.use(...handlers);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Mock a JSON response.
|
|
52
|
+
*
|
|
53
|
+
* @param url - Full URL to mock (e.g., 'https://api.example.com/users')
|
|
54
|
+
* @param data - JSON data to return
|
|
55
|
+
* @param options - HTTP method, status code, headers
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* mock.mockJsonResponse('https://api.example.com/users', { users: [] })
|
|
60
|
+
* mock.mockJsonResponse('https://api.example.com/users', { created: true }, { method: 'POST', status: 201 })
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
mockJsonResponse(url, data, options = {}) {
|
|
64
|
+
const method = (options.method ?? 'GET').toLowerCase();
|
|
65
|
+
const handler = http[method](url, () => HttpResponse.json(data, {
|
|
66
|
+
status: options.status ?? 200,
|
|
67
|
+
headers: options.headers,
|
|
68
|
+
}));
|
|
69
|
+
this.server.use(handler);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Mock an error response.
|
|
73
|
+
*
|
|
74
|
+
* @param url - Full URL to mock
|
|
75
|
+
* @param status - HTTP error status code
|
|
76
|
+
* @param message - Optional error message
|
|
77
|
+
* @param options - HTTP method, headers
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* mock.mockError('https://api.example.com/fail', 401, 'Unauthorized')
|
|
82
|
+
* mock.mockError('https://api.example.com/fail', 500, 'Server Error', { method: 'POST' })
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
mockError(url, status, message, options = {}) {
|
|
86
|
+
const method = (options.method ?? 'GET').toLowerCase();
|
|
87
|
+
const body = message ? { error: message } : undefined;
|
|
88
|
+
this.server.use(http[method](url, () => HttpResponse.json(body, { status, headers: options.headers })));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Factory function to create a new MockFetch instance
|
|
93
|
+
*
|
|
94
|
+
* @param handlers - Optional initial MSW request handlers
|
|
95
|
+
* @returns A new MockFetch instance
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* import { createMockFetch } from '@stratal/testing'
|
|
100
|
+
*
|
|
101
|
+
* const mock = createMockFetch()
|
|
102
|
+
*
|
|
103
|
+
* beforeAll(() => mock.listen())
|
|
104
|
+
* afterEach(() => mock.reset())
|
|
105
|
+
* afterAll(() => mock.close())
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export function createMockFetch(handlers) {
|
|
109
|
+
return new MockFetch(handlers);
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=mock-fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-fetch.js","sourceRoot":"","sources":["../../../src/core/http/mock-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,YAAY,EAAuB,MAAM,KAAK,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAoB,MAAM,UAAU,CAAA;AAKxD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,OAAO,SAAS;IACZ,MAAM,CAAa;IAE3B,YAAY,WAA6B,EAAE;QACzC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,GAAG,QAAQ,CAAC,CAAA;IACxC,CAAC;IAED,wDAAwD;IACxD,MAAM;QACJ,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,CAAA;IACrD,CAAC;IAED,iDAAiD;IACjD,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAA;IAC7B,CAAC;IAED,2CAA2C;IAC3C,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;IACrB,CAAC;IAED,gDAAgD;IAChD,GAAG,CAAC,GAAG,QAA0B;QAC/B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAA;IAC9B,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,GAAW,EAAE,IAAyC,EAAE,UAA2B,EAAE;QACpG,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAgB,CAAA;QACpE,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CACrC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE;YACtB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,GAAG;YAC7B,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CACH,CAAA;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAC1B,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,GAAW,EAAE,MAAc,EAAE,OAAgB,EAAE,UAA4B,EAAE;QACrF,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAgB,CAAA;QACpE,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;QACrD,IAAI,CAAC,MAAM,CAAC,GAAG,CACb,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CACrB,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAC9D,CACF,CAAA;IACH,CAAC;CACF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,eAAe,CAAC,QAA2B;IACzD,OAAO,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAA;AAChC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-override-builder.d.ts","sourceRoot":"","sources":["../../../src/core/override/provider-override-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAErE;;GAEG;AACH,MAAM,WAAW,sBAAsB,CAAC,CAAC,GAAG,OAAO;IACjD,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,CAAA;IACxB,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,CAAA;IAChD,cAAc,EAAE,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;CACxG;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,uBAAuB,CAAC,CAAC;IAElC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,MAAM,EAAE,oBAAoB,EAC5B,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC;IAG3C;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,oBAAoB;IAQxC;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,oBAAoB;IAQlE;;;;;;;OAOG;IACH,UAAU,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,GAAG,oBAAoB;IAQtE;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,oBAAoB;CAOpE"}
|
|
1
|
+
{"version":3,"file":"provider-override-builder.d.ts","sourceRoot":"","sources":["../../../src/core/override/provider-override-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAErE;;GAEG;AACH,MAAM,WAAW,sBAAsB,CAAC,CAAC,GAAG,OAAO;IACjD,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,CAAA;IACxB,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,CAAA;IAChD,cAAc,EAAE,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;CACxG;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,uBAAuB,CAAC,CAAC;IAElC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,MAAM,EAAE,oBAAoB,EAC5B,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC;IAG3C;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,oBAAoB;IAQxC;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,oBAAoB;IAQlE;;;;;;;OAOG;IACH,UAAU,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,GAAG,oBAAoB;IAQtE;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,oBAAoB;CAOpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-override-builder.js","sourceRoot":"","sources":["../../../src/core/override/provider-override-builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"provider-override-builder.js","sourceRoot":"","sources":["../../../src/core/override/provider-override-builder.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,uBAAuB;IAEf;IACA;IAFnB,YACmB,MAA4B,EAC5B,KAAwB;QADxB,WAAM,GAAN,MAAM,CAAsB;QAC5B,UAAK,GAAL,KAAK,CAAmB;IACvC,CAAC;IAEL;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAQ;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,OAAO;YACb,cAAc,EAAE,KAAK;SACtB,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAkC;QACzC,OAAO,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,OAAO;YACb,cAAc,EAAE,GAAG;SACpB,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,UAAU,CAAC,OAAoC;QAC7C,OAAO,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,SAAS;YACf,cAAc,EAAE,OAAO;SACxB,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,aAAgC;QAC1C,OAAO,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,UAAU;YAChB,cAAc,EAAE,aAAa;SAC9B,CAAC,CAAA;IACJ,CAAC;CACF"}
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import {
|
|
7
|
+
import { waitUntil } from 'cloudflare:workers';
|
|
8
8
|
import { Application, } from 'stratal';
|
|
9
9
|
import { LogLevel } from 'stratal/logger';
|
|
10
10
|
import { Module } from 'stratal/module';
|
|
@@ -52,7 +52,7 @@ export class TestingModuleBuilder {
|
|
|
52
52
|
*/
|
|
53
53
|
async compile() {
|
|
54
54
|
const env = getTestEnv(this.config.env);
|
|
55
|
-
const ctx =
|
|
55
|
+
const ctx = { waitUntil };
|
|
56
56
|
// Build root module from config
|
|
57
57
|
const baseModules = Test.getBaseModules();
|
|
58
58
|
const allImports = [...baseModules, ...(this.config.imports ?? [])];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing-module-builder.js","sourceRoot":"","sources":["../../src/core/testing-module-builder.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"testing-module-builder.js","sourceRoot":"","sources":["../../src/core/testing-module-builder.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,11 +2,12 @@ export { ProviderOverrideBuilder, type ProviderOverrideConfig } from './core/ove
|
|
|
2
2
|
export { Test } from './core/test';
|
|
3
3
|
export { TestingModule } from './core/testing-module';
|
|
4
4
|
export { TestingModuleBuilder, type TestingModuleConfig } from './core/testing-module-builder';
|
|
5
|
-
export {
|
|
5
|
+
export { createMockFetch, MockFetch } from './core/http/mock-fetch';
|
|
6
6
|
export type { MockErrorOptions, MockJsonOptions } from './core/http/fetch-mock.types';
|
|
7
7
|
export { TestHttpClient } from './core/http/test-http-client';
|
|
8
8
|
export { TestHttpRequest } from './core/http/test-http-request';
|
|
9
9
|
export { TestResponse } from './core/http/test-response';
|
|
10
|
+
export { http, HttpResponse } from 'msw';
|
|
10
11
|
export { ActingAs } from './auth';
|
|
11
12
|
export { FakeStorageService, type StoredFile } from './storage';
|
|
12
13
|
export { Seeder } from './types';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,KAAK,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AACtF,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AAG9F,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AACnE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAGxD,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAGjC,OAAO,EAAE,kBAAkB,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAA;AAG/D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAGhC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAGvC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,KAAK,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AACtF,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AAG9F,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AACnE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAGxD,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,KAAK,CAAA;AAGxC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAGjC,OAAO,EAAE,kBAAkB,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAA;AAG/D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAGhC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAGvC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -4,10 +4,12 @@ export { Test } from './core/test';
|
|
|
4
4
|
export { TestingModule } from './core/testing-module';
|
|
5
5
|
export { TestingModuleBuilder } from './core/testing-module-builder';
|
|
6
6
|
// HTTP Testing
|
|
7
|
-
export {
|
|
7
|
+
export { createMockFetch, MockFetch } from './core/http/mock-fetch';
|
|
8
8
|
export { TestHttpClient } from './core/http/test-http-client';
|
|
9
9
|
export { TestHttpRequest } from './core/http/test-http-request';
|
|
10
10
|
export { TestResponse } from './core/http/test-response';
|
|
11
|
+
// Re-export MSW utilities for convenience
|
|
12
|
+
export { http, HttpResponse } from 'msw';
|
|
11
13
|
// Auth
|
|
12
14
|
export { ActingAs } from './auth';
|
|
13
15
|
// Storage
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,uBAAuB,EAA+B,MAAM,iBAAiB,CAAA;AACtF,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,oBAAoB,EAA4B,MAAM,+BAA+B,CAAA;AAE9F,eAAe;AACf,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAExD,OAAO;AACP,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,UAAU;AACV,OAAO,EAAE,kBAAkB,EAAmB,MAAM,WAAW,CAAA;AAE/D,QAAQ;AACR,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAEhC,wBAAwB;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvC,SAAS;AACT,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,uBAAuB,EAA+B,MAAM,iBAAiB,CAAA;AACtF,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,oBAAoB,EAA4B,MAAM,+BAA+B,CAAA;AAE9F,eAAe;AACf,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAExD,0CAA0C;AAC1C,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,KAAK,CAAA;AAExC,OAAO;AACP,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,UAAU;AACV,OAAO,EAAE,kBAAkB,EAAmB,MAAM,WAAW,CAAA;AAE/D,QAAQ;AACR,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAEhC,wBAAwB;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvC,SAAS;AACT,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vitest-plugin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vitest-plugin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { cloudflareTest } from '@cloudflare/vitest-pool-workers';
|
|
2
|
+
import type { Plugin } from 'vite';
|
|
3
|
+
type CloudflareTestOptions = Parameters<typeof cloudflareTest>[0];
|
|
4
|
+
/**
|
|
5
|
+
* Unified Vite plugin for Stratal tests running in the Cloudflare Workers (workerd) environment.
|
|
6
|
+
*
|
|
7
|
+
* Wraps `cloudflareTest` from `@cloudflare/vitest-pool-workers` and applies Stratal-specific
|
|
8
|
+
* defaults: tslib alias for tsyringe, ZenStack language mocks, and SSR externals config.
|
|
9
|
+
*
|
|
10
|
+
* @param options - Same options as `cloudflareTest()` from `@cloudflare/vitest-pool-workers`
|
|
11
|
+
* @returns An array of Vite plugins
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { stratalTest } from '@stratal/testing/vitest-plugin'
|
|
16
|
+
* import { defineConfig } from 'vitest/config'
|
|
17
|
+
*
|
|
18
|
+
* export default defineConfig({
|
|
19
|
+
* plugins: [stratalTest({ wrangler: { configPath: './wrangler.jsonc' } })],
|
|
20
|
+
* test: {
|
|
21
|
+
* include: ['test/e2e/**\/*.spec.ts'],
|
|
22
|
+
* },
|
|
23
|
+
* })
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function stratalTest(options?: CloudflareTestOptions): Plugin[];
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=stratal-test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stratal-test.d.ts","sourceRoot":"","sources":["../../src/vitest-plugin/stratal-test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAChE,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,MAAM,CAAA;AAE9C,KAAK,qBAAqB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA;AAEjE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,qBAA0B,GAAG,MAAM,EAAE,CAwBzE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { cloudflareTest } from '@cloudflare/vitest-pool-workers';
|
|
2
|
+
/**
|
|
3
|
+
* Unified Vite plugin for Stratal tests running in the Cloudflare Workers (workerd) environment.
|
|
4
|
+
*
|
|
5
|
+
* Wraps `cloudflareTest` from `@cloudflare/vitest-pool-workers` and applies Stratal-specific
|
|
6
|
+
* defaults: tslib alias for tsyringe, ZenStack language mocks, and SSR externals config.
|
|
7
|
+
*
|
|
8
|
+
* @param options - Same options as `cloudflareTest()` from `@cloudflare/vitest-pool-workers`
|
|
9
|
+
* @returns An array of Vite plugins
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { stratalTest } from '@stratal/testing/vitest-plugin'
|
|
14
|
+
* import { defineConfig } from 'vitest/config'
|
|
15
|
+
*
|
|
16
|
+
* export default defineConfig({
|
|
17
|
+
* plugins: [stratalTest({ wrangler: { configPath: './wrangler.jsonc' } })],
|
|
18
|
+
* test: {
|
|
19
|
+
* include: ['test/e2e/**\/*.spec.ts'],
|
|
20
|
+
* },
|
|
21
|
+
* })
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function stratalTest(options = {}) {
|
|
25
|
+
const cfPlugin = cloudflareTest(options);
|
|
26
|
+
const stratalPlugin = {
|
|
27
|
+
name: 'stratal-test',
|
|
28
|
+
config() {
|
|
29
|
+
return {
|
|
30
|
+
resolve: {
|
|
31
|
+
alias: {
|
|
32
|
+
tslib: 'tsyringe/node_modules/tslib/tslib.es6.js',
|
|
33
|
+
'@zenstackhq/language/ast': '@stratal/testing/mocks/zenstack-language',
|
|
34
|
+
'@zenstackhq/language/utils': '@stratal/testing/mocks/zenstack-language',
|
|
35
|
+
'@zenstackhq/language': '@stratal/testing/mocks/zenstack-language',
|
|
36
|
+
nodemailer: '@stratal/testing/mocks/nodemailer',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
ssr: {
|
|
40
|
+
noExternal: ['@zenstackhq/better-auth'],
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
return [cfPlugin, stratalPlugin];
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=stratal-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stratal-test.js","sourceRoot":"","sources":["../../src/vitest-plugin/stratal-test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAKhE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,WAAW,CAAC,UAAiC,EAAE;IAC7D,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;IAExC,MAAM,aAAa,GAAW;QAC5B,IAAI,EAAE,cAAc;QACpB,MAAM;YACJ,OAAO;gBACL,OAAO,EAAE;oBACP,KAAK,EAAE;wBACL,KAAK,EAAE,0CAA0C;wBACjD,0BAA0B,EAAE,0CAA0C;wBACtE,4BAA4B,EAAE,0CAA0C;wBACxE,sBAAsB,EAAE,0CAA0C;wBAClE,UAAU,EAAE,mCAAmC;qBAChD;iBACF;gBACD,GAAG,EAAE;oBACH,UAAU,EAAE,CAAC,yBAAyB,CAAC;iBACxC;aACmB,CAAA;QACxB,CAAC;KACF,CAAA;IAED,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAA;AAClC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stratal/testing",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "Testing utilities and mocks for Stratal framework applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -48,6 +48,10 @@
|
|
|
48
48
|
"./mocks/zenstack-language": {
|
|
49
49
|
"types": "./dist/mocks/zenstack-language.d.ts",
|
|
50
50
|
"import": "./dist/mocks/zenstack-language.js"
|
|
51
|
+
},
|
|
52
|
+
"./vitest-plugin": {
|
|
53
|
+
"types": "./dist/vitest-plugin/index.d.ts",
|
|
54
|
+
"import": "./dist/vitest-plugin/index.js"
|
|
51
55
|
}
|
|
52
56
|
},
|
|
53
57
|
"scripts": {
|
|
@@ -57,13 +61,15 @@
|
|
|
57
61
|
"lint:fix": "npx eslint --fix ."
|
|
58
62
|
},
|
|
59
63
|
"dependencies": {
|
|
60
|
-
"@
|
|
64
|
+
"@cloudflare/vitest-pool-workers": "patch:@cloudflare/vitest-pool-workers@npm%3A0.13.0#~/.yarn/patches/@cloudflare-vitest-pool-workers-npm-0.13.0-47105599c6.patch",
|
|
65
|
+
"@golevelup/ts-vitest": "^2.2.0",
|
|
66
|
+
"msw": "^2.12.10"
|
|
61
67
|
},
|
|
62
68
|
"peerDependencies": {
|
|
63
|
-
"@stratal/framework": "^0.0.
|
|
69
|
+
"@stratal/framework": "^0.0.12",
|
|
64
70
|
"better-auth": "^1.4.9",
|
|
65
|
-
"stratal": "^0.0.
|
|
66
|
-
"vitest": "^
|
|
71
|
+
"stratal": "^0.0.12",
|
|
72
|
+
"vitest": "^4.1.0"
|
|
67
73
|
},
|
|
68
74
|
"peerDependenciesMeta": {
|
|
69
75
|
"@stratal/framework": {
|
|
@@ -74,13 +80,14 @@
|
|
|
74
80
|
}
|
|
75
81
|
},
|
|
76
82
|
"devDependencies": {
|
|
77
|
-
"@cloudflare/
|
|
78
|
-
"@cloudflare/workers-types": "4.20260307.1",
|
|
83
|
+
"@cloudflare/workers-types": "4.20260313.1",
|
|
79
84
|
"@stratal/framework": "workspace:*",
|
|
80
|
-
"@types/node": "^25.
|
|
81
|
-
"
|
|
85
|
+
"@types/node": "^25.5.0",
|
|
86
|
+
"@vitest/runner": "~4.1.0",
|
|
87
|
+
"@vitest/snapshot": "~4.1.0",
|
|
88
|
+
"better-auth": "^1.5.5",
|
|
82
89
|
"stratal": "workspace:*",
|
|
83
90
|
"typescript": "^5.9.3",
|
|
84
|
-
"vitest": "~
|
|
91
|
+
"vitest": "~4.1.0"
|
|
85
92
|
}
|
|
86
93
|
}
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
import type { MockJsonOptions, MockErrorOptions } from './fetch-mock.types';
|
|
2
|
-
/**
|
|
3
|
-
* Wrapper around Cloudflare's fetchMock for declarative fetch mocking in tests
|
|
4
|
-
*
|
|
5
|
-
* Based on undici's MockAgent, fetchMock.get(origin) returns a MockPool for that origin.
|
|
6
|
-
* The MockPool's intercept() method is used to define which requests to mock.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```typescript
|
|
10
|
-
* import { createFetchMock } from '@stratal/testing'
|
|
11
|
-
*
|
|
12
|
-
* const mock = createFetchMock()
|
|
13
|
-
*
|
|
14
|
-
* beforeEach(() => {
|
|
15
|
-
* mock.activate()
|
|
16
|
-
* mock.disableNetConnect()
|
|
17
|
-
* })
|
|
18
|
-
*
|
|
19
|
-
* afterEach(() => {
|
|
20
|
-
* mock.reset()
|
|
21
|
-
* })
|
|
22
|
-
*
|
|
23
|
-
* it('should mock external API', async () => {
|
|
24
|
-
* // Using helper method
|
|
25
|
-
* mock.mockJsonResponse('https://api.example.com/data', { success: true })
|
|
26
|
-
*
|
|
27
|
-
* // Or using direct API
|
|
28
|
-
* mock.get('https://api.example.com')
|
|
29
|
-
* .intercept({ path: '/users', method: 'POST' })
|
|
30
|
-
* .reply(201, JSON.stringify({ created: true }))
|
|
31
|
-
*
|
|
32
|
-
* const response = await fetch('https://api.example.com/data')
|
|
33
|
-
* const json = await response.json()
|
|
34
|
-
*
|
|
35
|
-
* expect(json.success).toBe(true)
|
|
36
|
-
* mock.assertNoPendingInterceptors()
|
|
37
|
-
* })
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
export declare class FetchMock {
|
|
41
|
-
/**
|
|
42
|
-
* Get a MockPool for the specified origin
|
|
43
|
-
*
|
|
44
|
-
* This is the underlying fetchMock.get() method that returns a MockPool
|
|
45
|
-
* for mocking requests to the specified origin.
|
|
46
|
-
*
|
|
47
|
-
* @param origin - The origin URL (e.g., 'https://api.example.com')
|
|
48
|
-
* @returns MockPool for chaining .intercept() and .reply()
|
|
49
|
-
*
|
|
50
|
-
* @example
|
|
51
|
-
* ```typescript
|
|
52
|
-
* // Mock a GET request
|
|
53
|
-
* mock.get('https://api.example.com')
|
|
54
|
-
* .intercept({ path: '/users', method: 'GET' })
|
|
55
|
-
* .reply(200, JSON.stringify({ users: [] }))
|
|
56
|
-
*
|
|
57
|
-
* // Mock a POST request with body matching
|
|
58
|
-
* mock.get('https://api.example.com')
|
|
59
|
-
* .intercept({
|
|
60
|
-
* path: '/users',
|
|
61
|
-
* method: 'POST',
|
|
62
|
-
* body: (body) => body.includes('test')
|
|
63
|
-
* })
|
|
64
|
-
* .reply(201, JSON.stringify({ created: true }))
|
|
65
|
-
* ```
|
|
66
|
-
*/
|
|
67
|
-
get(origin: string): import("cloudflare:test").Interceptable;
|
|
68
|
-
/**
|
|
69
|
-
* Activate fetch mocking for the current test
|
|
70
|
-
*
|
|
71
|
-
* @example
|
|
72
|
-
* ```typescript
|
|
73
|
-
* beforeEach(() => {
|
|
74
|
-
* mock.activate()
|
|
75
|
-
* })
|
|
76
|
-
* ```
|
|
77
|
-
*/
|
|
78
|
-
activate(): void;
|
|
79
|
-
/**
|
|
80
|
-
* Deactivate fetch mocking
|
|
81
|
-
*/
|
|
82
|
-
deactivate(): void;
|
|
83
|
-
/**
|
|
84
|
-
* Disable all network connections, forcing all requests to use mocks
|
|
85
|
-
*
|
|
86
|
-
* @example
|
|
87
|
-
* ```typescript
|
|
88
|
-
* beforeEach(() => {
|
|
89
|
-
* mock.activate()
|
|
90
|
-
* mock.disableNetConnect() // Ensure all requests are mocked
|
|
91
|
-
* })
|
|
92
|
-
* ```
|
|
93
|
-
*/
|
|
94
|
-
disableNetConnect(): void;
|
|
95
|
-
/**
|
|
96
|
-
* Enable network connections for specific hosts
|
|
97
|
-
*
|
|
98
|
-
* @example
|
|
99
|
-
* ```typescript
|
|
100
|
-
* mock.enableNetConnect('localhost')
|
|
101
|
-
* mock.enableNetConnect(/^https:\/\/trusted\.com/)
|
|
102
|
-
* ```
|
|
103
|
-
*/
|
|
104
|
-
enableNetConnect(host?: string | RegExp): void;
|
|
105
|
-
/**
|
|
106
|
-
* Assert that all defined interceptors were called
|
|
107
|
-
*
|
|
108
|
-
* @throws {Error} If there are pending interceptors that weren't matched
|
|
109
|
-
*
|
|
110
|
-
* @example
|
|
111
|
-
* ```typescript
|
|
112
|
-
* it('should call all mocked endpoints', async () => {
|
|
113
|
-
* mock.mockJsonResponse('https://api.example.com/data', { data: [] })
|
|
114
|
-
*
|
|
115
|
-
* await fetch('https://api.example.com/data')
|
|
116
|
-
*
|
|
117
|
-
* mock.assertNoPendingInterceptors() // Pass
|
|
118
|
-
* })
|
|
119
|
-
* ```
|
|
120
|
-
*/
|
|
121
|
-
assertNoPendingInterceptors(): void;
|
|
122
|
-
/**
|
|
123
|
-
* Reset all mocks and interceptors
|
|
124
|
-
*
|
|
125
|
-
* @example
|
|
126
|
-
* ```typescript
|
|
127
|
-
* afterEach(() => {
|
|
128
|
-
* mock.reset()
|
|
129
|
-
* })
|
|
130
|
-
* ```
|
|
131
|
-
*/
|
|
132
|
-
reset(): void;
|
|
133
|
-
/**
|
|
134
|
-
* Helper method to mock JSON responses
|
|
135
|
-
*
|
|
136
|
-
* Automatically parses the URL into origin and path, and sets up the mock.
|
|
137
|
-
*
|
|
138
|
-
* @param url - Full URL to mock (e.g., 'https://api.example.com/users')
|
|
139
|
-
* @param data - JSON data to return
|
|
140
|
-
* @param options - Additional options for the mock
|
|
141
|
-
*
|
|
142
|
-
* @example
|
|
143
|
-
* ```typescript
|
|
144
|
-
* // Mock a GET request
|
|
145
|
-
* mock.mockJsonResponse('https://api.example.com/users', { users: [] })
|
|
146
|
-
*
|
|
147
|
-
* // Mock a POST request
|
|
148
|
-
* mock.mockJsonResponse(
|
|
149
|
-
* 'https://api.example.com/users',
|
|
150
|
-
* { created: true },
|
|
151
|
-
* { method: 'POST', status: 201 }
|
|
152
|
-
* )
|
|
153
|
-
*
|
|
154
|
-
* // With custom headers and delay
|
|
155
|
-
* mock.mockJsonResponse(
|
|
156
|
-
* 'https://api.example.com/users',
|
|
157
|
-
* { users: [] },
|
|
158
|
-
* {
|
|
159
|
-
* status: 200,
|
|
160
|
-
* method: 'GET',
|
|
161
|
-
* headers: { 'X-Custom': 'value' },
|
|
162
|
-
* delay: 100
|
|
163
|
-
* }
|
|
164
|
-
* )
|
|
165
|
-
* ```
|
|
166
|
-
*/
|
|
167
|
-
mockJsonResponse(url: string, data: unknown, options?: MockJsonOptions): import("cloudflare:test").MockScope<object>;
|
|
168
|
-
/**
|
|
169
|
-
* Helper method to mock error responses
|
|
170
|
-
*
|
|
171
|
-
* @param url - Full URL to mock
|
|
172
|
-
* @param status - HTTP error status code
|
|
173
|
-
* @param message - Optional error message
|
|
174
|
-
* @param options - Additional options for the error mock
|
|
175
|
-
*
|
|
176
|
-
* @example
|
|
177
|
-
* ```typescript
|
|
178
|
-
* // Mock a 401 error
|
|
179
|
-
* mock.mockError('https://api.example.com/fail', 401, 'Unauthorized')
|
|
180
|
-
*
|
|
181
|
-
* // Mock a 500 error with custom method
|
|
182
|
-
* mock.mockError(
|
|
183
|
-
* 'https://api.example.com/fail',
|
|
184
|
-
* 500,
|
|
185
|
-
* 'Server Error',
|
|
186
|
-
* { method: 'POST' }
|
|
187
|
-
* )
|
|
188
|
-
* ```
|
|
189
|
-
*/
|
|
190
|
-
mockError(url: string, status: number, message?: string, options?: MockErrorOptions): import("cloudflare:test").MockScope<object>;
|
|
191
|
-
/**
|
|
192
|
-
* Generic helper to mock any HTTP request
|
|
193
|
-
*
|
|
194
|
-
* @param origin - The origin URL (e.g., 'https://api.example.com')
|
|
195
|
-
* @param options - Request matching and response options
|
|
196
|
-
*
|
|
197
|
-
* @example
|
|
198
|
-
* ```typescript
|
|
199
|
-
* mock.mockRequest('https://api.example.com', {
|
|
200
|
-
* path: '/users',
|
|
201
|
-
* method: 'PUT',
|
|
202
|
-
* status: 200,
|
|
203
|
-
* body: { updated: true }
|
|
204
|
-
* })
|
|
205
|
-
* ```
|
|
206
|
-
*/
|
|
207
|
-
mockRequest(origin: string, options: {
|
|
208
|
-
path: string;
|
|
209
|
-
method?: string;
|
|
210
|
-
status?: number;
|
|
211
|
-
body?: unknown;
|
|
212
|
-
}): import("cloudflare:test").MockScope<object>;
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Factory function to create a new FetchMock instance
|
|
216
|
-
*
|
|
217
|
-
* @returns A new FetchMock instance
|
|
218
|
-
*
|
|
219
|
-
* @example
|
|
220
|
-
* ```typescript
|
|
221
|
-
* import { createFetchMock } from '@stratal/testing'
|
|
222
|
-
*
|
|
223
|
-
* const mock = createFetchMock()
|
|
224
|
-
*
|
|
225
|
-
* beforeEach(() => {
|
|
226
|
-
* mock.activate()
|
|
227
|
-
* mock.disableNetConnect()
|
|
228
|
-
* })
|
|
229
|
-
*
|
|
230
|
-
* afterEach(() => {
|
|
231
|
-
* mock.reset()
|
|
232
|
-
* })
|
|
233
|
-
* ```
|
|
234
|
-
*/
|
|
235
|
-
export declare function createFetchMock(): FetchMock;
|
|
236
|
-
//# sourceMappingURL=fetch-mock.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-mock.d.ts","sourceRoot":"","sources":["../../../src/core/http/fetch-mock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAE3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,qBAAa,SAAS;IACrB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM;IAIlB;;;;;;;;;OASG;IACH,QAAQ;IAIR;;OAEG;IACH,UAAU;IAIV;;;;;;;;;;OAUG;IACH,iBAAiB;IAIjB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAOvC;;;;;;;;;;;;;;;OAeG;IACH,2BAA2B;IAI3B;;;;;;;;;OASG;IACH,KAAK;IAKL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,eAAoB;IAwB1E;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAkBvF;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CACV,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE;CAS5E;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,IAAI,SAAS,CAE3C"}
|
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
import { fetchMock } from 'cloudflare:test';
|
|
2
|
-
/**
|
|
3
|
-
* Wrapper around Cloudflare's fetchMock for declarative fetch mocking in tests
|
|
4
|
-
*
|
|
5
|
-
* Based on undici's MockAgent, fetchMock.get(origin) returns a MockPool for that origin.
|
|
6
|
-
* The MockPool's intercept() method is used to define which requests to mock.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```typescript
|
|
10
|
-
* import { createFetchMock } from '@stratal/testing'
|
|
11
|
-
*
|
|
12
|
-
* const mock = createFetchMock()
|
|
13
|
-
*
|
|
14
|
-
* beforeEach(() => {
|
|
15
|
-
* mock.activate()
|
|
16
|
-
* mock.disableNetConnect()
|
|
17
|
-
* })
|
|
18
|
-
*
|
|
19
|
-
* afterEach(() => {
|
|
20
|
-
* mock.reset()
|
|
21
|
-
* })
|
|
22
|
-
*
|
|
23
|
-
* it('should mock external API', async () => {
|
|
24
|
-
* // Using helper method
|
|
25
|
-
* mock.mockJsonResponse('https://api.example.com/data', { success: true })
|
|
26
|
-
*
|
|
27
|
-
* // Or using direct API
|
|
28
|
-
* mock.get('https://api.example.com')
|
|
29
|
-
* .intercept({ path: '/users', method: 'POST' })
|
|
30
|
-
* .reply(201, JSON.stringify({ created: true }))
|
|
31
|
-
*
|
|
32
|
-
* const response = await fetch('https://api.example.com/data')
|
|
33
|
-
* const json = await response.json()
|
|
34
|
-
*
|
|
35
|
-
* expect(json.success).toBe(true)
|
|
36
|
-
* mock.assertNoPendingInterceptors()
|
|
37
|
-
* })
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
export class FetchMock {
|
|
41
|
-
/**
|
|
42
|
-
* Get a MockPool for the specified origin
|
|
43
|
-
*
|
|
44
|
-
* This is the underlying fetchMock.get() method that returns a MockPool
|
|
45
|
-
* for mocking requests to the specified origin.
|
|
46
|
-
*
|
|
47
|
-
* @param origin - The origin URL (e.g., 'https://api.example.com')
|
|
48
|
-
* @returns MockPool for chaining .intercept() and .reply()
|
|
49
|
-
*
|
|
50
|
-
* @example
|
|
51
|
-
* ```typescript
|
|
52
|
-
* // Mock a GET request
|
|
53
|
-
* mock.get('https://api.example.com')
|
|
54
|
-
* .intercept({ path: '/users', method: 'GET' })
|
|
55
|
-
* .reply(200, JSON.stringify({ users: [] }))
|
|
56
|
-
*
|
|
57
|
-
* // Mock a POST request with body matching
|
|
58
|
-
* mock.get('https://api.example.com')
|
|
59
|
-
* .intercept({
|
|
60
|
-
* path: '/users',
|
|
61
|
-
* method: 'POST',
|
|
62
|
-
* body: (body) => body.includes('test')
|
|
63
|
-
* })
|
|
64
|
-
* .reply(201, JSON.stringify({ created: true }))
|
|
65
|
-
* ```
|
|
66
|
-
*/
|
|
67
|
-
get(origin) {
|
|
68
|
-
return fetchMock.get(origin);
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Activate fetch mocking for the current test
|
|
72
|
-
*
|
|
73
|
-
* @example
|
|
74
|
-
* ```typescript
|
|
75
|
-
* beforeEach(() => {
|
|
76
|
-
* mock.activate()
|
|
77
|
-
* })
|
|
78
|
-
* ```
|
|
79
|
-
*/
|
|
80
|
-
activate() {
|
|
81
|
-
fetchMock.activate();
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Deactivate fetch mocking
|
|
85
|
-
*/
|
|
86
|
-
deactivate() {
|
|
87
|
-
fetchMock.deactivate();
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Disable all network connections, forcing all requests to use mocks
|
|
91
|
-
*
|
|
92
|
-
* @example
|
|
93
|
-
* ```typescript
|
|
94
|
-
* beforeEach(() => {
|
|
95
|
-
* mock.activate()
|
|
96
|
-
* mock.disableNetConnect() // Ensure all requests are mocked
|
|
97
|
-
* })
|
|
98
|
-
* ```
|
|
99
|
-
*/
|
|
100
|
-
disableNetConnect() {
|
|
101
|
-
fetchMock.disableNetConnect();
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Enable network connections for specific hosts
|
|
105
|
-
*
|
|
106
|
-
* @example
|
|
107
|
-
* ```typescript
|
|
108
|
-
* mock.enableNetConnect('localhost')
|
|
109
|
-
* mock.enableNetConnect(/^https:\/\/trusted\.com/)
|
|
110
|
-
* ```
|
|
111
|
-
*/
|
|
112
|
-
enableNetConnect(host) {
|
|
113
|
-
if (host) {
|
|
114
|
-
fetchMock.enableNetConnect(host);
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
fetchMock.enableNetConnect();
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Assert that all defined interceptors were called
|
|
121
|
-
*
|
|
122
|
-
* @throws {Error} If there are pending interceptors that weren't matched
|
|
123
|
-
*
|
|
124
|
-
* @example
|
|
125
|
-
* ```typescript
|
|
126
|
-
* it('should call all mocked endpoints', async () => {
|
|
127
|
-
* mock.mockJsonResponse('https://api.example.com/data', { data: [] })
|
|
128
|
-
*
|
|
129
|
-
* await fetch('https://api.example.com/data')
|
|
130
|
-
*
|
|
131
|
-
* mock.assertNoPendingInterceptors() // Pass
|
|
132
|
-
* })
|
|
133
|
-
* ```
|
|
134
|
-
*/
|
|
135
|
-
assertNoPendingInterceptors() {
|
|
136
|
-
fetchMock.assertNoPendingInterceptors();
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Reset all mocks and interceptors
|
|
140
|
-
*
|
|
141
|
-
* @example
|
|
142
|
-
* ```typescript
|
|
143
|
-
* afterEach(() => {
|
|
144
|
-
* mock.reset()
|
|
145
|
-
* })
|
|
146
|
-
* ```
|
|
147
|
-
*/
|
|
148
|
-
reset() {
|
|
149
|
-
// Reset by deactivating
|
|
150
|
-
fetchMock.deactivate();
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Helper method to mock JSON responses
|
|
154
|
-
*
|
|
155
|
-
* Automatically parses the URL into origin and path, and sets up the mock.
|
|
156
|
-
*
|
|
157
|
-
* @param url - Full URL to mock (e.g., 'https://api.example.com/users')
|
|
158
|
-
* @param data - JSON data to return
|
|
159
|
-
* @param options - Additional options for the mock
|
|
160
|
-
*
|
|
161
|
-
* @example
|
|
162
|
-
* ```typescript
|
|
163
|
-
* // Mock a GET request
|
|
164
|
-
* mock.mockJsonResponse('https://api.example.com/users', { users: [] })
|
|
165
|
-
*
|
|
166
|
-
* // Mock a POST request
|
|
167
|
-
* mock.mockJsonResponse(
|
|
168
|
-
* 'https://api.example.com/users',
|
|
169
|
-
* { created: true },
|
|
170
|
-
* { method: 'POST', status: 201 }
|
|
171
|
-
* )
|
|
172
|
-
*
|
|
173
|
-
* // With custom headers and delay
|
|
174
|
-
* mock.mockJsonResponse(
|
|
175
|
-
* 'https://api.example.com/users',
|
|
176
|
-
* { users: [] },
|
|
177
|
-
* {
|
|
178
|
-
* status: 200,
|
|
179
|
-
* method: 'GET',
|
|
180
|
-
* headers: { 'X-Custom': 'value' },
|
|
181
|
-
* delay: 100
|
|
182
|
-
* }
|
|
183
|
-
* )
|
|
184
|
-
* ```
|
|
185
|
-
*/
|
|
186
|
-
mockJsonResponse(url, data, options = {}) {
|
|
187
|
-
const parsedUrl = new URL(url);
|
|
188
|
-
const origin = `${parsedUrl.protocol}//${parsedUrl.host}`;
|
|
189
|
-
const path = options.path ?? parsedUrl.pathname;
|
|
190
|
-
const method = options.method ?? 'GET';
|
|
191
|
-
const { status = 200, headers = {}, delay } = options;
|
|
192
|
-
const defaultHeaders = {
|
|
193
|
-
'Content-Type': 'application/json',
|
|
194
|
-
...headers,
|
|
195
|
-
};
|
|
196
|
-
const mock = fetchMock
|
|
197
|
-
.get(origin)
|
|
198
|
-
.intercept({ path, method })
|
|
199
|
-
.reply(status, JSON.stringify(data), { headers: defaultHeaders });
|
|
200
|
-
if (delay) {
|
|
201
|
-
return mock.delay(delay);
|
|
202
|
-
}
|
|
203
|
-
return mock;
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Helper method to mock error responses
|
|
207
|
-
*
|
|
208
|
-
* @param url - Full URL to mock
|
|
209
|
-
* @param status - HTTP error status code
|
|
210
|
-
* @param message - Optional error message
|
|
211
|
-
* @param options - Additional options for the error mock
|
|
212
|
-
*
|
|
213
|
-
* @example
|
|
214
|
-
* ```typescript
|
|
215
|
-
* // Mock a 401 error
|
|
216
|
-
* mock.mockError('https://api.example.com/fail', 401, 'Unauthorized')
|
|
217
|
-
*
|
|
218
|
-
* // Mock a 500 error with custom method
|
|
219
|
-
* mock.mockError(
|
|
220
|
-
* 'https://api.example.com/fail',
|
|
221
|
-
* 500,
|
|
222
|
-
* 'Server Error',
|
|
223
|
-
* { method: 'POST' }
|
|
224
|
-
* )
|
|
225
|
-
* ```
|
|
226
|
-
*/
|
|
227
|
-
mockError(url, status, message, options = {}) {
|
|
228
|
-
const parsedUrl = new URL(url);
|
|
229
|
-
const origin = `${parsedUrl.protocol}//${parsedUrl.host}`;
|
|
230
|
-
const path = options.path ?? parsedUrl.pathname;
|
|
231
|
-
const method = options.method ?? 'GET';
|
|
232
|
-
const { headers = {} } = options;
|
|
233
|
-
const body = message ? JSON.stringify({ error: message }) : '';
|
|
234
|
-
const responseHeaders = message
|
|
235
|
-
? { 'Content-Type': 'application/json', ...headers }
|
|
236
|
-
: headers;
|
|
237
|
-
return fetchMock
|
|
238
|
-
.get(origin)
|
|
239
|
-
.intercept({ path, method })
|
|
240
|
-
.reply(status, body, { headers: responseHeaders });
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* Generic helper to mock any HTTP request
|
|
244
|
-
*
|
|
245
|
-
* @param origin - The origin URL (e.g., 'https://api.example.com')
|
|
246
|
-
* @param options - Request matching and response options
|
|
247
|
-
*
|
|
248
|
-
* @example
|
|
249
|
-
* ```typescript
|
|
250
|
-
* mock.mockRequest('https://api.example.com', {
|
|
251
|
-
* path: '/users',
|
|
252
|
-
* method: 'PUT',
|
|
253
|
-
* status: 200,
|
|
254
|
-
* body: { updated: true }
|
|
255
|
-
* })
|
|
256
|
-
* ```
|
|
257
|
-
*/
|
|
258
|
-
mockRequest(origin, options) {
|
|
259
|
-
const { path, method = 'GET', status = 200, body } = options;
|
|
260
|
-
return fetchMock
|
|
261
|
-
.get(origin)
|
|
262
|
-
.intercept({ path, method })
|
|
263
|
-
.reply(status, body ? JSON.stringify(body) : '');
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Factory function to create a new FetchMock instance
|
|
268
|
-
*
|
|
269
|
-
* @returns A new FetchMock instance
|
|
270
|
-
*
|
|
271
|
-
* @example
|
|
272
|
-
* ```typescript
|
|
273
|
-
* import { createFetchMock } from '@stratal/testing'
|
|
274
|
-
*
|
|
275
|
-
* const mock = createFetchMock()
|
|
276
|
-
*
|
|
277
|
-
* beforeEach(() => {
|
|
278
|
-
* mock.activate()
|
|
279
|
-
* mock.disableNetConnect()
|
|
280
|
-
* })
|
|
281
|
-
*
|
|
282
|
-
* afterEach(() => {
|
|
283
|
-
* mock.reset()
|
|
284
|
-
* })
|
|
285
|
-
* ```
|
|
286
|
-
*/
|
|
287
|
-
export function createFetchMock() {
|
|
288
|
-
return new FetchMock();
|
|
289
|
-
}
|
|
290
|
-
//# sourceMappingURL=fetch-mock.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-mock.js","sourceRoot":"","sources":["../../../src/core/http/fetch-mock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAG3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,OAAO,SAAS;IACrB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,GAAG,CAAC,MAAc;QACjB,OAAO,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC;IAED;;;;;;;;;OASG;IACH,QAAQ;QACP,SAAS,CAAC,QAAQ,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,UAAU;QACT,SAAS,CAAC,UAAU,EAAE,CAAC;IACxB,CAAC;IAED;;;;;;;;;;OAUG;IACH,iBAAiB;QAChB,SAAS,CAAC,iBAAiB,EAAE,CAAC;IAC/B,CAAC;IAED;;;;;;;;OAQG;IACH,gBAAgB,CAAC,IAAsB;QACtC,IAAI,IAAI,EAAE,CAAC;YACV,SAAS,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAAC,OAAO;QAC1C,CAAC;QACD,SAAS,CAAC,gBAAgB,EAAE,CAAC;IAC9B,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,2BAA2B;QAC1B,SAAS,CAAC,2BAA2B,EAAE,CAAC;IACzC,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK;QACJ,wBAAwB;QACxB,SAAS,CAAC,UAAU,EAAE,CAAA;IACvB,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,gBAAgB,CAAC,GAAW,EAAE,IAAa,EAAE,UAA2B,EAAE;QACzE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QAC9B,MAAM,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,KAAK,SAAS,CAAC,IAAI,EAAE,CAAA;QACzD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC,QAAQ,CAAA;QAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAA;QACtC,MAAM,EAAE,MAAM,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;QAErD,MAAM,cAAc,GAAG;YACtB,cAAc,EAAE,kBAAkB;YAClC,GAAG,OAAO;SACV,CAAA;QAED,MAAM,IAAI,GAAG,SAAS;aACpB,GAAG,CAAC,MAAM,CAAC;aACX,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;aAC3B,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAA;QAElE,IAAI,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACzB,CAAC;QAED,OAAO,IAAI,CAAA;IACZ,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,SAAS,CAAC,GAAW,EAAE,MAAc,EAAE,OAAgB,EAAE,UAA4B,EAAE;QACtF,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QAC9B,MAAM,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,KAAK,SAAS,CAAC,IAAI,EAAE,CAAA;QACzD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC,QAAQ,CAAA;QAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAA;QACtC,MAAM,EAAE,OAAO,GAAG,EAAE,EAAE,GAAG,OAAO,CAAA;QAEhC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAC9D,MAAM,eAAe,GAAG,OAAO;YAC9B,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,OAAO,EAAE;YACpD,CAAC,CAAC,OAAO,CAAA;QAEV,OAAO,SAAS;aACd,GAAG,CAAC,MAAM,CAAC;aACX,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;aAC3B,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAA;IACpD,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CACV,MAAc,EACd,OAA2E;QAE3E,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,OAAO,CAAA;QAE5D,OAAO,SAAS;aACd,GAAG,CAAC,MAAM,CAAC;aACX,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;aAC3B,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAClD,CAAC;CACD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,eAAe;IAC9B,OAAO,IAAI,SAAS,EAAE,CAAA;AACvB,CAAC"}
|