Skip to content
49 linesCodeBlameRaw
1import { test } from "node:test";
2import assert from "node:assert/strict";
3
4import { dmTitle, isUnread, sidebarOrder, tally } from "./unread.ts";
5
6test("unread is what others wrote after your last read", () => {
7 assert.equal(isUnread({ id: "msg_2", author: "user:b" }, "user:a", "msg_1"), true);
8 assert.equal(isUnread({ id: "msg_1", author: "user:b" }, "user:a", "msg_1"), false);
9 assert.equal(isUnread({ id: "msg_2", author: "user:a" }, "user:a", "msg_1"), false);
10 assert.equal(isUnread({ id: "msg_0", author: "agent:x" }, "user:a", null), true);
11});
12
13test("counts per channel, replies included, with mentions of the viewer", () => {
14 const rows = [
15 { channel_id: "c1", id: "m1", author: "user:b", mentions: "" },
16 { channel_id: "c1", id: "m2", author: "agent:x", mentions: " syntaqx " },
17 { channel_id: "c1", id: "m3", author: "user:a", mentions: " syntaqx " },
18 { channel_id: "c2", id: "m4", author: "user:b", mentions: " syntaqxx " },
19 { channel_id: "c2", id: "m0", author: "user:b", mentions: " syntaqx " },
20 ];
21 const counts = tally(rows, "user:a", "syntaqx", new Map([["c1", null], ["c2", "m1"]]));
22 assert.deepEqual(counts.get("c1"), { unread: 2, mentions: 1 });
23 // m0 was read already, and @syntaqxx is someone else.
24 assert.deepEqual(counts.get("c2"), { unread: 1, mentions: 0 });
25 assert.equal(counts.get("c3"), undefined);
26});
27
28test("the sidebar puts starred first, then the most recently active", () => {
29 const entry = (title: string, starred: boolean, at: string | null) => ({
30 title,
31 starred,
32 channel: { last_message_at: at, created_at: "2026-10-01T00:00:00.000Z" },
33 });
34 const ordered = sidebarOrder([
35 entry("quiet", false, null),
36 entry("busy", false, "2026-10-08T10:00:00.000Z"),
37 entry("pinned", true, "2026-10-02T00:00:00.000Z"),
38 entry("older", false, "2026-10-05T00:00:00.000Z"),
39 ]);
40 assert.deepEqual(ordered.map((e) => e.title), ["pinned", "busy", "older", "quiet"]);
41});
42
43test("a direct message is titled by the others, or by you for notes", () => {
44 const p = (display_name: string) => ({ display_name });
45 assert.equal(dmTitle([p("Ada")], p("Me")), "Ada");
46 assert.equal(dmTitle([p("Ada"), p("Ship")], p("Me")), "Ada, Ship");
47 assert.equal(dmTitle([p("A"), p("B"), p("C"), p("D"), p("E")], p("Me")), "A, B, C and 2 more");
48 assert.equal(dmTitle([], p("Chase")), "Chase (you)");
49});