atagen

malice

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

Blame: web/test/emotes.test.ts

05a48e9e7942atagen2026-10-24 09:32 UTC1
import assert from 'node:assert/strict';
05a48e9e7942atagen2026-10-24 09:32 UTC2
import { test } from 'node:test';
05a48e9e7942atagen2026-10-24 09:32 UTC3
import { completeShortcode, emoteQueryAt, rankEmotes, resolveEmotes } from '../src/lib/emotes.ts';
05a48e9e7942atagen2026-10-24 09:32 UTC4
import { formatBody } from '../src/lib/markdown.ts';
05a48e9e7942atagen2026-10-24 09:32 UTC5
05a48e9e7942atagen2026-10-24 09:32 UTC6
const sob = { emoji: '😭', label: 'loudly crying face', tags: [], shortcodes: ['sob'] };
05a48e9e7942atagen2026-10-24 09:32 UTC7
const smile = { emoji: 'πŸ˜„', label: 'grinning face with smiling eyes', tags: [], shortcodes: ['smile'] };
05a48e9e7942atagen2026-10-24 09:32 UTC8
const blob = { shortcode: 'blob_sob', mxc: 'mxc://example.org/blob' };
05a48e9e7942atagen2026-10-24 09:32 UTC9
05a48e9e7942atagen2026-10-24 09:32 UTC10
test('opens the emote query after two shortcode characters at a word start', () => {
05a48e9e7942atagen2026-10-24 09:32 UTC11
  assert.deepEqual(emoteQueryAt('so :so', 6), { start: 3, query: 'so' });
05a48e9e7942atagen2026-10-24 09:32 UTC12
  assert.equal(emoteQueryAt('so :s', 5), null);
05a48e9e7942atagen2026-10-24 09:32 UTC13
  assert.equal(emoteQueryAt('re:so', 5), null);
05a48e9e7942atagen2026-10-24 09:32 UTC14
  assert.equal(emoteQueryAt('12:30', 5), null);
05a48e9e7942atagen2026-10-24 09:32 UTC15
  assert.equal(emoteQueryAt(':so b', 5), null);
05a48e9e7942atagen2026-10-24 09:32 UTC16
});
05a48e9e7942atagen2026-10-24 09:32 UTC17
05a48e9e7942atagen2026-10-24 09:32 UTC18
test('ranks prefix matches ahead of word and substring matches', () => {
05a48e9e7942atagen2026-10-24 09:32 UTC19
  const names = rankEmotes('sob', [blob], [sob, smile]).map((c) => c.shortcode);
05a48e9e7942atagen2026-10-24 09:32 UTC20
  assert.deepEqual(names, ['sob', 'blob_sob']);
05a48e9e7942atagen2026-10-24 09:32 UTC21
});
05a48e9e7942atagen2026-10-24 09:32 UTC22
05a48e9e7942atagen2026-10-24 09:32 UTC23
test('swaps a closed emoji shortcode for the emoji', () => {
05a48e9e7942atagen2026-10-24 09:32 UTC24
  assert.deepEqual(completeShortcode('ugh :sob:', 9, [sob]), { text: 'ugh 😭', caret: 6 });
05a48e9e7942atagen2026-10-24 09:32 UTC25
  assert.equal(completeShortcode('ugh :blob_sob:', 14, [sob]), null);
05a48e9e7942atagen2026-10-24 09:32 UTC26
  assert.equal(completeShortcode('a:sob:', 6, [sob]), null);
05a48e9e7942atagen2026-10-24 09:32 UTC27
});
05a48e9e7942atagen2026-10-24 09:32 UTC28
05a48e9e7942atagen2026-10-24 09:32 UTC29
test('sends used custom emotes as emoticon images', () => {
05a48e9e7942atagen2026-10-24 09:32 UTC30
  const emotes = resolveEmotes('hi :blob_sob: and :nope:', [blob]);
05a48e9e7942atagen2026-10-24 09:32 UTC31
  assert.deepEqual(emotes, [blob]);
05a48e9e7942atagen2026-10-24 09:32 UTC32
  assert.equal(
05a48e9e7942atagen2026-10-24 09:32 UTC33
    formatBody('hi :blob_sob:', [], false, emotes),
05a48e9e7942atagen2026-10-24 09:32 UTC34
    'hi <img data-mx-emoticon src="mxc://example.org/blob" alt=":blob_sob:" title=":blob_sob:" height="32">'
05a48e9e7942atagen2026-10-24 09:32 UTC35
  );
05a48e9e7942atagen2026-10-24 09:32 UTC36
  assert.match(formatBody('**hi** :blob_sob:', [], true, emotes) ?? '', /<strong>hi<\/strong> <img data-mx-emoticon/);
05a48e9e7942atagen2026-10-24 09:32 UTC37
  assert.equal(formatBody('`:blob_sob:`', [], true, emotes), '<p><code>:blob_sob:</code></p>');
05a48e9e7942atagen2026-10-24 09:32 UTC38
});