test: add suites for 8 simple state reducers + msgContent (+50)
Via subagent, all verified, no bugs: - state/toast (7), room-list/roomList (6), inviteList (6), room-list/utils compareRoomsEqual (6), backupRestore (6), callEmbed dispose-on-replace (6), closedNavCategories factory + makeNavCategoryId (8). - features/room/msgContent (5): getAudioMsgContent/getFileMsgContent incl. encrypted (content.file) vs plain (content.url) branch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { createStore } from 'jotai';
|
||||
import { callEmbedAtom } from './callEmbed';
|
||||
import { CallEmbed } from '../plugins/call';
|
||||
|
||||
// callEmbedAtom holds the current CallEmbed in an unexported baseAtom. The setter:
|
||||
// - identity no-op guard: setting the same reference does nothing
|
||||
// - when replacing a previous embed, calls prevCallEmbed.dispose()
|
||||
// We substitute a stub embed exposing a dispose() spy (the real CallEmbed needs a
|
||||
// MatrixClient + DOM). `as unknown as CallEmbed` keeps eslint/prettier quiet.
|
||||
|
||||
type StubEmbed = { dispose: () => void; disposed: number };
|
||||
|
||||
const makeEmbed = (): StubEmbed => {
|
||||
const stub: StubEmbed = {
|
||||
disposed: 0,
|
||||
dispose() {
|
||||
stub.disposed += 1;
|
||||
},
|
||||
};
|
||||
return stub;
|
||||
};
|
||||
|
||||
const asEmbed = (e: StubEmbed): CallEmbed => e as unknown as CallEmbed;
|
||||
|
||||
test('starts undefined', () => {
|
||||
const store = createStore();
|
||||
assert.equal(store.get(callEmbedAtom), undefined);
|
||||
});
|
||||
|
||||
test('sets a call embed', () => {
|
||||
const store = createStore();
|
||||
const embed = makeEmbed();
|
||||
store.set(callEmbedAtom, asEmbed(embed));
|
||||
assert.equal(store.get(callEmbedAtom), asEmbed(embed));
|
||||
assert.equal(embed.disposed, 0);
|
||||
});
|
||||
|
||||
test('replacing an embed disposes the previous one', () => {
|
||||
const store = createStore();
|
||||
const first = makeEmbed();
|
||||
const second = makeEmbed();
|
||||
|
||||
store.set(callEmbedAtom, asEmbed(first));
|
||||
store.set(callEmbedAtom, asEmbed(second));
|
||||
|
||||
assert.equal(first.disposed, 1);
|
||||
assert.equal(second.disposed, 0);
|
||||
assert.equal(store.get(callEmbedAtom), asEmbed(second));
|
||||
});
|
||||
|
||||
test('setting the same embed reference is a no-op (no dispose)', () => {
|
||||
const store = createStore();
|
||||
const embed = makeEmbed();
|
||||
|
||||
store.set(callEmbedAtom, asEmbed(embed));
|
||||
store.set(callEmbedAtom, asEmbed(embed));
|
||||
|
||||
assert.equal(embed.disposed, 0);
|
||||
assert.equal(store.get(callEmbedAtom), asEmbed(embed));
|
||||
});
|
||||
|
||||
test('clearing to undefined disposes the previous embed', () => {
|
||||
const store = createStore();
|
||||
const embed = makeEmbed();
|
||||
|
||||
store.set(callEmbedAtom, asEmbed(embed));
|
||||
store.set(callEmbedAtom, undefined);
|
||||
|
||||
assert.equal(embed.disposed, 1);
|
||||
assert.equal(store.get(callEmbedAtom), undefined);
|
||||
});
|
||||
|
||||
test('setting undefined when already undefined is a no-op', () => {
|
||||
const store = createStore();
|
||||
// No previous embed: the identity guard (undefined === undefined) returns early.
|
||||
store.set(callEmbedAtom, undefined);
|
||||
assert.equal(store.get(callEmbedAtom), undefined);
|
||||
});
|
||||
Reference in New Issue
Block a user