fix(producer): reject unknown codec strings + extract testable preset-override helper

Address @vanceingalls review on #850:

1. Unknown codec strings (typos like 'H265', future additions like 'av1')
   silently fell through to libx264 in resolveEncoderTriple. Add an
   explicit throw symmetric to the non-mp4-format branch already there.
   A JS caller building config from JSON who passes 'codec: "h266"'
   now gets a clear error at plan time instead of unflagged h264 output.

2. The preset.codec override in renderChunk had no fast unit coverage —
   only the heavyweight Docker fixture in #851 would catch a regression
   if someone refactored the spread (e.g. moved it into getEncoderPreset
   itself). Extract resolvePresetForLockedEncoder() and add 4 fast unit
   tests pinning the four encoder shapes (libx265/libx264/prores/png-seq).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
James
2026-05-15 01:57:08 +00:00
committed by James Russo
parent eccea88daf
commit db62e31d39
4 changed files with 92 additions and 7 deletions
@@ -267,4 +267,24 @@ describe("plan() — codec knob", () => {
expect(caught).toBeInstanceOf(Error);
expect((caught as Error).message).toMatch(/codec.*only valid for format="mp4"/);
});
it("rejects unknown codec strings for format=mp4 (no silent fall-through to h264)", async () => {
const planDir = join(runRoot, "plan-codec-unknown");
mkdirSync(planDir, { recursive: true });
let caught: unknown;
try {
await plan(
projectDir,
// @ts-expect-error — runtime check is the test's purpose. Catches
// typos ("H265") and future codec additions ("av1") that a JS
// caller building config from JSON might pass.
{ fps: 30, width: 320, height: 240, format: "mp4", codec: "h266" },
planDir,
);
} catch (err) {
caught = err;
}
expect(caught).toBeInstanceOf(Error);
expect((caught as Error).message).toMatch(/codec must be "h264" or "h265"/);
});
});