mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
105 lines
3.4 KiB
JavaScript
105 lines
3.4 KiB
JavaScript
// Run with: node tests/nostr-view-events.test.mjs
|
|
|
|
import "./test-helpers/setup-localstorage.mjs";
|
|
import assert from "node:assert/strict";
|
|
|
|
const {
|
|
deriveViewEventBucketIndex,
|
|
hasRecentViewPublish,
|
|
rememberViewPublish,
|
|
createVideoViewEventFilters,
|
|
getViewEventGuardWindowMs,
|
|
} = await import("../js/nostr/viewEvents.js");
|
|
|
|
async function withMockedNow(initialMs, callback) {
|
|
const originalNow = Date.now;
|
|
let nowMs = initialMs;
|
|
Date.now = () => nowMs;
|
|
const setNow = (nextMs) => {
|
|
nowMs = nextMs;
|
|
};
|
|
try {
|
|
await callback({ setNow, getNow: () => nowMs });
|
|
} finally {
|
|
Date.now = originalNow;
|
|
}
|
|
}
|
|
|
|
async function testRememberViewPublishHonorsGuardWindow() {
|
|
localStorage.clear();
|
|
|
|
const scope = "a:test-pointer";
|
|
const bucket = deriveViewEventBucketIndex(1_700_000_000);
|
|
const windowMs = getViewEventGuardWindowMs();
|
|
|
|
await withMockedNow(1_700_000_000_000, async ({ setNow }) => {
|
|
assert.equal(
|
|
hasRecentViewPublish(scope, bucket),
|
|
false,
|
|
"guard should not report recent publish before remembering",
|
|
);
|
|
|
|
rememberViewPublish(scope, bucket);
|
|
|
|
assert.equal(
|
|
hasRecentViewPublish(scope, bucket),
|
|
true,
|
|
"guard should report recent publish immediately after remembering",
|
|
);
|
|
|
|
const halfWindow = Math.max(1, Math.floor(windowMs / 2));
|
|
setNow(1_700_000_000_000 + halfWindow);
|
|
assert.equal(
|
|
hasRecentViewPublish(scope, bucket),
|
|
true,
|
|
"guard should continue blocking within the same window",
|
|
);
|
|
|
|
setNow(1_700_000_000_000 + windowMs + 5_000);
|
|
assert.equal(
|
|
hasRecentViewPublish(scope, bucket),
|
|
false,
|
|
"guard should allow publishes once the window has elapsed",
|
|
);
|
|
});
|
|
}
|
|
|
|
function assertPointerFilterStructure(filter, pointerValue, label) {
|
|
assert.ok(filter, `${label} filter should be defined`);
|
|
assert.ok(Array.isArray(filter.kinds), `${label} filter should specify kinds`);
|
|
assert.ok(
|
|
Number.isFinite(filter.kinds[0]),
|
|
`${label} filter should target a numeric kind`,
|
|
);
|
|
assert.deepEqual(filter["#t"], ["view"], `${label} filter should require the view tag`);
|
|
assert.deepEqual(filter["#a"] ?? filter["#e"], [pointerValue], `${label} filter should bind the pointer value`);
|
|
}
|
|
|
|
async function testCreateVideoViewEventFiltersForAddressPointer() {
|
|
const pointerValue = "30079:abc:def";
|
|
const pointer = { type: "a", value: pointerValue, relay: "wss://relay.example" };
|
|
const { pointer: descriptor, filters } = createVideoViewEventFilters(pointer);
|
|
|
|
assert.deepEqual(
|
|
descriptor,
|
|
{ type: "a", value: pointerValue, relay: "wss://relay.example" },
|
|
"descriptor should preserve pointer structure",
|
|
);
|
|
|
|
assert.ok(Array.isArray(filters) && filters.length === 1, "default filters should include only the pointer filter");
|
|
assertPointerFilterStructure(filters[0], pointerValue, "primary");
|
|
}
|
|
|
|
async function testCreateVideoViewEventFiltersForEventPointer() {
|
|
const pointerValue = "legacy-event";
|
|
const { filters } = createVideoViewEventFilters({ type: "e", value: pointerValue });
|
|
assert.ok(Array.isArray(filters) && filters.length === 1, "filters should include only the pointer filter");
|
|
assertPointerFilterStructure(filters[0], pointerValue, "primary");
|
|
}
|
|
|
|
await testRememberViewPublishHonorsGuardWindow();
|
|
await testCreateVideoViewEventFiltersForAddressPointer();
|
|
await testCreateVideoViewEventFiltersForEventPointer();
|
|
|
|
console.log("nostr view events tests passed");
|