mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
145 lines
5.0 KiB
JavaScript
145 lines
5.0 KiB
JavaScript
|
|
import "./test-helpers/setup-localstorage.mjs";
|
|
import { test, describe, it, after, before } from "node:test";
|
|
import assert from "node:assert";
|
|
import EventEmitter from "events";
|
|
import { TorrentClient } from "../js/webtorrent.js";
|
|
|
|
// Mock WebTorrent class
|
|
class MockWebTorrent extends EventEmitter {
|
|
constructor() {
|
|
super();
|
|
this.torrents = [];
|
|
this.setMaxListeners = () => {};
|
|
}
|
|
|
|
add(magnet, opts, cb) {
|
|
const torrent = new MockTorrent(magnet, opts);
|
|
this.torrents.push(torrent);
|
|
|
|
setTimeout(() => {
|
|
if (typeof cb === 'function') cb(torrent);
|
|
this.emit('torrent', torrent);
|
|
|
|
// Simulate webseed connection if urlList is present
|
|
if (opts && Array.isArray(opts.urlList) && opts.urlList.length > 0) {
|
|
torrent.emit('wire', { type: 'webSeed' });
|
|
}
|
|
}, 10);
|
|
|
|
return torrent;
|
|
}
|
|
|
|
destroy(cb) {
|
|
if (typeof cb === 'function') cb();
|
|
}
|
|
}
|
|
|
|
class MockTorrent extends EventEmitter {
|
|
constructor(magnet, opts) {
|
|
super();
|
|
this.magnet = magnet;
|
|
this.opts = opts;
|
|
this.numPeers = 0;
|
|
this.files = [];
|
|
this.wires = [];
|
|
|
|
// Simulate webseeds if provided in opts
|
|
if (opts && Array.isArray(opts.urlList) && opts.urlList.length > 0) {
|
|
// Create mock wires for webseeds
|
|
this.wires = opts.urlList.map(url => ({ type: 'webSeed' }));
|
|
|
|
// Emit wire events asynchronously to simulate connection
|
|
setTimeout(() => {
|
|
this.wires.forEach(wire => this.emit('wire', wire));
|
|
}, 5);
|
|
}
|
|
}
|
|
|
|
destroy(opts, cb) {
|
|
this.destroyed = true;
|
|
this.destroyedDuringWire = this.emittingWire === true;
|
|
if (typeof cb === 'function') cb();
|
|
}
|
|
|
|
emit(eventName, ...args) {
|
|
if (eventName === 'wire') this.emittingWire = true;
|
|
const result = super.emit(eventName, ...args);
|
|
if (eventName === 'wire') this.emittingWire = false;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
describe("WebTorrent Regression Tests", () => {
|
|
before(() => {
|
|
if (typeof global.window === "undefined") {
|
|
global.window = {};
|
|
}
|
|
if (typeof global.window.location === "undefined") {
|
|
global.window.location = { hostname: "localhost" };
|
|
}
|
|
if (typeof global.navigator === "undefined") {
|
|
global.navigator = { userAgent: "node" };
|
|
}
|
|
});
|
|
|
|
it("probePeers should report healthy if webseed is present even with 0 peers", async () => {
|
|
const client = new TorrentClient({ webTorrentClass: MockWebTorrent });
|
|
const magnet = "magnet:?xt=urn:btih:0123456789abcdef0123456789abcdef01234567";
|
|
const webSeedUrl = "http://localhost:8080/video.mp4";
|
|
|
|
const result = await client.probePeers(magnet, {
|
|
timeoutMs: 1000, // Significantly increased timeout for CI robustness
|
|
urlList: [webSeedUrl]
|
|
});
|
|
|
|
if (!result.healthy) {
|
|
console.log("Failed result:", result);
|
|
}
|
|
|
|
// The simplified implementation treats webseeds as peers
|
|
assert.strictEqual(result.healthy, true, "Should be healthy due to webseed");
|
|
assert.strictEqual(result.reason, "peer", "Reason should be 'peer'");
|
|
assert.ok(result.peers >= 1, "Should report at least 1 peer");
|
|
|
|
// Verify that the client ACTUALLY received the webseed in the urlList
|
|
// This ensures we don't regress on passing the parameter
|
|
// Note: probePeers uses 'probeClient', not the main 'client'
|
|
const torrent = client.probeClient.torrents[0];
|
|
assert.ok(torrent, "Torrent should have been created");
|
|
assert.ok(Array.isArray(torrent.opts.urlList), "urlList should be an array");
|
|
assert.ok(torrent.opts.urlList.includes(webSeedUrl), "urlList should contain the webseed URL");
|
|
});
|
|
|
|
it("probePeers should report unhealthy if no webseed and 0 peers", async () => {
|
|
const client = new TorrentClient({ webTorrentClass: MockWebTorrent });
|
|
const magnet = "magnet:?xt=urn:btih:0123456789abcdef0123456789abcdef01234567";
|
|
|
|
// Adding tracker to avoid "no-trackers" immediate return
|
|
const magnetWithTr = magnet + "&tr=wss://tracker.example.com";
|
|
|
|
const result = await client.probePeers(magnetWithTr, {
|
|
timeoutMs: 50,
|
|
urlList: []
|
|
});
|
|
|
|
assert.strictEqual(result.webseedOnly, false, "Should not be webseed only");
|
|
assert.strictEqual(result.healthy, false, "Should be unhealthy");
|
|
assert.strictEqual(result.reason, "timeout", "Reason should be 'timeout'");
|
|
});
|
|
|
|
it("defers probe cleanup until after a successful wire callback returns", async () => {
|
|
const client = new TorrentClient({ webTorrentClass: MockWebTorrent });
|
|
const magnet = "magnet:?xt=urn:btih:0123456789abcdef0123456789abcdef01234567";
|
|
const result = await client.probePeers(magnet, {
|
|
timeoutMs: 1000,
|
|
urlList: ["http://localhost:8080/video.mp4"],
|
|
});
|
|
const torrent = client.probeClient.torrents[0];
|
|
|
|
assert.equal(result.healthy, true);
|
|
assert.equal(torrent.destroyed, true, "temporary probe torrent is cleaned up before its queue slot releases");
|
|
assert.equal(torrent.destroyedDuringWire, false, "probe cleanup is not synchronous with the wire event");
|
|
});
|
|
});
|