A code redeemed on its last server sweeps in the game's colour and greys in place for 0.8 s, then lands in Redeemed or expired. A completed event greys and shines while its Moved to Archive notice holds, now 0.9 s rather than 1.5 s, which read as unresponsive; an ignored one only greys. Settings → Appearance gains Motion & celebrations as three What to track cards: Reduce motion (stops every animation and the fireworks, adding to the device's own setting), Fireworks, and Shine. Reduce motion locks the other two off without forgetting them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
59 lines
2.1 KiB
TypeScript
59 lines
2.1 KiB
TypeScript
import { expect, test } from "bun:test";
|
|
import { renderToStaticMarkup as render } from "react-dom/server";
|
|
import {
|
|
CelebrationsContext,
|
|
Fireworks,
|
|
celebrationsOn,
|
|
} from "../src/client/components/Fireworks.tsx";
|
|
import { finishesSection } from "../src/client/components/redesign/useSectionCelebration.ts";
|
|
import { AppearancePage } from "../src/client/components/redesign/AppearancePage.tsx";
|
|
import { migrateLegacy } from "../src/client/state/reader/migration.ts";
|
|
|
|
test("celebrations are on unless the reader turned them off", () => {
|
|
expect(celebrationsOn({})).toBe(true);
|
|
expect(celebrationsOn({ celebrations: true })).toBe(true);
|
|
expect(celebrationsOn({ celebrations: false })).toBe(false);
|
|
});
|
|
|
|
test("with celebrations off, no fireworks draw, big or small", () => {
|
|
for (const grand of [false, true])
|
|
expect(
|
|
render(
|
|
<CelebrationsContext value={false}>
|
|
<Fireworks grand={grand} />
|
|
</CelebrationsContext>,
|
|
),
|
|
).toBe("");
|
|
expect(render(<Fireworks />)).toContain('class="fireworks"');
|
|
});
|
|
|
|
test("the item that finishes a section gets the big celebration, not the small burst too", () => {
|
|
expect(finishesSection(3, 2)).toBe(true);
|
|
expect(finishesSection(3, 1)).toBe(false);
|
|
expect(finishesSection(1, 0)).toBe(true);
|
|
expect(finishesSection(3, 3)).toBe(false);
|
|
});
|
|
|
|
test("Appearance offers a Fireworks card, on by default", () => {
|
|
const s = migrateLegacy(
|
|
{},
|
|
[],
|
|
"2026-10-16T12:00:00.000Z",
|
|
() => "account:test",
|
|
);
|
|
const on = render(
|
|
<AppearancePage state={s} onAction={async () => ({ ok: true })} />,
|
|
);
|
|
expect(on).toContain("Motion & celebrations");
|
|
expect(on).toMatch(
|
|
/<button[^>]*data-celebrations="true"[^>]*aria-pressed="true"|<button[^>]*aria-pressed="true"[^>]*data-celebrations="true"/,
|
|
);
|
|
s.prefs.celebrations = false;
|
|
const off = render(
|
|
<AppearancePage state={s} onAction={async () => ({ ok: true })} />,
|
|
);
|
|
expect(off).toMatch(
|
|
/<button[^>]*aria-pressed="false"[^>]*data-celebrations="true"|<button[^>]*data-celebrations="true"[^>]*aria-pressed="false"/,
|
|
);
|
|
});
|