mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-31 09:52:24 +00:00
244 lines
7.0 KiB
JavaScript
244 lines
7.0 KiB
JavaScript
import "./test-helpers/setup-localstorage.mjs";
|
|
import assert from "node:assert/strict";
|
|
|
|
if (typeof globalThis.window === "undefined") {
|
|
globalThis.window = {};
|
|
}
|
|
|
|
const originalWindowNostr = window.nostr;
|
|
|
|
window.nostr = {
|
|
...(originalWindowNostr || {}),
|
|
signEvent: async (event) => ({
|
|
...event,
|
|
id: event?.id || `stub-${Math.random().toString(36).slice(2)}`,
|
|
sig: "stub-signature",
|
|
}),
|
|
nip04: {
|
|
...(originalWindowNostr?.nip04 || {}),
|
|
encrypt: async () => "cipher-text",
|
|
},
|
|
};
|
|
|
|
try {
|
|
const { RelayPublishError } = await import("../js/nostrPublish.js");
|
|
const { nostrClient } = await import("../js/nostr.js");
|
|
const { subscriptions } = await import("../js/subscriptions.js");
|
|
const { userBlocks } = await import("../js/userBlocks.js");
|
|
|
|
function createRejectingPool(reason = "relay rejected") {
|
|
const calls = [];
|
|
return {
|
|
calls,
|
|
publish(urls, event) {
|
|
calls.push({
|
|
urls: Array.isArray(urls) ? [...urls] : [],
|
|
event,
|
|
});
|
|
return {
|
|
on(eventName, handler) {
|
|
if (eventName === "failed") {
|
|
handler(new Error(reason));
|
|
}
|
|
return this;
|
|
},
|
|
};
|
|
},
|
|
};
|
|
}
|
|
|
|
function snapshotRelayState(client) {
|
|
return {
|
|
relays: Array.isArray(client.relays) ? [...client.relays] : [],
|
|
readRelays: Array.isArray(client.readRelays)
|
|
? [...client.readRelays]
|
|
: [],
|
|
writeRelays: Array.isArray(client.writeRelays)
|
|
? [...client.writeRelays]
|
|
: [],
|
|
pool: client.pool,
|
|
};
|
|
}
|
|
|
|
function restoreRelayState(client, snapshot) {
|
|
client.relays = [...snapshot.relays];
|
|
client.readRelays = [...snapshot.readRelays];
|
|
client.writeRelays = [...snapshot.writeRelays];
|
|
client.pool = snapshot.pool;
|
|
}
|
|
|
|
function applyTestRelayState(client, relays, pool) {
|
|
client.relays = [...relays];
|
|
client.readRelays = [...relays];
|
|
client.writeRelays = [...relays];
|
|
client.pool = pool;
|
|
}
|
|
|
|
async function testPublishVideoRejectsWhenAllRelaysFail() {
|
|
const testRelays = [
|
|
"wss://relay-a.example",
|
|
"wss://relay-b.example",
|
|
];
|
|
const pool = createRejectingPool("video rejected");
|
|
const relaySnapshot = snapshotRelayState(nostrClient);
|
|
applyTestRelayState(nostrClient, testRelays, pool);
|
|
|
|
try {
|
|
await assert.rejects(
|
|
nostrClient.publishVideo(
|
|
{
|
|
title: "Test video",
|
|
magnet: "magnet:?xt=urn:btih:TESTVIDEO1234567890",
|
|
mode: "live",
|
|
},
|
|
"f".repeat(64)
|
|
),
|
|
(error) => {
|
|
assert.ok(
|
|
error instanceof RelayPublishError,
|
|
"publishVideo should reject with RelayPublishError"
|
|
);
|
|
assert.equal(
|
|
error.relayFailures.length,
|
|
testRelays.length,
|
|
"relayFailures should include every relay"
|
|
);
|
|
const urls = error.relayFailures
|
|
.map((entry) => entry.url)
|
|
.sort();
|
|
assert.deepEqual(
|
|
urls,
|
|
[...testRelays].sort(),
|
|
"relayFailures should include the rejecting relay URLs"
|
|
);
|
|
return true;
|
|
}
|
|
);
|
|
|
|
assert.equal(
|
|
pool.calls.length,
|
|
testRelays.length,
|
|
"publishVideo should attempt each relay"
|
|
);
|
|
} finally {
|
|
restoreRelayState(nostrClient, relaySnapshot);
|
|
}
|
|
}
|
|
|
|
async function testPublishSubscriptionListRejectsWhenAllRelaysFail() {
|
|
const testRelays = [
|
|
"wss://relay-a.example",
|
|
"wss://relay-b.example",
|
|
];
|
|
const pool = createRejectingPool("subscription rejected");
|
|
const relaySnapshot = snapshotRelayState(nostrClient);
|
|
applyTestRelayState(nostrClient, testRelays, pool);
|
|
|
|
const originalSubs = new Set(subscriptions.subscribedPubkeys);
|
|
const originalSubsEventId = subscriptions.subsEventId;
|
|
subscriptions.subscribedPubkeys = new Set(["abcdef1234567890"]);
|
|
subscriptions.subsEventId = null;
|
|
|
|
try {
|
|
await assert.rejects(
|
|
subscriptions.publishSubscriptionList("f".repeat(64)),
|
|
(error) => {
|
|
assert.ok(
|
|
error instanceof RelayPublishError,
|
|
"publishSubscriptionList should reject with RelayPublishError"
|
|
);
|
|
assert.equal(
|
|
error.relayFailures.length,
|
|
testRelays.length,
|
|
"relayFailures should include each relay for subscriptions"
|
|
);
|
|
const urls = error.relayFailures
|
|
.map((entry) => entry.url)
|
|
.sort();
|
|
assert.deepEqual(urls, [...testRelays].sort());
|
|
return true;
|
|
}
|
|
);
|
|
|
|
assert.equal(
|
|
pool.calls.length,
|
|
testRelays.length,
|
|
"publishSubscriptionList should attempt each relay"
|
|
);
|
|
assert.equal(
|
|
subscriptions.subsEventId,
|
|
null,
|
|
"subsEventId should remain unset on failure"
|
|
);
|
|
} finally {
|
|
subscriptions.subscribedPubkeys = originalSubs;
|
|
subscriptions.subsEventId = originalSubsEventId;
|
|
restoreRelayState(nostrClient, relaySnapshot);
|
|
}
|
|
}
|
|
|
|
async function testPublishBlockListRejectsWhenAllRelaysFail() {
|
|
const testRelays = [
|
|
"wss://relay-a.example",
|
|
"wss://relay-b.example",
|
|
];
|
|
const pool = createRejectingPool("block list rejected");
|
|
const relaySnapshot = snapshotRelayState(nostrClient);
|
|
applyTestRelayState(nostrClient, testRelays, pool);
|
|
|
|
const originalBlocked = new Set(userBlocks.blockedPubkeys);
|
|
const originalBlockEventId = userBlocks.blockEventId;
|
|
userBlocks.blockedPubkeys = new Set(["abcd".repeat(16)]);
|
|
userBlocks.blockEventId = null;
|
|
|
|
try {
|
|
await assert.rejects(
|
|
userBlocks.publishBlockList("f".repeat(64)),
|
|
(error) => {
|
|
assert.ok(
|
|
error instanceof RelayPublishError,
|
|
"publishBlockList should reject with RelayPublishError"
|
|
);
|
|
assert.equal(
|
|
error.relayFailures.length,
|
|
testRelays.length,
|
|
"relayFailures should include each relay for block list"
|
|
);
|
|
const urls = error.relayFailures
|
|
.map((entry) => entry.url)
|
|
.sort();
|
|
assert.deepEqual(urls, [...testRelays].sort());
|
|
return true;
|
|
}
|
|
);
|
|
|
|
assert.equal(
|
|
pool.calls.length,
|
|
testRelays.length,
|
|
"publishBlockList should attempt each relay"
|
|
);
|
|
assert.equal(
|
|
userBlocks.blockEventId,
|
|
null,
|
|
"blockEventId should remain unset on failure"
|
|
);
|
|
} finally {
|
|
userBlocks.blockedPubkeys = originalBlocked;
|
|
userBlocks.blockEventId = originalBlockEventId;
|
|
restoreRelayState(nostrClient, relaySnapshot);
|
|
}
|
|
}
|
|
|
|
await testPublishVideoRejectsWhenAllRelaysFail();
|
|
await testPublishSubscriptionListRejectsWhenAllRelaysFail();
|
|
await testPublishBlockListRejectsWhenAllRelaysFail();
|
|
|
|
console.log("nostr publish rejection tests passed");
|
|
} finally {
|
|
if (typeof originalWindowNostr === "undefined") {
|
|
delete window.nostr;
|
|
} else {
|
|
window.nostr = originalWindowNostr;
|
|
}
|
|
}
|