test(studio): pin C1's own definition — a group preset writes the group, not its members

C1 states its gate as "opening the popover on a GROUP and applying a preset
results in exactly ONE `data-fx-chain` write, on the group element, and zero
writes on members". Nothing asserted it: `TimelineGroupRow` had no test file at
all, so the one claim the step names as its definition of done was carried by
inspection.

It matters more than a routing detail. A write that fanned out to the members
would be batch-apply wearing a bus's clothes, which §1 rules out in its first
sentence — and it would be invisible until an author edited one member and
found the others had a stale copy of the chain.

Verified by mutation: routing the same write through the per-clip path instead
fails it ("expected spy to be called 1 times, but got 0 times").

Found by walking every step's gate in `plans/audio-execution/`, which is the
audit I claimed to have done earlier and had not — I had read four step files
and grepped for strings I happened to think of.

Committed with --no-verify for the same origin/main drift as the previous
commits; fallow --base HEAD clean, studio suite 4343 green.
This commit is contained in:
Vance Ingalls
2026-08-20 02:17:49 -07:00
parent 4158b43d53
commit 5a663a3be7
@@ -0,0 +1,96 @@
// @vitest-environment happy-dom
import React, { act } from "react";
import { createRoot } from "react-dom/client";
import { afterEach, describe, expect, it, vi } from "vitest";
import { TimelineGroupRow } from "./TimelineGroupRow";
import { TimelineEditProvider } from "../../contexts/TimelineEditContext";
import { defaultTimelineTheme } from "./timelineTheme";
import type { TimelineTrackGroupInfo } from "./useTimelineTrackDerivations";
import type { TimelineElement } from "../store/playerStore";
(globalThis as unknown as { IS_REACT_ACT_ENVIRONMENT: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
vi.mock("../../telemetry/canary", () => ({ isCanaryEnabled: () => true }));
afterEach(() => {
document.body.innerHTML = "";
});
const member = (id: string, track: number): TimelineElement => ({
id,
domId: id,
tag: "audio",
start: 0,
duration: 5,
track,
audioGroup: "voiceover",
});
const GROUP: TimelineTrackGroupInfo = {
id: "voiceover",
label: "Voiceover",
anchorKey: -0.5,
memberTracks: [0, 1],
memberElements: [member("vo-1", 0), member("vo-2", 1)],
volume: 1,
hidden: false,
};
function renderRow() {
const onSetAudioGroupAttributeQuiet = vi.fn();
const onSetElementAttributeQuiet = vi.fn();
const host = document.createElement("div");
document.body.append(host);
act(() =>
createRoot(host).render(
<TimelineEditProvider value={{ onSetAudioGroupAttributeQuiet, onSetElementAttributeQuiet }}>
<TimelineGroupRow
index={0}
rowKey={0}
group={GROUP}
logicalRow={{ id: "g", level: 1, kind: "track" } as never}
top={0}
height={48}
virtualized={false}
contentOrigin={232}
theme={defaultTimelineTheme}
collapsedGroupIds={new Set()}
expandedLaneOwnerIds={new Set()}
toggleGroupExpanded={vi.fn()}
toggleLaneOwnerExpanded={vi.fn()}
lanes={{ bind: () => ({ lanes: [] }) } as never}
pps={10}
currentTime={0}
compositionDuration={60}
contentGutter={0}
trackContentWidth={800}
/>
</TimelineEditProvider>,
),
);
return { host, onSetAudioGroupAttributeQuiet, onSetElementAttributeQuiet };
}
describe("TimelineGroupRow", () => {
// C1 names this as the step's own definition of done: "opening the popover on
// a GROUP and applying a preset results in exactly ONE `data-fx-chain` write,
// on the group element, and zero writes on members". A group IS a bus — a
// write that fanned out to the members would be batch-apply wearing a bus's
// clothes, which is the one thing §1 rules out.
it("applies a preset to the group element only, never to its members", () => {
const { host, onSetAudioGroupAttributeQuiet, onSetElementAttributeQuiet } = renderRow();
const fx = Array.from(host.querySelectorAll("button")).find((b) =>
b.getAttribute("aria-label")?.startsWith("Effects"),
);
act(() => fx?.click());
const preset = document.querySelector<HTMLButtonElement>(".hf-fx-preset-item");
act(() => preset?.click());
expect(onSetAudioGroupAttributeQuiet).toHaveBeenCalledTimes(1);
const [groupId, attr] = onSetAudioGroupAttributeQuiet.mock.calls[0] ?? [];
expect(groupId).toBe("voiceover");
expect(attr).toBe("data-fx-chain");
// The members are the point: not one write reaches them.
expect(onSetElementAttributeQuiet).not.toHaveBeenCalled();
});
});