Files
gacha-event-tracker/test/redesign-routine-drawer.test.tsx
T
Lucas WintherandClaude Opus 5.5 50c6e91b00 feat: the redesigned Event Clock
The new reader app replaces the old UI: Checklist with a rail (focus
pills, Next to expire, today's dailies, pinned routines), Timeline in a
new and a classic look, Routines, Archive and a Settings area, in a
Structured (default) and a Relaxed interface. It follows the approved
Round 6 B and Round 7 mockups, corrected screen by screen with the owner.

Reader data moves to a v2 store (gacha-tracker:v2:*). Existing v1 data
is migrated on first load, a recovery copy is written first, and the v1
keys are never removed, so a rollback finds them unchanged. Redeem codes
for Genshin arrive as their own feed.

Also: live's urgency ramp, editable per theme; completion and
section-complete fireworks; a returning-user tour; the design mockups,
specs, plans, reviews and handoff record.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 01:55:16 +02:00

91 lines
2.6 KiB
TypeScript

import { expect, test } from "bun:test";
import { renderToStaticMarkup as render } from "react-dom/server";
import {
RoutineDrawer,
scheduleWords,
sourceLabel,
} from "../src/client/components/redesign/RoutineDrawer.tsx";
import { migrateLegacy } from "../src/client/state/reader/migration.ts";
import { createAccount } from "../src/client/state/reader/accounts.ts";
const at = "2026-10-16T12:00:00.000Z";
const drawer = (
pane: "library" | "create",
state = migrateLegacy({}, ["genshin"], at, () => "account:one"),
) =>
render(
<RoutineDrawer
state={state}
now={Date.parse(at)}
pane={pane}
editing={null}
onPane={() => {}}
onClose={() => {}}
onAction={async () => ({ ok: true })}
onSave={async () => true}
/>,
);
test("schedule lines read like the mockup", () => {
expect(scheduleWords({ unit: "week", startsOn: 1 }, 4)).toBe(
"Every Monday at 04:00",
);
expect(scheduleWords({ unit: "month", startsOn: 16 }, 4)).toBe(
"Every month on the 16th at 04:00",
);
expect(scheduleWords({ unit: "day" }, 20)).toBe("Every day at 20:00");
expect(
sourceLabel("https://genshin-impact.fandom.com/wiki/Weekly_Boss"),
).toBe("Community wiki");
});
test("the library is a shelf of built-ins with bulk follows and dated sources", () => {
const html = drawer("library");
expect(html).toContain('class="routine-drawer"');
expect(html).toContain("Create your own routine");
expect(html).toContain("New follows also show in");
expect(html).toContain("Follow all weeklies");
expect(html).toContain("Every Monday at 04:00 · 3 runs · Community wiki");
expect(html).toContain(">Follow<");
});
test("a game on two servers gets one follow button per server", () => {
const s = migrateLegacy({}, ["genshin"], at, () => "account:one");
s.accounts["account:asia"] = createAccount(
"genshin",
"asia",
at,
"account:asia",
);
s.data["account:asia"] = {
progress: {},
ignored: {},
daily: {},
amounts: {},
};
const html = drawer("library", s);
expect(html).toContain(">EU<");
expect(html).toContain(">Asia<");
expect(html).toContain("2 servers");
});
test("the create shelf asks every mockup question and previews the result", () => {
const html = drawer("create");
for (const label of [
"Start from an example",
"What is it",
"Repeats",
"Every day",
"Resets at",
"Another hour",
"Done when",
"Note",
"Link",
"Also show in",
"Preview",
"Create and follow",
])
expect(html).toContain(label);
expect(html).toContain("Still needed: a name.");
});