atagen

malice

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

Blame: web/test/pack-preferences.test.ts

132eeceeb362atagen2026-10-25 03:34 UTC1
import assert from 'node:assert/strict';
132eeceeb362atagen2026-10-25 03:34 UTC2
import { test } from 'node:test';
132eeceeb362atagen2026-10-25 03:34 UTC3
import { enabledPacks, enabledQuickReactions, imageEnabled, parseDisabledPackImages, withImageEnabled } from '../src/lib/pack-preferences-model.ts';
132eeceeb362atagen2026-10-25 03:34 UTC4
132eeceeb362atagen2026-10-25 03:34 UTC5
const image = (shortcode: string) => ({
132eeceeb362atagen2026-10-25 03:34 UTC6
  shortcode,
132eeceeb362atagen2026-10-25 03:34 UTC7
  media_id: `mxc://x/${shortcode}`,
132eeceeb362atagen2026-10-25 03:34 UTC8
  reaction_key: `mxc://x/${shortcode}`,
132eeceeb362atagen2026-10-25 03:34 UTC9
  body: null,
132eeceeb362atagen2026-10-25 03:34 UTC10
  mimetype: null,
132eeceeb362atagen2026-10-25 03:34 UTC11
  width: null,
132eeceeb362atagen2026-10-25 03:34 UTC12
  height: null,
132eeceeb362atagen2026-10-25 03:34 UTC13
  usage: ['Sticker' as const]
132eeceeb362atagen2026-10-25 03:34 UTC14
});
132eeceeb362atagen2026-10-25 03:34 UTC15
132eeceeb362atagen2026-10-25 03:34 UTC16
const pack = {
132eeceeb362atagen2026-10-25 03:34 UTC17
  id: 'pack-a',
132eeceeb362atagen2026-10-25 03:34 UTC18
  display_name: 'Pack A',
132eeceeb362atagen2026-10-25 03:34 UTC19
  avatar: null,
132eeceeb362atagen2026-10-25 03:34 UTC20
  attribution: 'source',
132eeceeb362atagen2026-10-25 03:34 UTC21
  source: 'User' as const,
132eeceeb362atagen2026-10-25 03:34 UTC22
  images: [image('one'), image('two')],
132eeceeb362atagen2026-10-25 03:34 UTC23
  editable: true,
132eeceeb362atagen2026-10-25 03:34 UTC24
  enabled_everywhere: false
132eeceeb362atagen2026-10-25 03:34 UTC25
};
132eeceeb362atagen2026-10-25 03:34 UTC26
132eeceeb362atagen2026-10-25 03:34 UTC27
test('disabled image preferences parse only safe nonempty string lists', () => {
132eeceeb362atagen2026-10-25 03:34 UTC28
  const raw = JSON.parse('{"disabled":{"pack-a":["one","one","",2,null],"empty":[],"wrong":"one","__proto__":["hidden"],"constructor":["other"]}}');
132eeceeb362atagen2026-10-25 03:34 UTC29
  const parsed = parseDisabledPackImages(raw);
132eeceeb362atagen2026-10-25 03:34 UTC30
  assert.deepEqual(parsed, JSON.parse('{"pack-a":["one"],"__proto__":["hidden"],"constructor":["other"]}'));
132eeceeb362atagen2026-10-25 03:34 UTC31
  assert.equal(Object.getPrototypeOf(parsed), Object.prototype);
132eeceeb362atagen2026-10-25 03:34 UTC32
  assert.equal(({} as Record<string, unknown>)['hidden'], undefined);
132eeceeb362atagen2026-10-25 03:34 UTC33
  assert.deepEqual(parseDisabledPackImages(null), {});
132eeceeb362atagen2026-10-25 03:34 UTC34
  assert.deepEqual(parseDisabledPackImages({ disabled: [] }), {});
132eeceeb362atagen2026-10-25 03:34 UTC35
});
132eeceeb362atagen2026-10-25 03:34 UTC36
132eeceeb362atagen2026-10-25 03:34 UTC37
test('image preference updates are immutable and remove empty pack entries', () => {
132eeceeb362atagen2026-10-25 03:34 UTC38
  const original = { 'pack-a': ['one'] };
132eeceeb362atagen2026-10-25 03:34 UTC39
  const disabled = withImageEnabled(original, 'pack-a', 'two', false);
132eeceeb362atagen2026-10-25 03:34 UTC40
  assert.deepEqual(original, { 'pack-a': ['one'] });
132eeceeb362atagen2026-10-25 03:34 UTC41
  assert.deepEqual(disabled, { 'pack-a': ['one', 'two'] });
132eeceeb362atagen2026-10-25 03:34 UTC42
  assert.notEqual(disabled, original);
132eeceeb362atagen2026-10-25 03:34 UTC43
  assert.equal(imageEnabled(disabled, 'pack-a', 'two'), false);
132eeceeb362atagen2026-10-25 03:34 UTC44
132eeceeb362atagen2026-10-25 03:34 UTC45
  const enabled = withImageEnabled(disabled, 'pack-a', 'two', true);
132eeceeb362atagen2026-10-25 03:34 UTC46
  const cleared = withImageEnabled(enabled, 'pack-a', 'one', true);
132eeceeb362atagen2026-10-25 03:34 UTC47
  assert.deepEqual(cleared, {});
132eeceeb362atagen2026-10-25 03:34 UTC48
  assert.equal(imageEnabled(cleared, 'pack-a', 'one'), true);
132eeceeb362atagen2026-10-25 03:34 UTC49
});
132eeceeb362atagen2026-10-25 03:34 UTC50
132eeceeb362atagen2026-10-25 03:34 UTC51
test('enabled packs filter hidden images while preserving metadata and source input', () => {
132eeceeb362atagen2026-10-25 03:34 UTC52
  const disabled = { 'pack-a': ['one'] };
132eeceeb362atagen2026-10-25 03:34 UTC53
  const source = [pack];
132eeceeb362atagen2026-10-25 03:34 UTC54
  const result = enabledPacks(source, disabled);
132eeceeb362atagen2026-10-25 03:34 UTC55
  assert.deepEqual(result[0], { ...pack, images: [image('two')] });
132eeceeb362atagen2026-10-25 03:34 UTC56
  assert.notEqual(result, source);
132eeceeb362atagen2026-10-25 03:34 UTC57
  assert.notEqual(result[0], pack);
132eeceeb362atagen2026-10-25 03:34 UTC58
  assert.notEqual(result[0].images, pack.images);
132eeceeb362atagen2026-10-25 03:34 UTC59
  assert.deepEqual(pack.images.map((item) => item.shortcode), ['one', 'two']);
132eeceeb362atagen2026-10-25 03:34 UTC60
});
132eeceeb362atagen2026-10-25 03:34 UTC61
132eeceeb362atagen2026-10-25 03:34 UTC62
test('personal hiding prunes quick reactions while preserving enabled copies and unrelated keys', () => {
132eeceeb362atagen2026-10-25 03:34 UTC63
  const quick = [{ key: 'mxc://x/one', shortcode: 'one' }, { key: '👍', shortcode: 'thumbsup' }];
132eeceeb362atagen2026-10-25 03:34 UTC64
  assert.deepEqual(enabledQuickReactions(quick, [pack], { 'pack-a': ['one'] }), [quick[1]]);
132eeceeb362atagen2026-10-25 03:34 UTC65
  assert.deepEqual(enabledQuickReactions(quick, [pack, { ...pack, id: 'pack-b' }], { 'pack-a': ['one'] }), quick);
132eeceeb362atagen2026-10-25 03:34 UTC66
  assert.deepEqual(enabledQuickReactions(quick, [], {}), quick);
132eeceeb362atagen2026-10-25 03:34 UTC67
});