Files
gacha-event-tracker/test/routines.test.ts
T
Lucas WintherandClaude Opus 5.5 624c725cbf feat(settings): switch built-in weekly tasks per game, and make one your own
The switch sits beside the daily chores and answers the strip's question
too. Built-ins are listed with a link to their dated source. Make it mine
copies one into the reader's tasks, numbers and ticks included, and hides
the original while the copy exists. It's additive, so deleting the copy
brings the original back as it was.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 14:10:58 +02:00

97 lines
3.7 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import {
activeRoutines,
ROUTINES,
RoutineSchema,
routinesFor,
routineToAsk,
mineFrom,
} from "../src/shared/routines.ts";
import { restorePrefsValue } from "../src/client/state/usePrefs.ts";
import { taskStatus } from "../src/shared/task.ts";
/**
* Weekly tasks the app ships for a game. Each is a claim about a game we did
* not write, so each must say where it came from and as of when — the bar
* `dailyTasks` in games.ts is held to.
*/
describe("ROUTINES", () => {
test("every one parses, and ids are unique", () => {
for (const r of ROUTINES) expect(RoutineSchema.safeParse(r).success).toBe(true);
expect(new Set(ROUTINES.map((r) => r.id)).size).toBe(ROUTINES.length);
});
test("every one names its game in its id, and cites an https source with a date", () => {
for (const r of ROUTINES) {
expect(r.id.split(":")[1]).toBe(r.game);
expect(r.source.startsWith("https://")).toBe(true);
expect(r.asOf).toMatch(/^\d{4}-\d{2}-\d{2}$/);
expect(r.checked).toMatch(/^\d{4}-\d{2}-\d{2}$/);
}
});
test("a routine without a source is refused", () => {
const { source: _s, ...bare } = ROUTINES[0]!;
expect(RoutineSchema.safeParse(bare).success).toBe(false);
});
test("the first two, as sourced", () => {
expect(routinesFor("zzz").map((r) => [r.title, r.measure])).toEqual([
["Ridu Weekly", { kind: "amount", target: 1300, unit: "points" }],
]);
expect(routinesFor("endfield").map((r) => [r.title, r.measure])).toEqual([
["Weekly Routine", { kind: "amount", target: 10, unit: "points" }],
]);
expect(routinesFor("genshin")).toEqual([]);
});
test("a routine has a status like any task", () => {
const s = taskStatus({
task: routinesFor("zzz")[0]!, region: "europe",
now: Date.parse("2026-10-15T12:00:00Z"), logged: [],
amounts: { "2026-10-12": { value: 900, at: "2026-10-15T12:00:00.000Z" } },
});
expect(s).toMatchObject({ scope: "week", count: 900, required: 1300 });
});
});
describe("which built-ins are on", () => {
test("only for games the reader said yes to", () => {
expect(activeRoutines(undefined, new Set()).map((r) => r.id)).toEqual([]);
expect(activeRoutines(["zzz"], new Set()).map((r) => r.id)).toEqual(["routine:zzz:ridu-weekly"]);
});
test("one the reader made their own is hidden while the copy exists", () => {
expect(activeRoutines(["zzz", "endfield"], new Set(["routine:zzz:ridu-weekly"])).map((r) => r.id))
.toEqual(["routine:endfield:weekly-routine"]);
});
});
describe("which game to ask about", () => {
test("the first game on screen with built-ins, not asked and not on", () => {
expect(routineToAsk(["genshin", "zzz", "endfield"], undefined, undefined)).toBe("zzz");
expect(routineToAsk(["genshin", "zzz", "endfield"], undefined, ["zzz"])).toBe("endfield");
expect(routineToAsk(["zzz"], ["zzz"], undefined)).toBeNull();
expect(routineToAsk(["genshin"], undefined, undefined)).toBeNull();
});
});
describe("restoring prefs with the new fields", () => {
test("junk in the arrays is sanitised, and absent stays absent", () => {
const r = restorePrefsValue({ routineGames: ["zzz", 7], routinesAsked: "zzz" });
expect(r.routineGames).toEqual(["zzz"]);
expect(r.routinesAsked).toBeUndefined();
expect(restorePrefsValue({}).routineGames).toBeUndefined();
});
});
describe("making a built-in your own", () => {
test("copies its shape and remembers where it came from", () => {
const ridu = routinesFor("zzz")[0]!;
expect(mineFrom(ridu)).toEqual({
game: "zzz", title: "Ridu Weekly", period: { unit: "week", startsOn: 1 },
measure: { kind: "amount", target: 1300, unit: "points" }, from: "routine:zzz:ridu-weekly",
});
});
});