Files
cinny/src/app/features/message-search/useMessageSearch.test.ts
T
jaredandClaude Opus 5 02592ed43c fix(search): apply the date range to server results client-side
from_ts/to_ts are not Matrix filter fields; the server dropped them, so
the range only worked for the local encrypted-room search. Stop sending
them and post-filter server results by origin_server_ts with the same
inclusive predicate. Unit-tested; docs corrected.

Fixes #13

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-12 14:48:35 -04:00

112 lines
3.8 KiB
TypeScript

import { test } from 'node:test';
import assert from 'node:assert/strict';
import {
filterGroupsByDateRange,
filterGroupsByMsgType,
filterGroupsByPinned,
ResultGroup,
} from './useMessageSearch';
// Minimal ResultGroup/ResultItem fixtures — only the fields the filters read
// (event.content.msgtype, event.event_id, group.roomId).
const item = (msgtype: string | undefined, eventId: string) => ({
rank: 1,
event: { event_id: eventId, content: msgtype === undefined ? {} : { msgtype } },
context: {},
});
const tsItem = (eventId: string, ts: number) => ({
rank: 1,
event: { event_id: eventId, origin_server_ts: ts, content: {} },
context: {},
});
const mkGroups = (
...groups: { roomId: string; items: ReturnType<typeof item>[] }[]
): ResultGroup[] => groups as unknown as ResultGroup[];
test('filterGroupsByMsgType: empty filter returns groups unchanged', () => {
const groups = mkGroups({ roomId: '!r1', items: [item('m.text', '$1'), item('m.image', '$2')] });
assert.equal(filterGroupsByMsgType(groups, []), groups);
});
test('filterGroupsByMsgType: keeps only matching msgtypes (union)', () => {
const groups = mkGroups({
roomId: '!r1',
items: [item('m.text', '$1'), item('m.image', '$2'), item('m.file', '$3')],
});
const out = filterGroupsByMsgType(groups, ['m.image', 'm.file']);
assert.equal(out.length, 1);
assert.deepEqual(
out[0].items.map((i) => i.event.event_id),
['$2', '$3'],
);
});
test('filterGroupsByMsgType: drops groups left empty', () => {
const groups = mkGroups(
{ roomId: '!r1', items: [item('m.text', '$1')] },
{ roomId: '!r2', items: [item('m.image', '$2')] },
);
const out = filterGroupsByMsgType(groups, ['m.image']);
assert.equal(out.length, 1);
assert.equal(out[0].roomId, '!r2');
});
test('filterGroupsByMsgType: ignores items with a non-string msgtype', () => {
const groups = mkGroups({ roomId: '!r1', items: [item(undefined, '$1'), item('m.video', '$2')] });
const out = filterGroupsByMsgType(groups, ['m.video']);
assert.equal(out[0].items.length, 1);
assert.equal(out[0].items[0].event.event_id, '$2');
});
test('filterGroupsByDateRange: no bounds returns groups unchanged', () => {
const groups = mkGroups({ roomId: '!r1', items: [tsItem('$1', 100)] });
assert.equal(filterGroupsByDateRange(groups, undefined, undefined), groups);
});
test('filterGroupsByDateRange: keeps only items within an inclusive range', () => {
const groups = mkGroups({
roomId: '!r1',
items: [tsItem('$1', 50), tsItem('$2', 100), tsItem('$3', 150), tsItem('$4', 200)],
});
const out = filterGroupsByDateRange(groups, 100, 150);
assert.deepEqual(
out[0].items.map((i) => i.event.event_id),
['$2', '$3'],
);
});
test('filterGroupsByDateRange: drops groups left empty and supports one-sided bounds', () => {
const groups = mkGroups(
{ roomId: '!r1', items: [tsItem('$1', 50)] },
{ roomId: '!r2', items: [tsItem('$2', 500)] },
);
const out = filterGroupsByDateRange(groups, 100, undefined);
assert.equal(out.length, 1);
assert.equal(out[0].roomId, '!r2');
});
test('filterGroupsByPinned: disabled returns groups unchanged', () => {
const groups = mkGroups({ roomId: '!r1', items: [item('m.text', '$1')] });
assert.equal(
filterGroupsByPinned(groups, false, () => false),
groups,
);
});
test('filterGroupsByPinned: keeps pinned items and drops empty groups', () => {
const groups = mkGroups(
{ roomId: '!r1', items: [item('m.text', '$1'), item('m.text', '$2')] },
{ roomId: '!r2', items: [item('m.text', '$3')] },
);
const pinned = new Set(['!r1/$2']);
const out = filterGroupsByPinned(groups, true, (roomId, eventId) =>
pinned.has(`${roomId}/${eventId}`),
);
assert.equal(out.length, 1);
assert.equal(out[0].roomId, '!r1');
assert.deepEqual(
out[0].items.map((i) => i.event.event_id),
['$2'],
);
});