atagen

malice

public
Star0
Watch0
48af827771081b0e3b68719cf046485aaab65304
2
ssh://brewery@pls.lobotomise.me:33/atagen/malice.git

Blame: web/test/mention-profiles.test.ts

48af82777108atagen2026-10-26 10:41 UTC1
import assert from 'node:assert/strict';
48af82777108atagen2026-10-26 10:41 UTC2
import { test } from 'node:test';
48af82777108atagen2026-10-26 10:41 UTC3
import { contextWithProfiles, roomsLackingProfiles, withProfiles } from '../src/lib/mention-profiles.ts';
48af82777108atagen2026-10-26 10:41 UTC4
import type { MemberSummary, Sender, TimelineItem } from '../src/lib/types.ts';
48af82777108atagen2026-10-26 10:41 UTC5
48af82777108atagen2026-10-26 10:41 UTC6
const bare = (user_id: string): Sender => ({ user_id, display_name: null, avatar: null, name_ambiguous: false });
48af82777108atagen2026-10-26 10:41 UTC7
48af82777108atagen2026-10-26 10:41 UTC8
function message(sender: Sender, replySender: Sender | null = null): TimelineItem {
48af82777108atagen2026-10-26 10:41 UTC9
  return {
48af82777108atagen2026-10-26 10:41 UTC10
    kind: 'event',
48af82777108atagen2026-10-26 10:41 UTC11
    event: {
48af82777108atagen2026-10-26 10:41 UTC12
      item_id: `i-${sender.user_id}`,
48af82777108atagen2026-10-26 10:41 UTC13
      event_id: `$e-${sender.user_id}`,
48af82777108atagen2026-10-26 10:41 UTC14
      transaction_id: null,
48af82777108atagen2026-10-26 10:41 UTC15
      sender,
48af82777108atagen2026-10-26 10:41 UTC16
      timestamp_ms: 1,
48af82777108atagen2026-10-26 10:41 UTC17
      own: false,
48af82777108atagen2026-10-26 10:41 UTC18
      send_state: { kind: 'Sent' },
48af82777108atagen2026-10-26 10:41 UTC19
      content: { kind: 'Redacted' },
48af82777108atagen2026-10-26 10:41 UTC20
      reply_to: replySender ? { event_id: '$target', details: { kind: 'Ready', sender: replySender, content: { kind: 'Redacted' }, timestamp_ms: 0 } } : null,
48af82777108atagen2026-10-26 10:41 UTC21
      thread_root: null,
48af82777108atagen2026-10-26 10:41 UTC22
      thread_summary: null,
48af82777108atagen2026-10-26 10:41 UTC23
      reactions: [],
48af82777108atagen2026-10-26 10:41 UTC24
      read_by: [],
48af82777108atagen2026-10-26 10:41 UTC25
      editable: false
48af82777108atagen2026-10-26 10:41 UTC26
    }
48af82777108atagen2026-10-26 10:41 UTC27
  };
48af82777108atagen2026-10-26 10:41 UTC28
}
48af82777108atagen2026-10-26 10:41 UTC29
48af82777108atagen2026-10-26 10:41 UTC30
function member(user_id: string, display_name: string | null, avatar: string | null = null): MemberSummary {
48af82777108atagen2026-10-26 10:41 UTC31
  return { user_id, name: display_name ?? user_id, display_name, avatar, membership: 'Join', own: false, name_ambiguous: false, ignored: false, service: false };
48af82777108atagen2026-10-26 10:41 UTC32
}
48af82777108atagen2026-10-26 10:41 UTC33
48af82777108atagen2026-10-26 10:41 UTC34
const members = { '@carol:x': member('@carol:x', 'Carol', 'mxc://x/c'), '@dave:x': member('@dave:x', 'Dave') };
48af82777108atagen2026-10-26 10:41 UTC35
48af82777108atagen2026-10-26 10:41 UTC36
test('lists only rooms with a sender or reply sender missing both name and avatar', () => {
48af82777108atagen2026-10-26 10:41 UTC37
  const named = { ...bare('@carol:x'), display_name: 'Carol' };
48af82777108atagen2026-10-26 10:41 UTC38
  const rooms = roomsLackingProfiles([
48af82777108atagen2026-10-26 10:41 UTC39
    { roomId: '!a:x', item: message(named) },
48af82777108atagen2026-10-26 10:41 UTC40
    { roomId: '!b:x', item: message(bare('@carol:x')) },
48af82777108atagen2026-10-26 10:41 UTC41
    { roomId: '!c:x', item: message(named, bare('@dave:x')) },
48af82777108atagen2026-10-26 10:41 UTC42
    { roomId: '!d:x', item: { kind: 'readMarker' } }
48af82777108atagen2026-10-26 10:41 UTC43
  ]);
48af82777108atagen2026-10-26 10:41 UTC44
  assert.deepEqual([...rooms].sort(), ['!b:x', '!c:x']);
48af82777108atagen2026-10-26 10:41 UTC45
});
48af82777108atagen2026-10-26 10:41 UTC46
48af82777108atagen2026-10-26 10:41 UTC47
test('fills the sender and reply sender from the room members', () => {
48af82777108atagen2026-10-26 10:41 UTC48
  const filled = withProfiles(message(bare('@carol:x'), bare('@dave:x')), members);
48af82777108atagen2026-10-26 10:41 UTC49
  assert.equal(filled.kind, 'event');
48af82777108atagen2026-10-26 10:41 UTC50
  if (filled.kind !== 'event') return;
48af82777108atagen2026-10-26 10:41 UTC51
  assert.equal(filled.event.sender.display_name, 'Carol');
48af82777108atagen2026-10-26 10:41 UTC52
  assert.equal(filled.event.sender.avatar, 'mxc://x/c');
48af82777108atagen2026-10-26 10:41 UTC53
  assert.equal(filled.event.reply_to?.details.kind === 'Ready' && filled.event.reply_to.details.sender.display_name, 'Dave');
48af82777108atagen2026-10-26 10:41 UTC54
});
48af82777108atagen2026-10-26 10:41 UTC55
48af82777108atagen2026-10-26 10:41 UTC56
test('keeps an engine profile and the same item when nothing changes', () => {
48af82777108atagen2026-10-26 10:41 UTC57
  const named = message({ ...bare('@carol:x'), display_name: 'Carol from the engine' });
48af82777108atagen2026-10-26 10:41 UTC58
  assert.equal(withProfiles(named, members), named);
48af82777108atagen2026-10-26 10:41 UTC59
  const unknown = message(bare('@erin:x'));
48af82777108atagen2026-10-26 10:41 UTC60
  assert.equal(withProfiles(unknown, members), unknown);
48af82777108atagen2026-10-26 10:41 UTC61
  const context = { events_before: [unknown], event: named, events_after: [], start_token: null, end_token: null };
48af82777108atagen2026-10-26 10:41 UTC62
  assert.equal(contextWithProfiles(context, undefined), context);
48af82777108atagen2026-10-26 10:41 UTC63
});