Skip to content

Commit e2de5f1

Browse files
authored
fix: msw lazy delay (#2576)
1 parent bb714b1 commit e2de5f1

File tree

2 files changed

+119
-1
lines changed

2 files changed

+119
-1
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import type { GeneratorOptions, GeneratorVerbOptions } from '@orval/core';
2+
import { describe, expect, it } from 'vitest';
3+
4+
import { generateMSW } from './index';
5+
6+
describe('generateMSW', () => {
7+
const mockVerbOptions: GeneratorVerbOptions = {
8+
operationId: 'getUser',
9+
verb: 'get',
10+
tags: [],
11+
response: {
12+
imports: [],
13+
definition: { success: 'User' },
14+
types: { success: [{ key: '200', value: 'User' }] },
15+
contentTypes: ['application/json'],
16+
},
17+
} as GeneratorVerbOptions;
18+
19+
const baseOptions: GeneratorOptions = {
20+
pathRoute: '/users/{id}',
21+
override: { operations: {}, tags: {} },
22+
context: {
23+
specKey: 'test',
24+
specs: { test: {} },
25+
output: { override: {} },
26+
},
27+
} as GeneratorOptions;
28+
29+
const generate = (overrides: Partial<GeneratorOptions> = {}) =>
30+
generateMSW(mockVerbOptions, { ...baseOptions, ...overrides });
31+
32+
describe('delay functionality', () => {
33+
it('should not include delay call when no delay is provided', () => {
34+
const result = generate();
35+
expect(result.implementation.handler).not.toContain('await delay');
36+
});
37+
38+
it('should include delay call when delay is a number', () => {
39+
const result = generate({ mock: { delay: 100 } });
40+
expect(result.implementation.handler).toContain('await delay(100);');
41+
});
42+
43+
it('should not include delay call when delay is false', () => {
44+
const result = generate({ mock: { delay: false } });
45+
expect(result.implementation.handler).not.toContain('await delay');
46+
});
47+
48+
it('should execute delay function immediately when delayFunctionLazyExecute is false', () => {
49+
const result = generate({
50+
mock: { delay: () => 200, delayFunctionLazyExecute: false },
51+
});
52+
expect(result.implementation.handler).toContain('await delay(200);');
53+
});
54+
55+
it('should preserve delay function when delayFunctionLazyExecute is true', () => {
56+
const result = generate({
57+
mock: {
58+
delay: () => Number(process.env.MSW_DELAY) || 10,
59+
delayFunctionLazyExecute: true,
60+
},
61+
});
62+
expect(result.implementation.handler).toContain(
63+
'await delay((() => Number(process.env.MSW_DELAY) || 10)());',
64+
);
65+
});
66+
67+
it('should handle delay function in override.mock', () => {
68+
const result = generate({
69+
override: {
70+
...baseOptions.override,
71+
mock: { delay: () => 300, delayFunctionLazyExecute: true },
72+
},
73+
});
74+
expect(result.implementation.handler).toContain(
75+
'await delay((() => 300)());',
76+
);
77+
});
78+
79+
it('should prioritize override.mock.delay over options.mock.delay', () => {
80+
const result = generate({
81+
mock: { delay: 100 },
82+
override: { ...baseOptions.override, mock: { delay: 500 } },
83+
});
84+
expect(result.implementation.handler).toContain('await delay(500);');
85+
expect(result.implementation.handler).not.toContain('await delay(100);');
86+
});
87+
88+
it('should prioritize override.mock.delayFunctionLazyExecute', () => {
89+
const result = generate({
90+
mock: { delay: () => 100, delayFunctionLazyExecute: false },
91+
override: {
92+
...baseOptions.override,
93+
mock: { delay: () => 200, delayFunctionLazyExecute: true },
94+
},
95+
});
96+
expect(result.implementation.handler).toContain(
97+
'await delay((() => 200)());',
98+
);
99+
});
100+
});
101+
102+
describe('handler generation', () => {
103+
it('should generate a valid MSW handler', () => {
104+
const result = generate({ mock: { delay: 100 } });
105+
106+
expect(result.implementation.handlerName).toBe('getGetUserMockHandler');
107+
expect(result.implementation.handler).toContain(
108+
'export const getGetUserMockHandler',
109+
);
110+
expect(result.implementation.handler).toContain('return http.get');
111+
expect(result.implementation.handler).toContain(
112+
'return new HttpResponse',
113+
);
114+
});
115+
});
116+
});

packages/mock/src/msw/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ const generateDefinition = (
134134
const handlerImplementation = `
135135
export const ${handlerName} = (overrideResponse?: ${returnType} | ((${infoParam}: Parameters<Parameters<typeof http.${verb}>[1]>[0]) => Promise<${returnType}> | ${returnType}), options?: RequestHandlerOptions) => {
136136
return http.${verb}('${route}', async (${infoParam}) => {${
137-
typeof delay === 'number' ? `await delay(${delay});` : ''
137+
delay === false
138+
? ''
139+
: `await delay(${isFunction(delay) ? `(${delay})()` : delay});`
138140
}
139141
${isReturnHttpResponse ? '' : `if (typeof overrideResponse === 'function') {await overrideResponse(info); }`}
140142
return new HttpResponse(${

0 commit comments

Comments
 (0)