@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.
@@ -1,4 +1,4 @@
1
- import { env as cloudflareEnv } from 'cloudflare:test';
1
+ import { env as cloudflareEnv } from 'cloudflare:workers';
2
2
  /**
3
3
  * Get test environment with optional overrides
4
4
  *
@@ -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,iBAAiB,CAAA;AAEtD;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,SAA+B;IACxD,OAAO;QACL,GAAG,aAAa;QAChB,GAAG,SAAS;KACC,CAAA;AACjB,CAAC"}
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 { FetchMock, createFetchMock } from './fetch-mock';
4
+ export { MockFetch, createMockFetch } from './mock-fetch';
5
5
  export type { MockJsonOptions, MockErrorOptions } from './fetch-mock.types';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -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 { FetchMock, createFetchMock } from './fetch-mock';
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,3 +1,4 @@
1
+ import { type Container } from 'stratal/di';
1
2
  import { type InjectionToken } from 'stratal/module';
2
3
  import type { TestingModuleBuilder } from '../testing-module-builder';
3
4
  /**
@@ -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":"AAYA;;;;;;;;;;;;;;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"}
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 { createExecutionContext } from 'cloudflare:test';
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 = createExecutionContext();
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":"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"}
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 { createFetchMock, FetchMock } from './core/http/fetch-mock';
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';
@@ -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 { createFetchMock, FetchMock } from './core/http/fetch-mock';
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,2 @@
1
+ export { stratalTest } from './stratal-test.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -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,2 @@
1
+ export { stratalTest } from './stratal-test.js';
2
+ //# sourceMappingURL=index.js.map
@@ -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.11",
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
- "@golevelup/ts-vitest": "^2.2.0"
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.11",
69
+ "@stratal/framework": "^0.0.12",
64
70
  "better-auth": "^1.4.9",
65
- "stratal": "^0.0.11",
66
- "vitest": "^3.2.0"
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/vitest-pool-workers": "^0.12.20",
78
- "@cloudflare/workers-types": "4.20260307.1",
83
+ "@cloudflare/workers-types": "4.20260313.1",
79
84
  "@stratal/framework": "workspace:*",
80
- "@types/node": "^25.3.5",
81
- "better-auth": "^1.5.4",
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": "~3.2.0"
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":"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"}