mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 16:02:26 +00:00
186 lines
6.1 KiB
JavaScript
186 lines
6.1 KiB
JavaScript
import './setup-test-env.js';
|
|
import { NostrClient } from '../../js/nostr/client.js';
|
|
import { buildVideoPostEvent, buildViewEvent, NOTE_TYPES } from '../../js/nostrEventSchemas.js';
|
|
import * as NostrTools from 'nostr-tools';
|
|
|
|
const bytesToHex = (bytes) => {
|
|
return Buffer.from(bytes).toString('hex');
|
|
};
|
|
|
|
const RELAYS = [
|
|
"wss://relay.damus.io",
|
|
"wss://nos.lol"
|
|
];
|
|
|
|
async function runTests() {
|
|
console.log("Starting Protocol & Interop Tests...");
|
|
|
|
// --- Setup ---
|
|
console.log("[Setup] Generating ephemeral keys...");
|
|
const aliceSkBytes = NostrTools.generateSecretKey();
|
|
const aliceSk = bytesToHex(aliceSkBytes);
|
|
const alicePk = NostrTools.getPublicKey(aliceSkBytes);
|
|
|
|
const bobSkBytes = NostrTools.generateSecretKey();
|
|
const bobSk = bytesToHex(bobSkBytes);
|
|
const bobPk = NostrTools.getPublicKey(bobSkBytes);
|
|
|
|
console.log(`[Setup] Alice: ${alicePk}`);
|
|
console.log(`[Setup] Bob: ${bobPk}`);
|
|
|
|
const aliceClient = new NostrClient();
|
|
aliceClient.relays = [...RELAYS];
|
|
aliceClient.readRelays = [...RELAYS];
|
|
aliceClient.writeRelays = [...RELAYS];
|
|
|
|
const bobClient = new NostrClient();
|
|
bobClient.relays = [...RELAYS];
|
|
bobClient.readRelays = [...RELAYS];
|
|
bobClient.writeRelays = [...RELAYS];
|
|
|
|
console.log("[Setup] Connecting clients...");
|
|
// Initialize to connect
|
|
await aliceClient.init(); // This might try to load stored session, but shouldn't matter
|
|
await bobClient.init();
|
|
|
|
// Register signers
|
|
await aliceClient.registerPrivateKeySigner({ privateKey: aliceSk, pubkey: alicePk });
|
|
aliceClient.pubkey = alicePk; // Explicitly set client pubkey to ensure correct signer resolution
|
|
|
|
await bobClient.registerPrivateKeySigner({ privateKey: bobSk, pubkey: bobPk });
|
|
bobClient.pubkey = bobPk; // Explicitly set client pubkey to ensure correct signer resolution
|
|
|
|
let testsPassed = 0;
|
|
let testsTotal = 0;
|
|
|
|
// --- Test A: Video Post ---
|
|
testsTotal++;
|
|
console.log("\n[Test A] Publishing VIDEO_POST...");
|
|
try {
|
|
const videoPayload = {
|
|
version: 3,
|
|
title: "Interop Test Video " + Date.now(),
|
|
description: "This is a test video event.",
|
|
videoRootId: "interop-test-" + Date.now(),
|
|
mode: "dev",
|
|
isPrivate: false,
|
|
isNsfw: false,
|
|
isForKids: false,
|
|
enableComments: true
|
|
};
|
|
|
|
// We use signAndPublishEvent directly with a manually built event to test the schema helper
|
|
const event = buildVideoPostEvent({
|
|
pubkey: alicePk,
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
dTagValue: videoPayload.videoRootId,
|
|
content: videoPayload
|
|
});
|
|
|
|
const { signedEvent } = await aliceClient.signAndPublishEvent(event);
|
|
console.log(`[Test A] Published event ${signedEvent.id}`);
|
|
|
|
// Verify
|
|
console.log("[Test A] Verifying roundtrip...");
|
|
// Give relays a moment
|
|
await new Promise(r => setTimeout(r, 2000));
|
|
|
|
// getEventById returns the Video object (converted), but we can ask for raw too
|
|
const result = await bobClient.getEventById(signedEvent.id, { includeRaw: true });
|
|
if (!result || !result.rawEvent) throw new Error("Failed to fetch event back");
|
|
|
|
const fetched = result.rawEvent;
|
|
if (fetched.id !== signedEvent.id) throw new Error("Fetched ID mismatch");
|
|
|
|
// Parse content
|
|
const content = typeof fetched.content === 'string' ? JSON.parse(fetched.content) : fetched.content;
|
|
if (content.title !== videoPayload.title) throw new Error("Content mismatch: title");
|
|
|
|
console.log("[Test A] PASSED");
|
|
testsPassed++;
|
|
} catch (e) {
|
|
console.error("[Test A] FAILED:", e);
|
|
}
|
|
|
|
// --- Test B: View Event ---
|
|
testsTotal++;
|
|
console.log("\n[Test B] Publishing VIEW_EVENT...");
|
|
try {
|
|
const viewEvent = buildViewEvent({
|
|
pubkey: alicePk,
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
pointerValue: "test-video-pointer", // Arbitrary pointer for test
|
|
content: "view-test"
|
|
});
|
|
|
|
const { signedEvent: signedView } = await aliceClient.signAndPublishEvent(viewEvent);
|
|
console.log(`[Test B] Published view event ${signedView.id}`);
|
|
|
|
await new Promise(r => setTimeout(r, 2000));
|
|
|
|
// Bob fetches raw event
|
|
const fetchedView = await bobClient.fetchRawEventById(signedView.id);
|
|
if (!fetchedView) throw new Error("Failed to fetch view event");
|
|
if (fetchedView.id !== signedView.id) throw new Error("View event ID mismatch");
|
|
|
|
console.log("[Test B] PASSED");
|
|
testsPassed++;
|
|
} catch (e) {
|
|
console.error("[Test B] FAILED:", e);
|
|
}
|
|
|
|
// --- Test C: Direct Message ---
|
|
testsTotal++;
|
|
console.log("\n[Test C] Sending Direct Message...");
|
|
try {
|
|
const message = "Hello Bob, this is Alice " + Date.now();
|
|
const npubBob = NostrTools.nip19.npubEncode(bobPk);
|
|
|
|
const sendResult = await aliceClient.sendDirectMessage(npubBob, message);
|
|
if (!sendResult.ok) throw new Error("Failed to send DM: " + (sendResult.error || "unknown"));
|
|
console.log("[Test C] DM sent successfully");
|
|
|
|
await new Promise(r => setTimeout(r, 3000));
|
|
|
|
console.log("[Test C] Bob checking messages...");
|
|
// Force bob to list messages (which triggers decryption using his registered signer)
|
|
const messages = await bobClient.listDirectMessages(bobPk, { limit: 5 });
|
|
|
|
const received = messages.find(m => m.plaintext === message);
|
|
if (!received) {
|
|
console.log("Received messages:", messages.map(m => m.plaintext));
|
|
throw new Error("Bob did not find the specific message");
|
|
}
|
|
|
|
if (received.sender.pubkey !== alicePk) {
|
|
console.log(`[Test C] Sender mismatch: Expected ${alicePk}, got ${received.sender.pubkey}`);
|
|
throw new Error("Sender mismatch");
|
|
}
|
|
|
|
console.log("[Test C] PASSED");
|
|
testsPassed++;
|
|
} catch (e) {
|
|
console.error("[Test C] FAILED:", e);
|
|
}
|
|
|
|
// --- Summary ---
|
|
console.log("\n---------------------------------------------------");
|
|
console.log(`Tests Completed: ${testsPassed}/${testsTotal}`);
|
|
|
|
aliceClient.logout();
|
|
bobClient.logout();
|
|
|
|
if (testsPassed === testsTotal) {
|
|
console.log("ALL TESTS PASSED");
|
|
process.exit(0);
|
|
} else {
|
|
console.error("SOME TESTS FAILED");
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
runTests().catch(e => {
|
|
console.error("Unhandled execution error:", e);
|
|
process.exit(1);
|
|
});
|