Skip to content

Commit 2f9b7be

Browse files
committed
fix: preserve strictOverride in 404 journal entries
Also update recorder test to match new strict-before-proxy semantics and add test verifying strict header prevents proxy in record mode.
1 parent cd7ed8b commit 2f9b7be

18 files changed

Lines changed: 39 additions & 3 deletions

src/__tests__/recorder.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ describe("recorder strict mode", () => {
692692
expect(body.error.message).toBe("Strict mode: no fixture matched");
693693
});
694694

695-
it("record + strict: proxy succeeds when upstream is available", async () => {
695+
it("record + strict: strict blocks proxy even when upstream is available", async () => {
696696
await setupUpstreamAndRecorder([
697697
{
698698
match: { userMessage: "hello" },
@@ -714,14 +714,15 @@ describe("recorder strict mode", () => {
714714
record: { providers: { openai: upstream!.url }, fixturePath: tmpDir },
715715
});
716716

717+
// Strict mode now takes precedence over proxy — returns 503
717718
const resp = await post(`${recorder.url}/v1/chat/completions`, {
718719
model: "gpt-4",
719720
messages: [{ role: "user", content: "hello" }],
720721
});
721722

722-
expect(resp.status).toBe(200);
723+
expect(resp.status).toBe(503);
723724
const body = JSON.parse(resp.body);
724-
expect(body.choices[0].message.content).toBe("world");
725+
expect(body.error.message).toBe("Strict mode: no fixture matched");
725726
});
726727
});
727728

src/__tests__/strict-header.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,19 @@ describe("X-AIMock-Strict header integration", () => {
219219
expect(entries.length).toBe(1);
220220
expect(entries[0].response.strictOverride).toBe(false);
221221
});
222+
223+
it("strict header prevents proxy in record mode", async () => {
224+
server = await createServer([], {
225+
port: 0,
226+
record: {
227+
providers: { openai: "https://api.openai.com" },
228+
},
229+
});
230+
const res = await httpPost(`${server.url}/v1/chat/completions`, chatRequest("anything"), {
231+
"X-AIMock-Strict": "true",
232+
});
233+
expect(res.status).toBe(503);
234+
const body = JSON.parse(res.body);
235+
expect(body.error.message).toBe("Strict mode: no fixture matched");
236+
});
222237
});

src/bedrock-converse.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,7 @@ export async function handleConverse(
659659
response: {
660660
status: 404,
661661
fixture: null,
662+
...strictOverrideField(defaults.strict, req.headers),
662663
},
663664
});
664665
writeErrorResponse(
@@ -949,6 +950,7 @@ export async function handleConverseStream(
949950
response: {
950951
status: 404,
951952
fixture: null,
953+
...strictOverrideField(defaults.strict, req.headers),
952954
},
953955
});
954956
writeErrorResponse(

src/bedrock.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@ export async function handleBedrock(
487487
response: {
488488
status: 404,
489489
fixture: null,
490+
...strictOverrideField(defaults.strict, req.headers),
490491
},
491492
});
492493
writeErrorResponse(
@@ -1127,6 +1128,7 @@ export async function handleBedrockStream(
11271128
response: {
11281129
status: 404,
11291130
fixture: null,
1131+
...strictOverrideField(defaults.strict, req.headers),
11301132
},
11311133
});
11321134
writeErrorResponse(

src/cohere.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,7 @@ export async function handleCohere(
925925
response: {
926926
status: 404,
927927
fixture: null,
928+
...strictOverrideField(defaults.strict, req.headers),
928929
},
929930
});
930931
writeErrorResponse(

src/elevenlabs-audio.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ export async function handleElevenLabsAudio(
187187
response: {
188188
status: 404,
189189
fixture: null,
190+
...strictOverrideField(defaults.strict, req.headers),
190191
},
191192
});
192193
writeErrorResponse(

src/fal-audio.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ async function handleQueueSubmit(
375375
response: {
376376
status: 404,
377377
fixture: null,
378+
...strictOverrideField(defaults.strict, req.headers),
378379
},
379380
});
380381
res.writeHead(404, { "Content-Type": "application/json" });
@@ -722,6 +723,7 @@ async function handleSyncRun(
722723
response: {
723724
status: 404,
724725
fixture: null,
726+
...strictOverrideField(defaults.strict, req.headers),
725727
},
726728
});
727729
res.writeHead(404, { "Content-Type": "application/json" });

src/fal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ export async function handleFal(
373373
response: {
374374
status: 404,
375375
fixture: null,
376+
...strictOverrideField(defaults.strict, req.headers),
376377
},
377378
});
378379
res.writeHead(404, { "Content-Type": "application/json" });

src/gemini-interactions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,7 @@ export async function handleGeminiInteractions(
764764
response: {
765765
status: 404,
766766
fixture: null,
767+
...strictOverrideField(defaults.strict, req.headers),
767768
},
768769
});
769770
writeErrorResponse(

src/gemini.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,7 @@ export async function handleGemini(
710710
response: {
711711
status: 404,
712712
fixture: null,
713+
...strictOverrideField(defaults.strict, req.headers),
713714
},
714715
});
715716
writeErrorResponse(

0 commit comments

Comments
 (0)