Skip to content
52 linesCodeBlameRaw
1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import { VISIT_GAP_MS, lastVisit, markVisit, visitWorkspace } from "./visits.ts";
5
6const NOW = Date.parse("2026-10-10T12:00:00Z");
7const MIN = 60_000;
8const HOUR = 60 * MIN;
9const DAY = 24 * HOUR;
10
11test("a workspace slug is lowercased and checked", () => {
12 assert.equal(visitWorkspace(" Acme "), "acme");
13 assert.equal(visitWorkspace("flagon-io"), "flagon-io");
14 assert.equal(visitWorkspace(""), null);
15 assert.equal(visitWorkspace("a/b"), null);
16 assert.equal(visitWorkspace(7), null);
17 assert.equal(visitWorkspace("x".repeat(65)), null);
18});
19
20test("the first mark starts a visit with nothing before it", () => {
21 assert.deepEqual(markVisit(null, new Date(NOW - HOUR).toISOString(), NOW), { seen_at: NOW - HOUR, previous_at: null });
22});
23
24test("marks close together are one visit; a gap starts the next", () => {
25 const first = { seen_at: NOW - 3 * DAY, previous_at: null };
26 // Back after three days: the new visit counts from the old one's last mark.
27 const back = markVisit(first, NOW - 10 * MIN, NOW)!;
28 assert.deepEqual(back, { seen_at: NOW - 10 * MIN, previous_at: NOW - 3 * DAY });
29 // A refresh a few minutes later is the same visit.
30 assert.deepEqual(markVisit(back, NOW, NOW), { seen_at: NOW, previous_at: NOW - 3 * DAY });
31});
32
33test("a mark never moves the visit back", () => {
34 const kept = { seen_at: NOW - HOUR, previous_at: null };
35 assert.equal(markVisit(kept, NOW - 2 * HOUR, NOW), null);
36 assert.equal(markVisit(kept, NOW - HOUR, NOW), null);
37});
38
39test("a mark is never in the future, nor more than a day behind", () => {
40 assert.equal(markVisit(null, NOW + HOUR, NOW)!.seen_at, NOW);
41 assert.equal(markVisit(null, NOW - 72 * HOUR, NOW)!.seen_at, NOW - DAY);
42 assert.equal(markVisit(null, "not a time", NOW), null);
43 assert.equal(markVisit(null, undefined, NOW), null);
44});
45
46test("last here: the visit before during one, its last mark after", () => {
47 assert.equal(lastVisit(null, NOW), null);
48 const during = { seen_at: NOW - 5 * MIN, previous_at: NOW - 3 * DAY };
49 assert.equal(lastVisit(during, NOW), NOW - 3 * DAY);
50 assert.equal(lastVisit({ seen_at: NOW - 5 * MIN, previous_at: null }, NOW), null);
51 assert.equal(lastVisit(during, NOW - 5 * MIN + VISIT_GAP_MS), NOW - 5 * MIN);
52});