Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit 0657e73d75a650fff1646389c838a6ade500dda6
parent 20685d1914f71966f58a9a253c9dddde63ef8277
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Sun, 20 Sep 2026 19:16:17 -0400

Prove a patch spares the fields it does not name

The round-trip assertions only checked name/handling/url, which survive a patch
trivially: parseChannelForm REQUIRES the first two, and the serializer re-posts
the third like any other. None of them exercise the thing that could actually go
wrong — updateChannelAction deletes every CHANNEL_FORM_FIELDS key from the
baseline before layering the parse result on, so a field the patch fails to
re-post is silently CLEARED, not preserved.

So the fixture is seeded with two of those keys and both are asserted after an
unrelated downloadFilter patch, and again after the clear. `keepLatest: 0` is
the sharp one: 0 is the explicit "disabled" sentinel, so a serializer testing
the value for truthiness rather than for null/undefined would drop it and the
channel would silently fall back to inherit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Diffstat:
Meditor/e2e/ops-api.spec.ts | 33+++++++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/editor/e2e/ops-api.spec.ts b/editor/e2e/ops-api.spec.ts @@ -23,6 +23,7 @@ import { readJson, resetData, resolvePath, + writeChannelConfig, writeSettings, } from "./helpers"; @@ -170,8 +171,28 @@ test("channel-config round-trips a download filter and refuses a bad regex", asy await settings(); const SLUG = "test-filter"; const CONFIG = `test-transcripts/channels/${SLUG}/config.json`; + // TWO FIELDS THE CLEAR-THEN-LAYER PATH ACTUALLY THREATENS. name/handling/url + // survive a patch trivially — they are re-posted by the serializer because + // parseChannelForm requires the first two and CHANNEL_FORM_FIELDS spares + // none of the rest. `cookieMode` and `keepLatest` are in CHANNEL_FORM_FIELDS, + // so updateChannelAction deletes them from the baseline before layering, and + // a patch that failed to re-post them would silently clear both. + // + // `keepLatest: 0` is the sharp one: 0 is the explicit "disabled" sentinel, and + // a serializer that tested the value for truthiness rather than for + // null/undefined would drop it and read as "inherit" on the next save. + await writeChannelConfig(SLUG, { + handling: "youtube", + name: "Test Title Filter", + url: "https://www.youtube.com/@example/videos", + downloadFilter: { include: "guest" }, + cookieMode: "always", + keepLatest: 0, + }); const before = await readJson<Record<string, unknown>>(CONFIG); expect(before.downloadFilter).toEqual({ include: "guest" }); + expect(before.cookieMode).toBe("always"); + expect(before.keepLatest).toBe(0); // THE SAME SENTENCE THE FORM SHOWS. title-filter.spec.ts reads this off the // page after typing "elf(" into the exclude input; the route reaches it @@ -202,10 +223,12 @@ test("channel-config round-trips a download filter and refuses a bad regex", asy }); // A PATCH IS A PATCH. updateChannelAction clears every form-managed key // before layering the parse result on, so a route that posted only the patch - // would have silently dropped handling/url/name here. + // would have silently dropped every one of these. expect(after.name).toBe(before.name); expect(after.handling).toBe(before.handling); expect(after.url).toBe(before.url); + expect(after.cookieMode).toBe("always"); + expect(after.keepLatest).toBe(0); // "" clears a field, exactly as clearing the input does. const cleared = await ops(request, "channel-config", { @@ -213,9 +236,11 @@ test("channel-config round-trips a download filter and refuses a bad regex", asy patch: { downloadFilterInclude: "", downloadFilterExclude: "" }, }); expect(cleared.body).toEqual({ ok: true }); - expect( - "downloadFilter" in (await readJson<Record<string, unknown>>(CONFIG)), - ).toBe(false); + const emptied = await readJson<Record<string, unknown>>(CONFIG); + expect("downloadFilter" in emptied).toBe(false); + // Clearing one field clears ONLY that field. + expect(emptied.cookieMode).toBe("always"); + expect(emptied.keepLatest).toBe(0); // The read route sees the same config, and says whether the media is there. await generateReport(page, SLUG);