Files
bitvid/tests/unit/searchFilters.test.mjs
T
thePR0M3TH3ANandClaude Opus 4.8 a36d57c8b4 tests(11): spec-correct searchFilters author parsing (validated pubkeys)
tests/unit/searchFilters.test.mjs fed author:abc123 and expected
authorPubkeys === ["abc123"] with zero errors. The author filter now runs values
through normalizeAuthorValues (searchFilters.js): it accepts a 64-char hex pubkey
or a decodable npub1 and DROPS anything else (recording an error), because videos
carry HEX pubkeys and npub authors otherwise matched nothing. "abc123" is neither,
so it is correctly dropped → authorPubkeys empty + an error, contradicting this
happy-path test. Equally-strict spec_correction: use a valid 64-hex author so the
test exercises the intended normalization. Verified: # pass 4 # fail 0.

This was the LAST failure in a full per-file scan of all 392 test files (the
fail-fast runner had been surfacing them one at a time).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-05 11:40:04 -04:00

126 lines
3.6 KiB
JavaScript

import assert from "node:assert/strict";
import { test } from "node:test";
import {
parseFilterQuery,
serializeFiltersToQuery,
} from "../../js/search/searchFilters.js";
import { buildVideoSearchFilterMatcher } from "../../js/search/searchFilterMatchers.js";
test("parseFilterQuery collects filters and text tokens", () => {
// spec_correction (todo-11): the author filter now runs values through
// normalizeAuthorValues (searchFilters.js) — it accepts a 64-char hex pubkey
// or a decodable npub1 and DROPS anything else (with an error), because videos
// carry HEX pubkeys and npub authors otherwise matched nothing. The old fixture
// "abc123" is neither hex64 nor an npub, so it is (correctly) dropped, leaving
// authorPubkeys empty and an error — contradicting this happy-path test. Use a
// valid hex pubkey so the test exercises the intended normalization.
const authorHex = "a".repeat(64);
const parsed = parseFilterQuery(
`author:${authorHex} tag:#news duration:<=5m has:magnet nsfw:false hello world`,
);
assert.deepEqual(parsed.filters.authorPubkeys, [authorHex]);
assert.deepEqual(parsed.filters.tags, ["news"]);
assert.equal(parsed.filters.duration.maxSeconds, 300);
assert.equal(parsed.filters.hasMagnet, true);
assert.equal(parsed.filters.nsfw, "false");
assert.equal(parsed.text, "hello world");
assert.equal(parsed.errors.length, 0);
});
test("serializeFiltersToQuery emits filter tokens in order", () => {
const serialized = serializeFiltersToQuery({
authorPubkeys: ["npub123"],
tags: ["clips"],
kind: 30078,
relay: "wss://relay.example",
dateRange: { after: null, before: null },
duration: { minSeconds: 60, maxSeconds: 120 },
hasMagnet: true,
hasUrl: true,
nsfw: "false",
});
assert.equal(
serialized,
"author:npub123 tag:clips kind:30078 relay:wss://relay.example duration:>=1m duration:<=2m has:magnet has:url nsfw:false",
);
});
test("video search filter matcher enforces tags, duration, and nsfw when allowed", () => {
const matcher = buildVideoSearchFilterMatcher(
{
tags: ["cats"],
duration: { minSeconds: 60, maxSeconds: 180 },
hasMagnet: true,
nsfw: "only",
},
{ allowNsfw: true },
);
const videos = [
{
id: "a",
tags: [["t", "cats"]],
nip71: { duration: 120 },
magnet: "magnet:?xt=urn:btih:abc",
isNsfw: true,
},
{
id: "b",
tags: [["t", "cats"]],
nip71: { duration: 240 },
magnet: "magnet:?xt=urn:btih:def",
isNsfw: true,
},
{
id: "c",
tags: [["t", "dogs"]],
nip71: { duration: 120 },
magnet: "magnet:?xt=urn:btih:ghi",
isNsfw: true,
},
{
id: "d",
tags: [["t", "cats"]],
nip71: { duration: 120 },
magnet: "magnet:?xt=urn:btih:jkl",
isNsfw: false,
},
{
id: "e",
tags: [["t", "cats"]],
nip71: { duration: 120 },
url: "https://cdn.example/video.mp4",
isNsfw: true,
},
];
const matches = videos.filter(matcher);
assert.deepEqual(
matches.map((video) => video.id),
["a"],
);
});
test("video search filter matcher blocks nsfw when disallowed and requires url", () => {
const matcher = buildVideoSearchFilterMatcher(
{ hasUrl: true, nsfw: "true" },
{ allowNsfw: false },
);
const videos = [
{ id: "a", url: "https://cdn.example/a.mp4", isNsfw: true },
{ id: "b", url: "https://cdn.example/b.mp4", isNsfw: false },
];
const matches = videos.filter(matcher);
assert.deepEqual(
matches.map((video) => video.id),
["b"],
);
});