Genshin and Miliastra rows take the end their own wiki article states, because the table's date can mean 03:59, 14:59, 17:59 or one instant worldwide. Rows with no usable time stay on the daily-reset reading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
76 lines
2.8 KiB
TypeScript
76 lines
2.8 KiB
TypeScript
import { afterEach, beforeEach, expect, test } from "bun:test";
|
|
import { mkdtemp, rm } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { ArticleStore } from "../src/ingest/articleStore.ts";
|
|
import { EventFeed } from "../src/shared/feed.ts";
|
|
import { SnapshotStore } from "../src/ingest/snapshots.ts";
|
|
|
|
const NOW = "2026-11-07T00:00:00.000Z";
|
|
const dir = "fixtures/genshin/articles";
|
|
let root: string;
|
|
|
|
beforeEach(async () => {
|
|
root = await mkdtemp(join(tmpdir(), "event-clock-feed-"));
|
|
await new SnapshotStore(root).save("genshin-fandom-events", {
|
|
url: "https://genshin-impact.fandom.com/api.php?action=parse&page=Event",
|
|
body: await Bun.file(`${dir}/event-table-2026-11-06.html`).text(),
|
|
etag: null,
|
|
lastModified: null,
|
|
at: "2026-11-06T17:27:59.858Z",
|
|
eventCount: 15,
|
|
});
|
|
});
|
|
afterEach(async () => {
|
|
await rm(root, { recursive: true, force: true });
|
|
});
|
|
|
|
async function buildFeed() {
|
|
const out = join(root, "feed.json");
|
|
const proc = Bun.spawn(["bun", "run", "scripts/build-feed.ts"], {
|
|
env: { ...process.env, SNAPSHOT_DIR: root, EVENT_FEED_OUT: out, EVENT_FEED_NOW: NOW },
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
const stderr = await new Response(proc.stderr).text();
|
|
const log = await new Response(proc.stdout).text();
|
|
expect(`${await proc.exited} ${stderr}`).toBe("0 ");
|
|
return { feed: EventFeed.parse(await Bun.file(out).json()), log };
|
|
}
|
|
|
|
const hourOfRuin = "genshin:hour-of-ruin:2026-11-04";
|
|
|
|
test("the feed carries the end the article states, on an unchanged id", async () => {
|
|
await new ArticleStore(root).saveRead(
|
|
"Hour_of_Ruin_(Event)",
|
|
await Bun.file(`${dir}/hour-of-ruin-2026-11-07.html`).text(),
|
|
NOW,
|
|
);
|
|
const { feed } = await buildFeed();
|
|
const row = feed.events.find((e) => e.id === hourOfRuin)!;
|
|
expect(row.endPrecision).toBe("exact");
|
|
expect(row.regionScoped).toBe(true);
|
|
expect(row.regionEnds?.europe).toBe("2026-12-15T13:59:00.000Z");
|
|
expect(row.startsAt).toBe("2026-11-04T00:00:00.000Z");
|
|
});
|
|
|
|
test("no articles directory builds the same day-precision row as today", async () => {
|
|
const { feed } = await buildFeed();
|
|
const row = feed.events.find((e) => e.id === hourOfRuin)!;
|
|
expect(row.endPrecision).toBe("day");
|
|
expect(row.endsAt).toBe("2026-12-15T00:00:00.000Z");
|
|
expect(row.regionEnds).toBeNull();
|
|
});
|
|
|
|
test("an article that disagrees on the date is named in the build log", async () => {
|
|
const body = (await Bun.file(`${dir}/hour-of-ruin-2026-11-07.html`).text()).replace(
|
|
"December 15, 2026 14:59",
|
|
"December 20, 2026 14:59",
|
|
);
|
|
await new ArticleStore(root).saveRead("Hour_of_Ruin_(Event)", body, NOW);
|
|
const { feed, log } = await buildFeed();
|
|
expect(feed.events.find((e) => e.id === hourOfRuin)?.endPrecision).toBe("day");
|
|
expect(log).toContain("article:");
|
|
expect(log).toContain("Hour of Ruin");
|
|
});
|