a1956deb63
Co-authored-by: Cursor <cursoragent@cursor.com>
81 lines
3.3 KiB
TypeScript
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);
|
|
});
|