import {
act,
cleanup,
fireEvent,
render,
screen,
} from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import { defineToolcraft } from "../../schema/define-toolcraft";
import type { ToolcraftExternalStore } from "../../state/toolcraft-external-store";
import { ToolcraftRoot } from "./toolcraft-root";
import { useToolcraftStore } from "./toolcraft-store-context";
import { useToolcraftDispatch } from "./use-toolcraft";
const playbackPersistenceSchema = defineToolcraft({
canvas: { enabled: true },
panels: { timeline: { mode: "playback" } },
persistence: {
include: ["panels", "timeline"],
key: "toolcraft:playback-boundary:state:v1",
storage: "localStorage",
version: 1,
},
});
function CaptureStore({
capture,
}: {
capture: (store: ToolcraftExternalStore) => void;
}): null {
capture(useToolcraftStore());
return null;
}
function PublicPlaybackControls(): React.JSX.Element {
const dispatch = useToolcraftDispatch();
return (
<>
>
);
}
afterEach(() => {
vi.useRealTimers();
cleanup();
window.localStorage.clear();
});
describe("public playback persistence boundary", () => {
it.each([
{ buttonName: "Pause through public dispatch", label: "setPlaying(false)" },
{ buttonName: "Toggle through public dispatch", label: "togglePlayback" },
])(
"persists and reloads transient time when public $label stops playback",
({ buttonName }) => {
vi.useFakeTimers();
let store: ToolcraftExternalStore | undefined;
const view = render(
{ store = value; }} />
,
);
act(() => {
vi.advanceTimersByTime(120);
store?.dispatchTransient({
currentTimeSeconds: 2,
type: "timeline.setCurrentTime",
});
});
fireEvent.click(screen.getByRole("button", { name: buttonName }));
expect(store?.getCommittedState().timeline).toMatchObject({
currentTimeSeconds: 2,
isPlaying: false,
});
act(() => {
vi.advanceTimersByTime(120);
});
view.unmount();
let reloadedStore: ToolcraftExternalStore | undefined;
render(
{ reloadedStore = value; }} />
,
);
expect(reloadedStore?.getState().timeline).toMatchObject({
currentTimeSeconds: 2,
isPlaying: false,
});
},
);
});