mirror of
https://github.com/block/buzz.git
synced 2026-10-31 22:41:12 +00:00
## Summary - Adds a pure-TS operator parser (`from:` / `in:` / `after:` / `before:`) with unit tests. Invalid date tokens stay in the FTS text. - Extends `search_messages` so the desktop can send `authors` / `since` / `until` (and existing `#h`) on the filter the relay already understands. - Wires topbar search to strip operators from the prefix query, resolve `in:` against local channels and `from:` against hex pubkeys / known agents, then pass the structured fields through. This is part 1 of #2853 (parser + command plumbing). Autocomplete chips / richer `from:@name` resolution can follow in a second PR. ## Test plan - [x] `node --import ./test-loader.mjs --experimental-strip-types --test src/features/search/lib/parseSearchOperators.test.mjs` - [x] Added `search_messages_filter_emits_operator_fields` unit test (full `buzz-desktop` crate build needs local sidecar binaries in this environment) - [ ] Manual: topbar `deploy from:<hex> after:2024-01-01` emits authors/since on the bridge filter and returns narrowed hits Made with [Cursor](https://cursor.com) --------- Signed-off-by: Jatinder Mahajan <jatinder.mahajan@certifyos.com> Co-authored-by: Jatinder Mahajan <jatinder.mahajan@certifyos.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
82 lines
2.3 KiB
JavaScript
82 lines
2.3 KiB
JavaScript
/**
|
|
* Unit tests for the e2e bridge's mock `search_messages` predicate.
|
|
*
|
|
* The mock stands in for the relay in identity-less E2E runs, so its `since` /
|
|
* `until` comparators must match the relay's inclusive NIP-01 bounds
|
|
* (`crates/buzz-core/src/filter.rs` keeps `since <= created_at <= until`).
|
|
* `before:YYYY-MM-DD` gets its exclusivity from `parseSearchOperators`, which
|
|
* emits `localMidnight - 1`; a mock that also excluded its own bound would
|
|
* drop the last second of the range that production returns.
|
|
*/
|
|
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import { mockSearchHitMatches } from "./e2eBridge.ts";
|
|
|
|
const NO_FILTERS = { query: "", authorSet: null };
|
|
|
|
function hitAt(created_at) {
|
|
return {
|
|
event_id: "hit",
|
|
content: "deploy notes",
|
|
kind: 9,
|
|
pubkey: "a".repeat(64),
|
|
channel_id: "9a1657ac-f7aa-5db0-b632-d8bbeb6dfb50",
|
|
channel_name: "general",
|
|
created_at,
|
|
score: 1,
|
|
};
|
|
}
|
|
|
|
test("until is inclusive, so a before: bound keeps its own second", () => {
|
|
const localMidnight = Math.floor(new Date(2024, 1, 1).getTime() / 1000);
|
|
// What parseSearchOperators emits for `before:2024-02-01`.
|
|
const until = localMidnight - 1;
|
|
|
|
assert.equal(
|
|
mockSearchHitMatches(hitAt(until), { ...NO_FILTERS, until }),
|
|
true,
|
|
);
|
|
assert.equal(
|
|
mockSearchHitMatches(hitAt(localMidnight), { ...NO_FILTERS, until }),
|
|
false,
|
|
);
|
|
});
|
|
|
|
test("since is inclusive and excludes only earlier timestamps", () => {
|
|
const since = Math.floor(new Date(2024, 0, 15).getTime() / 1000);
|
|
|
|
assert.equal(
|
|
mockSearchHitMatches(hitAt(since), { ...NO_FILTERS, since }),
|
|
true,
|
|
);
|
|
assert.equal(
|
|
mockSearchHitMatches(hitAt(since - 1), { ...NO_FILTERS, since }),
|
|
false,
|
|
);
|
|
});
|
|
|
|
test("channel, author, and text filters still narrow results", () => {
|
|
const hit = hitAt(1_700_000_000);
|
|
|
|
assert.equal(
|
|
mockSearchHitMatches(hit, { ...NO_FILTERS, channelId: "other-channel" }),
|
|
false,
|
|
);
|
|
assert.equal(
|
|
mockSearchHitMatches(hit, {
|
|
...NO_FILTERS,
|
|
authorSet: new Set(["b".repeat(64)]),
|
|
}),
|
|
false,
|
|
);
|
|
assert.equal(
|
|
mockSearchHitMatches(hit, { query: "zzz", authorSet: null }),
|
|
false,
|
|
);
|
|
assert.equal(
|
|
mockSearchHitMatches(hit, { query: "deploy", authorSet: null }),
|
|
true,
|
|
);
|
|
});
|