atagen

malice

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

Blame: web/test/packs.test.ts

d095131eec0eatagen2026-10-24 08:39 UTC1
import assert from 'node:assert/strict';
d095131eec0eatagen2026-10-24 08:39 UTC2
import { test } from 'node:test';
132eeceeb362atagen2026-10-25 03:34 UTC3
import { clonePackDestinations, cloneRequest, editableChoices, findSticker, freePackStateKey, packsForRoom, packSlug, reactionShortcode, shortcodeFor, stickersOf } from '../src/lib/packs.ts';
d095131eec0eatagen2026-10-24 08:39 UTC4
d095131eec0eatagen2026-10-24 08:39 UTC5
const image = (shortcode: string, usage: ('Emoticon' | 'Sticker')[]) => ({
d095131eec0eatagen2026-10-24 08:39 UTC6
  shortcode,
d095131eec0eatagen2026-10-24 08:39 UTC7
  media_id: `mxc://x/${shortcode}`,
d095131eec0eatagen2026-10-24 08:39 UTC8
  reaction_key: `mxc://x/${shortcode}`,
d095131eec0eatagen2026-10-24 08:39 UTC9
  body: null,
d095131eec0eatagen2026-10-24 08:39 UTC10
  mimetype: null,
d095131eec0eatagen2026-10-24 08:39 UTC11
  width: null,
d095131eec0eatagen2026-10-24 08:39 UTC12
  height: null,
d095131eec0eatagen2026-10-24 08:39 UTC13
  usage
d095131eec0eatagen2026-10-24 08:39 UTC14
});
d095131eec0eatagen2026-10-24 08:39 UTC15
d095131eec0eatagen2026-10-24 08:39 UTC16
const roomPack = (state_key: string, editable: boolean) => ({
d095131eec0eatagen2026-10-24 08:39 UTC17
  id: `room:!r:x:${state_key}`,
d095131eec0eatagen2026-10-24 08:39 UTC18
  display_name: state_key,
d095131eec0eatagen2026-10-24 08:39 UTC19
  avatar: null,
d095131eec0eatagen2026-10-24 08:39 UTC20
  attribution: null,
d095131eec0eatagen2026-10-24 08:39 UTC21
  source: { Room: { room_id: '!r:x', state_key } },
d095131eec0eatagen2026-10-24 08:39 UTC22
  images: [image('a', ['Sticker']), image('b', ['Emoticon']), image('c', [])],
d095131eec0eatagen2026-10-24 08:39 UTC23
  editable,
d095131eec0eatagen2026-10-24 08:39 UTC24
  enabled_everywhere: false
d095131eec0eatagen2026-10-24 08:39 UTC25
});
d095131eec0eatagen2026-10-24 08:39 UTC26
d095131eec0eatagen2026-10-24 08:39 UTC27
test('shortcodes come from file names and never clash', () => {
d095131eec0eatagen2026-10-24 08:39 UTC28
  const taken = new Set(['cat']);
d095131eec0eatagen2026-10-24 08:39 UTC29
  assert.equal(shortcodeFor('Cat.PNG', taken), 'cat_2');
d095131eec0eatagen2026-10-24 08:39 UTC30
  assert.equal(shortcodeFor('my cool sticker!.webp', taken), 'my_cool_sticker');
d095131eec0eatagen2026-10-24 08:39 UTC31
  assert.equal(shortcodeFor('.png', taken), 'image');
d095131eec0eatagen2026-10-24 08:39 UTC32
  assert.equal(packSlug('Cats & Dogs'), 'cats-dogs');
d095131eec0eatagen2026-10-24 08:39 UTC33
});
d095131eec0eatagen2026-10-24 08:39 UTC34
d095131eec0eatagen2026-10-24 08:39 UTC35
test('stickers include images with no usage of their own', () => {
d095131eec0eatagen2026-10-24 08:39 UTC36
  assert.deepEqual(stickersOf(roomPack('s', true)).map((i) => i.shortcode), ['a', 'c']);
d095131eec0eatagen2026-10-24 08:39 UTC37
});
d095131eec0eatagen2026-10-24 08:39 UTC38
132eeceeb362atagen2026-10-25 03:34 UTC39
test('custom reaction nicknames fall back to known packs without changing the reaction key', () => {
132eeceeb362atagen2026-10-25 03:34 UTC40
  const packs = [roomPack('mine', true)];
132eeceeb362atagen2026-10-25 03:34 UTC41
  assert.equal(reactionShortcode('mxc://x/a', undefined, packs), 'a');
132eeceeb362atagen2026-10-25 03:34 UTC42
  assert.equal(reactionShortcode('mxc://x/a', ' preferred ', packs), 'preferred');
132eeceeb362atagen2026-10-25 03:34 UTC43
  assert.equal(reactionShortcode('mxc://x/unknown', undefined, packs), undefined);
132eeceeb362atagen2026-10-25 03:34 UTC44
  assert.equal(reactionShortcode('👍', 'thumbsup', packs), undefined);
132eeceeb362atagen2026-10-25 03:34 UTC45
});
132eeceeb362atagen2026-10-25 03:34 UTC46
132eeceeb362atagen2026-10-25 03:34 UTC47
test('sticker commands resolve names without matching emoticons or choosing ambiguous stickers', () => {
132eeceeb362atagen2026-10-25 03:34 UTC48
  const pack = roomPack('s', true);
132eeceeb362atagen2026-10-25 03:34 UTC49
  assert.equal(findSticker([pack], 'A').sticker.shortcode, 'a');
132eeceeb362atagen2026-10-25 03:34 UTC50
  assert.equal(findSticker([pack], 'c').pack, pack);
132eeceeb362atagen2026-10-25 03:34 UTC51
  assert.throws(() => findSticker([pack], 'b'), /No sticker named b/);
132eeceeb362atagen2026-10-25 03:34 UTC52
  assert.throws(() => findSticker([pack], 'missing'), /No sticker named missing/);
132eeceeb362atagen2026-10-25 03:34 UTC53
  assert.throws(() => findSticker([pack, roomPack('other', false)], 'a'), /More than one sticker/);
132eeceeb362atagen2026-10-25 03:34 UTC54
});
132eeceeb362atagen2026-10-25 03:34 UTC55
d095131eec0eatagen2026-10-24 08:39 UTC56
test('your pack is always a destination, then editable room packs only', () => {
d095131eec0eatagen2026-10-24 08:39 UTC57
  const packs = { global: [], rooms: { '!r:x': [roomPack('mine', true), roomPack('theirs', false)] } };
d095131eec0eatagen2026-10-24 08:39 UTC58
  const choices = editableChoices(packs, () => 'Room');
d095131eec0eatagen2026-10-24 08:39 UTC59
  assert.deepEqual(choices.map((c) => c.target), [{ kind: 'user' }, { kind: 'room', room_id: '!r:x', state_key: 'mine' }]);
d095131eec0eatagen2026-10-24 08:39 UTC60
  const dests = clonePackDestinations(roomPack('Fancy Pack', false), [{ room_id: '!d:x', name: 'Dest' }], () => 'Room');
d095131eec0eatagen2026-10-24 08:39 UTC61
  assert.deepEqual(dests[1].target, { kind: 'room', room_id: '!d:x', state_key: 'fancy-pack' });
d095131eec0eatagen2026-10-24 08:39 UTC62
});
132eeceeb362atagen2026-10-25 03:34 UTC63
132eeceeb362atagen2026-10-25 03:34 UTC64
test('new pack names avoid existing keys without changing merge destinations', () => {
132eeceeb362atagen2026-10-25 03:34 UTC65
  const packs = { global: [], rooms: { '!r:x': [roomPack('cats', true), roomPack('cats-2', true)] } };
132eeceeb362atagen2026-10-25 03:34 UTC66
  assert.equal(freePackStateKey(packs, '!r:x', 'Cats'), 'cats-3');
132eeceeb362atagen2026-10-25 03:34 UTC67
  assert.equal(freePackStateKey(packs, '!other:x', 'Cats'), 'cats');
132eeceeb362atagen2026-10-25 03:34 UTC68
  const destination = editableChoices(packs, () => 'Room')[1];
132eeceeb362atagen2026-10-25 03:34 UTC69
  const request = cloneRequest({ kind: 'pack', pack: roomPack('source', false) }, destination.target, ['Sticker', 'Emoticon'], null, destination.pack);
132eeceeb362atagen2026-10-25 03:34 UTC70
  assert.deepEqual(request, { op: 'clone_pack', from_pack: 'room:!r:x:source', to: destination.target, display_name: null, usage: ['Sticker', 'Emoticon'] });
132eeceeb362atagen2026-10-25 03:34 UTC71
});
132eeceeb362atagen2026-10-25 03:34 UTC72
132eeceeb362atagen2026-10-25 03:34 UTC73
test('image and event clones keep explicit usage and event names avoid collisions', () => {
132eeceeb362atagen2026-10-25 03:34 UTC74
  const pack = roomPack('source', false);
132eeceeb362atagen2026-10-25 03:34 UTC75
  const to = { kind: 'user' as const };
132eeceeb362atagen2026-10-25 03:34 UTC76
  assert.deepEqual(cloneRequest({ kind: 'image', pack, image: pack.images[1] }, to, ['Sticker'], null, null), {
132eeceeb362atagen2026-10-25 03:34 UTC77
    op: 'clone_pack_image', from_pack: pack.id, shortcode: 'b', to, usage: ['Sticker']
132eeceeb362atagen2026-10-25 03:34 UTC78
  });
132eeceeb362atagen2026-10-25 03:34 UTC79
  const source = { kind: 'sticker' as const, room_id: '!r:x', event_id: '$event', body: 'a' };
132eeceeb362atagen2026-10-25 03:34 UTC80
  assert.deepEqual(cloneRequest(source, to, ['Sticker', 'Emoticon'], null, pack), {
132eeceeb362atagen2026-10-25 03:34 UTC81
    op: 'clone_sticker', room_id: '!r:x', event_id: '$event', shortcode: 'a_2', to, usage: ['Sticker', 'Emoticon']
132eeceeb362atagen2026-10-25 03:34 UTC82
  });
132eeceeb362atagen2026-10-25 03:34 UTC83
  assert.throws(() => cloneRequest(source, to, [], null, pack), /at least one use/);
132eeceeb362atagen2026-10-25 03:34 UTC84
});
132eeceeb362atagen2026-10-25 03:34 UTC85
132eeceeb362atagen2026-10-25 03:34 UTC86
test('channel packs include all ancestor spaces once and do not cross to unrelated spaces', () => {
132eeceeb362atagen2026-10-25 03:34 UTC87
  const local = roomPack('local', false);
132eeceeb362atagen2026-10-25 03:34 UTC88
  const parent = { ...roomPack('parent', false), id: 'space-pack' };
132eeceeb362atagen2026-10-25 03:34 UTC89
  const ancestor = { ...roomPack('ancestor', false), id: 'ancestor-pack' };
132eeceeb362atagen2026-10-25 03:34 UTC90
  const unrelated = { ...roomPack('unrelated', false), id: 'unrelated-pack' };
132eeceeb362atagen2026-10-25 03:34 UTC91
  const global = { ...roomPack('global', false), id: 'global-pack' };
132eeceeb362atagen2026-10-25 03:34 UTC92
  const packs = { global: [global, parent], rooms: { '!r:x': [local], '!s:x': [parent], '!a:x': [ancestor], '!u:x': [unrelated] } };
132eeceeb362atagen2026-10-25 03:34 UTC93
  const rooms = [
132eeceeb362atagen2026-10-25 03:34 UTC94
    { room_id: '!r:x', parent_spaces: ['!s:x'], children: [], space: false },
132eeceeb362atagen2026-10-25 03:34 UTC95
    { room_id: '!s:x', parent_spaces: ['!a:x'], children: ['!r:x'], space: true },
132eeceeb362atagen2026-10-25 03:34 UTC96
    { room_id: '!a:x', parent_spaces: ['!s:x'], children: ['!s:x'], space: true },
132eeceeb362atagen2026-10-25 03:34 UTC97
    { room_id: '!u:x', parent_spaces: [], children: [], space: true }
132eeceeb362atagen2026-10-25 03:34 UTC98
  ];
132eeceeb362atagen2026-10-25 03:34 UTC99
  assert.deepEqual(packsForRoom(packs, '!r:x', rooms).map((pack) => pack.id), [local.id, parent.id, ancestor.id, global.id]);
132eeceeb362atagen2026-10-25 03:34 UTC100
  assert.deepEqual(packsForRoom(packs, '!r:x', [{ ...rooms[0], parent_spaces: [] }, ...rooms.slice(1)]).map((pack) => pack.id), [local.id, parent.id, ancestor.id, global.id]);
132eeceeb362atagen2026-10-25 03:34 UTC101
});