mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-31 09:52:24 +00:00
- Added `NIP_INVENTORY.md` tracking compliance status for all referenced NIPs/Kinds. - Added `nip-report-2025-02-12.md` summarizing audit findings. - Added `CONTEXT.md`, `TODO.md`, `DECISIONS.md`, `TEST_LOG.md`. - Added automated regression tests in `tests/compliance/`: - `nip04_44_compliance.test.mjs`: Verifies encryption fallback logic. - `nip65_compliance.test.mjs`: Verifies relay list loading (Kind 10002). - `video_note_compliance.test.mjs`: Verifies video note (Kind 30078) structure and NIP-71 tagging. Co-authored-by: PR0M3TH3AN <[email protected]>
98 lines
3.2 KiB
JavaScript
98 lines
3.2 KiB
JavaScript
|
|
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
// Polyfill minimal window/localStorage
|
|
const localStorageMock = {
|
|
store: new Map(),
|
|
getItem: (key) => localStorageMock.store.get(key) || null,
|
|
setItem: (key, value) => localStorageMock.store.set(key, value),
|
|
removeItem: (key) => localStorageMock.store.delete(key),
|
|
clear: () => localStorageMock.store.clear(),
|
|
};
|
|
|
|
if (typeof globalThis.window === 'undefined') {
|
|
globalThis.window = {
|
|
localStorage: localStorageMock,
|
|
crypto: globalThis.crypto,
|
|
location: { protocol: 'https:' },
|
|
addEventListener: () => {},
|
|
removeEventListener: () => {},
|
|
};
|
|
globalThis.localStorage = localStorageMock;
|
|
}
|
|
|
|
test('NIP-65 Compliance: Relay List Loading', async (t) => {
|
|
// Import dependencies
|
|
const { relayManager } = await import('../../js/relayManager.js');
|
|
const { nostrClient } = await import('../../js/nostrClientFacade.js');
|
|
|
|
const pubkey = "0000000000000000000000000000000000000000000000000000000000000001";
|
|
|
|
// Mock pool
|
|
const mockPool = {
|
|
list: async (relays, filters) => {
|
|
// Return a NIP-65 event
|
|
if (filters.some(f => f.kinds && f.kinds.includes(10002))) {
|
|
return [{
|
|
id: "event1",
|
|
pubkey: pubkey,
|
|
kind: 10002,
|
|
created_at: 1600000000,
|
|
tags: [
|
|
["r", "wss://relay.example.com", "read"],
|
|
["r", "wss://relay.other.com", "write"],
|
|
["r", "wss://relay.both.com"],
|
|
],
|
|
content: ""
|
|
}];
|
|
}
|
|
return [];
|
|
},
|
|
sub: () => ({ on: () => {}, unsub: () => {} }) // shimLegacySimplePoolMethods might wrap this
|
|
};
|
|
|
|
// Inject mock pool
|
|
nostrClient.pool = mockPool;
|
|
nostrClient.ensurePool = async () => mockPool; // Ensure ensurePool returns our mock
|
|
|
|
await t.test('loadRelayList requests Kind 10002', async () => {
|
|
// Spy on list
|
|
let listCalled = false;
|
|
let capturedFilters = null;
|
|
const originalList = mockPool.list;
|
|
mockPool.list = async (relays, filters) => {
|
|
listCalled = true;
|
|
capturedFilters = filters;
|
|
return originalList(relays, filters);
|
|
};
|
|
|
|
await relayManager.loadRelayList(pubkey);
|
|
|
|
assert.ok(listCalled, 'pool.list should be called');
|
|
assert.ok(capturedFilters, 'Filters should be captured');
|
|
const filter = capturedFilters.find(f => f.kinds && f.kinds.includes(10002));
|
|
assert.ok(filter, 'Filter should include kind 10002');
|
|
assert.deepEqual(filter.authors, [pubkey], 'Filter should include correct author');
|
|
});
|
|
|
|
await t.test('loadRelayList parses r tags correctly', async () => {
|
|
const entries = relayManager.getEntries();
|
|
|
|
// Check read relay
|
|
const readRelay = entries.find(e => e.url === "wss://relay.example.com");
|
|
assert.ok(readRelay, 'Read relay should be present');
|
|
assert.equal(readRelay.mode, 'read');
|
|
|
|
// Check write relay
|
|
const writeRelay = entries.find(e => e.url === "wss://relay.other.com");
|
|
assert.ok(writeRelay, 'Write relay should be present');
|
|
assert.equal(writeRelay.mode, 'write');
|
|
|
|
// Check both relay
|
|
const bothRelay = entries.find(e => e.url === "wss://relay.both.com");
|
|
assert.ok(bothRelay, 'Both relay should be present');
|
|
assert.equal(bothRelay.mode, 'both');
|
|
});
|
|
});
|