Files
bitvid/tests/magnet-utils.test.mjs
T

226 lines
7.3 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import { WSS_TRACKERS } from "../js/constants.js";
import {
normalizeAndAugmentMagnet as normalizeMagnetObject,
safeDecodeMagnet,
} from "../js/magnetUtils.js";
import {
extractMagnetHints,
normalizeAndAugmentMagnet as normalizeMagnetString,
} from "../js/magnet.js";
function getParamValues(magnet, key) {
const parsed = new URL(magnet);
return parsed.searchParams.getAll(key);
}
function assertDefaultTrackersPresent(magnet) {
const trackers = getParamValues(magnet, "tr");
for (const tracker of WSS_TRACKERS) {
assert.ok(
trackers.includes(tracker),
`Expected default tracker ${tracker} to be present`
);
}
}
test("safeDecodeMagnet handles encoded values", () => {
const rawMagnet =
"magnet:?xt=urn:btih:0123456789abcdef0123456789abcdef01234567&dn=Example";
const encodedMagnet = encodeURIComponent(rawMagnet);
assert.equal(
safeDecodeMagnet(encodedMagnet),
rawMagnet,
"Percent-encoded magnets should be decoded"
);
});
test("safeDecodeMagnet leaves plain strings untouched", () => {
const rawMagnet =
"magnet:?xt=urn:btih:abcdefabcdefabcdefabcdefabcdefabcdefabcd";
assert.equal(
safeDecodeMagnet(rawMagnet),
rawMagnet,
"Plain magnet strings should pass through"
);
});
test("bare hashes normalize consistently across helpers", () => {
const infoHash = "0123456789abcdef0123456789abcdef01234567";
const objectResult = normalizeMagnetObject(infoHash);
const stringResult = normalizeMagnetString(infoHash);
assert.ok(objectResult.didChange, "Bare hashes should mark didChange true");
assert.equal(
stringResult,
objectResult.magnet,
"String helper should match object helper output"
);
const xtValues = getParamValues(stringResult, "xt");
assert.deepEqual(xtValues, [`urn:btih:${infoHash}`]);
assertDefaultTrackersPresent(stringResult);
});
test("legacy %3A payloads decode across helpers", () => {
const infoHash = "abcdefabcdefabcdefabcdefabcdefabcdefabcd";
const encoded = `magnet:?xt=urn%3Abtih%3A${infoHash}&dn=Example`;
const objectResult = normalizeMagnetObject(encoded);
const stringResult = normalizeMagnetString(encoded);
assert.equal(
stringResult,
objectResult.magnet,
"Helpers should agree on encoded xt payload normalization"
);
const xtValues = getParamValues(stringResult, "xt");
assert.deepEqual(xtValues, [`urn:btih:${infoHash}`]);
});
test("duplicate trackers and hints stay in sync", () => {
const infoHash = "fedcba9876543210fedcba9876543210fedcba98";
const baseMagnet =
`magnet:?xt=urn:btih:${infoHash}` +
"&tr=wss://tracker.openwebtorrent.com" +
"&tr=WsS://tracker.openwebtorrent.com/";
const objectResult = normalizeMagnetObject(baseMagnet, {
extraTrackers: [
"http://tracker.invalid",
"wss://tracker.openwebtorrent.com",
],
xs: "https://cdn.example.com/video.torrent",
webSeed: "https://cdn.example.com/files/",
});
const stringResult = normalizeMagnetString(baseMagnet, {
ws: "https://cdn.example.com/files/", // ensure string helper adds hint
xs: "https://cdn.example.com/video.torrent",
});
assert.equal(
stringResult,
objectResult.magnet,
"Helpers should emit identical magnets after augmentation"
);
const trackers = getParamValues(stringResult, "tr");
const openwebCount = trackers.filter(
(value) => value === "wss://tracker.openwebtorrent.com"
).length;
assert.equal(openwebCount, 1, "Duplicate trackers should be deduped when appended");
assert.ok(
!trackers.includes("http://tracker.invalid"),
"HTTP tracker candidates should be ignored"
);
const webSeeds = getParamValues(stringResult, "ws");
assert.deepEqual(webSeeds, ["https://cdn.example.com/files/"]);
const xsValues = getParamValues(stringResult, "xs");
assert.deepEqual(xsValues, ["https://cdn.example.com/video.torrent"]);
});
test("object helper enforces HTTPS web seeds when on HTTPS", () => {
const infoHash = "0123456789abcdef0123456789abcdef01234567";
const messages = [];
const result = normalizeMagnetObject(`magnet:?xt=urn:btih:${infoHash}`, {
webSeed: [
"https://cdn.example.com/video.mp4",
"http://cdn.example.com/legacy.mp4",
],
logger: (msg) => messages.push(msg),
appProtocol: "https:",
});
const seeds = getParamValues(result.magnet, "ws");
assert.deepEqual(seeds, ["https://cdn.example.com/video.mp4"]);
assert.equal(messages.length, 1, "HTTP web seeds should trigger a log message");
assert.ok(
messages[0].includes("Skipping insecure web seed"),
"Expected skip log for HTTP seed"
);
});
test("object helper allows HTTP seeds on HTTP origins", () => {
const infoHash = "abcdefabcdefabcdefabcdefabcdefabcdefabcd";
const result = normalizeMagnetObject(`magnet:?xt=urn:btih:${infoHash}`, {
webSeed: "http://cdn.example.com/video.mp4",
appProtocol: "http:",
});
const seeds = getParamValues(result.magnet, "ws");
assert.deepEqual(seeds, ["http://cdn.example.com/video.mp4"]);
});
test("extractMagnetHints returns first ws/xs pair", () => {
const magnet =
"magnet:?xt=urn:btih:abcdef0123456789abcdef0123456789abcdef01" +
"&ws=https://cdn.example.com/base/" +
"&ws=https://cdn.example.com/duplicate/" +
"&xs=https://cdn.example.com/video.torrent";
const hints = extractMagnetHints(magnet);
assert.deepEqual(hints, {
ws: "https://cdn.example.com/base/",
xs: "https://cdn.example.com/video.torrent",
});
});
test("string helper skips insecure ws hints on HTTPS origins", () => {
const infoHash = "0123456789abcdef0123456789abcdef01234567";
const normalized = normalizeMagnetString(`magnet:?xt=urn:btih:${infoHash}`, {
ws: "http://cdn.example.com/video-base/",
});
const parsed = new URL(normalized);
assert.equal(parsed.searchParams.getAll("ws").length, 0);
});
test("object helper reports didChange when output differs", () => {
const infoHash = "abcdef0123456789abcdef0123456789abcdef01";
const result = normalizeMagnetObject(`magnet:?xt=urn:btih:${infoHash}`, {
webSeed: "https://cdn.example.com/video.mp4",
});
assert.ok(result.didChange, "Augmenting with web seeds should mark didChange");
});
test("helpers trim fragments from non-magnet values", () => {
const url = "https://example.com/video.mp4#fragment";
const objectResult = normalizeMagnetObject(url);
const stringResult = normalizeMagnetString(url);
assert.equal(objectResult.magnet, "https://example.com/video.mp4");
assert.equal(stringResult, "https://example.com/video.mp4");
assert.ok(
objectResult.didChange,
"Dropping the fragment should be reflected in didChange"
);
});
test("normalizeAndAugmentMagnet filters out known broken trackers", () => {
const infoHash = "abcdef0123456789abcdef0123456789abcdef01";
const brokenTrackers = [
"wss://tracker.dler.org/announce",
"wss://tracker.ghostchu-services.top/announce"
];
const rawMagnet =
`magnet:?xt=urn:btih:${infoHash}` +
`&tr=${brokenTrackers[0]}` +
`&tr=${brokenTrackers[1]}`;
const result = normalizeMagnetObject(rawMagnet);
const trackers = getParamValues(result.magnet, "tr");
for (const broken of brokenTrackers) {
assert.ok(
!trackers.includes(broken),
`Expected broken tracker ${broken} to be removed`
);
}
assertDefaultTrackersPresent(result.magnet);
});