36 lines
1.4 KiB
TypeScript
36 lines
1.4 KiB
TypeScript
import "../../setup.ts";
|
|
import { assert, assertEquals } from "@std/assert";
|
|
import { DatabaseSync } from "node:sqlite";
|
|
import { up as up0020 } from "../../../db/migrations/0020_digest_schedule.ts";
|
|
|
|
Deno.test("migration 0020 spreads existing users' first digests over the coming period", () => {
|
|
const db = new DatabaseSync(":memory:");
|
|
db.exec(`CREATE TABLE users (id TEXT PRIMARY KEY);`);
|
|
const ids = Array.from({ length: 40 }, () => crypto.randomUUID());
|
|
for (const id of ids) {
|
|
db.prepare(`INSERT INTO users (id) VALUES (?);`).run(id);
|
|
}
|
|
const before = Date.now();
|
|
up0020(db);
|
|
up0020(db); // idempotent
|
|
const rows = db.prepare(
|
|
`SELECT user_id, cadence, window_start FROM digest_schedule;`,
|
|
).all() as { user_id: string; cadence: string; window_start: string }[];
|
|
assertEquals(rows.length, 80);
|
|
const due = (cadence: string, days: number) =>
|
|
rows.filter((r) => r.cadence === cadence).map((r) =>
|
|
new Date(r.window_start).getTime() + days * 86_400_000
|
|
);
|
|
for (const [cadence, days] of [["weekly", 7], ["monthly", 30]] as const) {
|
|
const dues = due(cadence, days);
|
|
// Each first digest falls due within the coming period, not all at once.
|
|
assert(
|
|
dues.every((t) =>
|
|
t >= before - 1000 && t <= Date.now() + days * 86_400_000
|
|
),
|
|
);
|
|
assert(new Set(dues.map((t) => Math.floor(t / 3_600_000))).size > 10);
|
|
}
|
|
db.close();
|
|
});
|