atagen

malice

public
Star0
Watch0
db4e552594cba852ed2a622cfaef56f0091d3721
2
ssh://brewery@pls.lobotomise.me:33/atagen/malice.git
web/test/thread-index.test.tsTypescript46 lines1.9 KB
1
import assert from 'node:assert/strict';
2
import { test } from 'node:test';
3
import { roomThreads, threadMatches } from '../src/lib/thread-index.ts';
4
import type { TimelineEvent, TimelineItem } from '../src/lib/types.ts';
5
6
function root(id: string, body: string, replies: number, latest: number, extra: Partial<TimelineEvent> = {}): TimelineItem {
7
  return {
8
    kind: 'event',
9
    event: {
10
      item_id: id,
11
      event_id: id,
12
      timestamp_ms: 1,
13
      sender: { user_id: '@a:x', display_name: 'Alice', avatar: null, name_ambiguous: false },
14
      content: { kind: 'Message', message: { kind: 'Text', body, media: null } },
15
      thread_root: null,
16
      thread_summary: replies ? { reply_count: replies, latest_event_id: null, latest_event_timestamp_ms: latest } : null,
17
      ...extra
18
    } as TimelineEvent
19
  };
20
}
21
22
test('threads sort by latest activity with pins first', () => {
23
  const items = [root('$a', 'old thread', 2, 100), root('$b', 'new thread', 1, 300), root('$c', 'no replies', 0, 0), root('$d', 'pinned', 4, 50)];
24
  const list = roomThreads('!r', items, ['$d']);
25
  assert.deepEqual(list.map((t) => t.root_event_id), ['$d', '$b', '$a']);
26
  assert.equal(list[0].pinned, true);
27
});
28
29
test('pinned threads outside the loaded timeline still get a row', () => {
30
  const list = roomThreads('!r', [], ['$gone']);
31
  assert.equal(list.length, 1);
32
  assert.equal(list[0].root_event_id, '$gone');
33
  assert.equal(list[0].preview, '');
34
});
35
36
test('replies inside a thread are not treated as roots', () => {
37
  const reply = root('$r', 'reply', 3, 10, { thread_root: '$a' });
38
  assert.equal(roomThreads('!r', [reply], []).length, 0);
39
});
40
41
test('search matches preview text and sender', () => {
42
  const [entry] = roomThreads('!r', [root('$a', 'Deploy plan for Friday', 2, 10)], []);
43
  assert.ok(threadMatches(entry, 'deploy'));
44
  assert.ok(threadMatches(entry, 'alice'));
45
  assert.equal(threadMatches(entry, 'lunch'), false);
46
});