Skip to content

Commit eea2d60

Browse files
committed
test: remove implicity failures in auto-mocker
1 parent a03674f commit eea2d60

File tree

3 files changed

+51
-27
lines changed

3 files changed

+51
-27
lines changed

docs/mocks.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ Usage
1212
Regeneration
1313
- Delete a fixture file or run with `AUTO_MOCKER_FORCE=1` to re-generate.
1414

15+
Failure behavior (always strict)
16+
- If a schema is missing or faker fails, the handler responds 500 and does not write a placeholder.
17+
- Invalid fixtures (including empty `{}` when the schema defines properties) respond 500.
18+
1519
Types (optional)
1620
- If you expose OpenAPI response types under `@api/types.gen`, set `USE_TYPES_FOR_FIXTURES = true` in `src/mocks/mocker.ts` to add a `satisfies` clause in generated fixtures.
17-

src/mocks/fixtures/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ Notes
1010
- If your project exposes OpenAPI response types via `@api/types.gen`, you can
1111
enable type enforcement by setting `USE_TYPES_FOR_FIXTURES = true` in
1212
`src/mocks/mocker.ts`.
13-
13+
- Always strict: missing/failed generation returns 500 (no placeholder), and invalid fixtures return 500.

src/mocks/mocker.ts

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ export function autoGenerateHandlers() {
171171

172172
const hasFile = fs.existsSync(fixtureFileName);
173173
if ((FORCE_REGENERATE || !hasFile) && successStatus !== "204") {
174-
let payload: any = {};
174+
let payload: any | undefined;
175175
if (successStatus) {
176176
const schema =
177177
operation.responses?.[successStatus]?.content?.[
@@ -182,41 +182,42 @@ export function autoGenerateHandlers() {
182182
const resolved = derefSchema(schema);
183183
payload = jsf.generate(resolved);
184184
} catch (e) {
185-
console.warn(
185+
console.error(
186186
"[auto-mocker] jsf.generate failed for",
187187
method.toUpperCase(),
188188
rawPath,
189189
e,
190190
);
191191
}
192192
} else {
193-
console.warn(
193+
console.error(
194194
"[auto-mocker] no JSON schema for",
195195
method.toUpperCase(),
196196
rawPath,
197197
"status",
198198
successStatus,
199199
);
200-
payload = {};
201200
}
202201
}
203202

204-
const opType = successStatus
205-
? opResponseTypeName(method, rawPath)
206-
: undefined;
207-
const tsModule = buildMockModule(payload, {
208-
opType,
209-
useTypes: USE_TYPES_FOR_FIXTURES,
210-
});
211-
try {
212-
fs.writeFileSync(fixtureFileName, tsModule);
213-
console.log("[auto-mocker] wrote", fixtureFileName);
214-
} catch (e) {
215-
console.error(
216-
"[auto-mocker] failed to write fixture",
217-
fixtureFileName,
218-
e,
219-
);
203+
if (payload !== undefined) {
204+
const opType = successStatus
205+
? opResponseTypeName(method, rawPath)
206+
: undefined;
207+
const tsModule = buildMockModule(payload, {
208+
opType,
209+
useTypes: USE_TYPES_FOR_FIXTURES,
210+
});
211+
try {
212+
fs.writeFileSync(fixtureFileName, tsModule);
213+
console.log("[auto-mocker] wrote", fixtureFileName);
214+
} catch (e) {
215+
console.error(
216+
"[auto-mocker] failed to write fixture",
217+
fixtureFileName,
218+
e,
219+
);
220+
}
220221
}
221222
}
222223

@@ -237,7 +238,7 @@ export function autoGenerateHandlers() {
237238
}
238239
} catch (e) {
239240
return new HttpResponse(
240-
`Missing mock fixture: ${relPath}. ${e instanceof Error ? e.message : ""}`,
241+
`[auto-mocker] Missing mock fixture: ${relPath}. ${e instanceof Error ? e.message : ""}`,
241242
{ status: 500 },
242243
);
243244
}
@@ -248,13 +249,33 @@ export function autoGenerateHandlers() {
248249
]?.schema;
249250
if (validateSchema) {
250251
const resolved = derefSchema(validateSchema);
251-
const isValid = ajv.validate(resolved, data);
252+
let isValid = ajv.validate(resolved, data);
253+
// Treat empty object as invalid when schema exposes properties.
254+
if (
255+
isValid &&
256+
data &&
257+
typeof data === "object" &&
258+
!Array.isArray(data) &&
259+
Object.keys(data as any).length === 0 &&
260+
(resolved as any)?.properties &&
261+
Object.keys((resolved as any).properties).length > 0
262+
) {
263+
isValid = false;
264+
}
252265
if (!isValid) {
253-
console.error("[auto-mocker] invalid mock response", {
254-
fixtureFileName,
255-
errors: ajv.errors,
266+
const message = `fixture validation failed for ${method.toUpperCase()} ${rawPath} -> ${fixtureFileName}`;
267+
console.error("[auto-mocker]", message, ajv.errors || []);
268+
return new HttpResponse(`[auto-mocker] ${message}`, {
269+
status: 500,
256270
});
257271
}
272+
} else {
273+
// No JSON schema to validate against: explicit failure
274+
const message = `no JSON schema for ${method.toUpperCase()} ${rawPath} status ${successStatus ?? "200"}`;
275+
console.error("[auto-mocker]", message);
276+
return new HttpResponse(`[auto-mocker] ${message}`, {
277+
status: 500,
278+
});
258279
}
259280

260281
return HttpResponse.json(data, {

0 commit comments

Comments
 (0)