Files
Jyotisha/frontend/tests/session-groups.test.ts
T

81 lines
3.3 KiB
TypeScript

import assert from "node:assert/strict";
import test from "node:test";
import {
beginSessionPageLoad,
groupSessionsByRecency,
mergeSessionPage,
recencyKeyFor,
sortSessions,
} from "../src/lib/session-groups.ts";
function session(id: string, updatedAt: number, pinned = false) {
return { id, pinned, updatedAt };
}
test("sortSessions puts pinned ahead of a newer unpinned row", () => {
const olderPinned = session("pin", 100, true);
const newer = session("new", 500);
assert.deepEqual(sortSessions([newer, olderPinned]).map((item) => item.id), ["pin", "new"]);
});
test("sortSessions orders same pin state by updatedAt descending", () => {
const early = session("early", 100);
const late = session("late", 400);
assert.deepEqual(sortSessions([early, late]).map((item) => item.id), ["late", "early"]);
});
test("sortSessions keeps the original order when pin and time are equal", () => {
const first = session("a", 200);
const second = session("b", 200);
assert.deepEqual(sortSessions([first, second]).map((item) => item.id), ["a", "b"]);
});
test("sortSessions does not drop archived rows", () => {
const archived = { ...session("arc", 50), archivedAt: "2026-09-01T00:00:00.000Z" };
const live = session("live", 80);
assert.deepEqual(sortSessions([archived, live]).map((item) => item.id), ["live", "arc"]);
});
test("groupSessionsByRecency uses local midnight for yesterday across 23:59 to 00:01", () => {
const now = new Date(2026, 8, 6, 0, 1, 0).getTime();
const justYesterday = new Date(2026, 8, 5, 23, 59, 0).getTime();
const justToday = new Date(2026, 8, 6, 0, 0, 0).getTime();
assert.equal(recencyKeyFor(justYesterday, now), "yesterday");
assert.equal(recencyKeyFor(justToday, now), "today");
});
test("groupSessionsByRecency splits day 7 and day 8, and day 30 and day 31", () => {
const now = new Date(2026, 8, 6, 12, 0, 0).getTime();
const todayStart = new Date(2026, 8, 6).getTime();
const dayMs = 24 * 60 * 60 * 1000;
const day7 = todayStart - 6 * dayMs + 12 * 60 * 60 * 1000;
const day8 = todayStart - 7 * dayMs + 12 * 60 * 60 * 1000;
const day30 = todayStart - 29 * dayMs + 12 * 60 * 60 * 1000;
const day31 = todayStart - 30 * dayMs + 12 * 60 * 60 * 1000;
assert.equal(recencyKeyFor(day7, now), "week");
assert.equal(recencyKeyFor(day8, now), "month");
assert.equal(recencyKeyFor(day30, now), "month");
assert.equal(recencyKeyFor(day31, now), "older");
const groups = groupSessionsByRecency([
session("today", now),
session("week", day7),
session("older", day31),
], now);
assert.deepEqual(groups.map((group) => group.label), ["今天", "最近 7 天", "更早"]);
});
test("mergeSessionPage keeps the local row and skips a duplicate id", () => {
const local = session("keep", 900);
const incoming = [session("keep", 100), session("next", 80)];
assert.deepEqual(mergeSessionPage([local], incoming).map((item) => item.id), ["keep", "next"]);
assert.equal(mergeSessionPage([local], incoming)[0]?.updatedAt, 900);
});
test("beginSessionPageLoad only starts one in-flight request", () => {
const inFlight = { current: false };
assert.equal(beginSessionPageLoad(inFlight, "cursor"), true);
assert.equal(beginSessionPageLoad(inFlight, "cursor"), false);
assert.equal(beginSessionPageLoad({ current: false }, null), false);
});