cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 1 | import assert from 'node:assert/strict'; |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 2 | import { test } from 'node:test'; |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 3 | import { formatBody } from '../src/lib/markdown.ts'; |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 4 | import { mentionQueryAt, mentionedUserIds, rankPeople, resolveMentions, stripMarkdownPills } from '../src/lib/mentions.ts'; |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 5 | import { findUrls } from '../src/lib/urls.ts'; |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 6 | |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 7 | const alice = { user_id: '@alice:example.org', name: 'Alice Liddell', avatar: null }; |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 8 | const bob = { user_id: '@bob:example.org', name: 'Bob', avatar: null }; |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 9 | const carol = { user_id: '@carol:example.org', name: 'Carol', avatar: null }; |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 10 | |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 11 | test('finds the query under the caret only at a word start', () => { |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 12 | assert.deepEqual(mentionQueryAt('hi @al', 6), { start: 3, query: 'al' }); |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 13 | assert.deepEqual(mentionQueryAt('@', 1), { start: 0, query: '' }); |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 14 | assert.equal(mentionQueryAt('me@al', 5), null); |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 15 | assert.equal(mentionQueryAt('@al ice', 7), null); |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 16 | }); |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 17 | |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 18 | test('ranks by name and id, skipping yourself', () => { |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 19 | assert.deepEqual(rankPeople([alice, bob, carol], 'lid', null), [alice]); |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 20 | assert.deepEqual(rankPeople([alice, bob, carol], 'bob:ex', null), [bob]); |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 21 | assert.deepEqual(rankPeople([alice, bob, carol], '', '@bob:example.org'), [alice, carol]); |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 22 | }); |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 23 | |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 24 | test('keeps picked names still in the body and typed matrix ids', () => { |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 25 | const picked = [ |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 26 | { user_id: alice.user_id, text: alice.name }, |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 27 | { user_id: bob.user_id, text: bob.name } |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 28 | ]; |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 29 | const mentions = resolveMentions('Alice Liddell and @carol:example.org', picked); |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 30 | assert.deepEqual(mentionedUserIds(mentions), ['@alice:example.org', '@carol:example.org']); |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 31 | }); |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 32 | |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 33 | test('links mentions outside code', () => { |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 34 | const mentions = [{ user_id: '@a<b:example.org', text: 'A<B' }]; |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 35 | assert.equal( |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 36 | formatBody('hey A<B `A<B`', mentions, true), |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 37 | '<p>hey <a href="https://matrix.to/#/@a<b:example.org">A<B</a> <code>A<B</code></p>' |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 38 | ); |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 39 | assert.equal(formatBody('hey A<B', mentions, false), 'hey <a href="https://matrix.to/#/@a<b:example.org">A<B</a>'); |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 40 | assert.equal(formatBody('nobody here', mentions, true), null); |
cf23dbf4e77c | atagen | 2026-10-23 06:36 UTC | 41 | }); |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 42 | |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 43 | test('markdown pills in the plain body become names', () => { |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 44 | const body = 'Good Morning [lillis](https://matrix.to/#/@lillis:matrix.org),\nhi'; |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 45 | assert.deepEqual(stripMarkdownPills(body), { |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 46 | text: 'Good Morning lillis,\nhi', |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 47 | mentions: [{ user_id: '@lillis:matrix.org', text: 'lillis' }] |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 48 | }); |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 49 | assert.deepEqual(stripMarkdownPills('[x](https://matrix.to/#/@%E0%A4%A)'), { |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 50 | text: '[x](https://matrix.to/#/@%E0%A4%A)', |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 51 | mentions: [] |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 52 | }); |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 53 | }); |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 54 | |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 55 | test('matrix.to permalinks get no link card', () => { |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 56 | assert.deepEqual( |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 57 | findUrls('https://matrix.to/#/@lillis:matrix.org and https://example.org/a').map((u) => u.href), |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 58 | ['https://example.org/a'] |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 59 | ); |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 60 | }); |