mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
WebTorrent (handleTorrentStream) hardening:
- Resolve only when playback is actually viable (loadeddata/canplay/playing),
not the instant streamTo() is called. A dead/too-slow swarm is no longer
reported as success, so the caller's fallback can run.
- Pre-playback torrent errors reject (caller falls back); post-playback errors
go to an onPlaybackError hook instead of a dead reject().
- Mid-stream stall watchdog surfaces an onStall hook ("waiting for peers").
- Fix a <video> listener leak: stream listeners are tracked and torn down
before the next stream and on cleanup() (the modal reuses one element).
- Stream the largest decodable file from a multi-file torrent and deselect the
rest (wider ext set: mp4/m4v/webm/mkv/mov/ogv/ogg) so the swarm isn't spent
downloading files we never play.
playbackCoordinator wires onStall/onPlaybackError to user-facing status.
Forced-source deep links (test affordance):
- The main app honors ?v=<nevent>&playback=torrent|url (mirrors the embed
player) to force a playback path; a missing source shows a clear message.
- The video share menu gains "Copy WebTorrent URL" / "Copy CDN URL" items that
copy the forced-source deep link (disabled with a reason when unavailable).
Tests: webtorrent-handlers (resolve-on-readiness, pre/post-ready errors, stall
fires/clears, largest-file select/deselect, no listener accumulation),
playback-forced-source (param normalization), videoMenuRenderers (copy items +
availability). All mutation-verified.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
36 lines
1.3 KiB
JavaScript
36 lines
1.3 KiB
JavaScript
// Unit test for the forced-source deep-link normalizer.
|
|
//
|
|
// SCN-forced-source-deep-link:
|
|
// Given a `?playback=` deep-link value (or a caller hint),
|
|
// When normalized,
|
|
// Then it maps to the canonical 'url' | 'torrent' the playback pipeline
|
|
// understands (accepting the friendly aliases shown in the UI toggle),
|
|
// And anything unset/unrecognized yields null so normal source selection runs
|
|
// (a bad value must NEVER silently coerce to a real source).
|
|
|
|
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { normalizeForcedSource } from "../js/app/playbackCoordinator.js";
|
|
|
|
test("maps torrent aliases to 'torrent'", () => {
|
|
for (const v of ["torrent", "p2p", "P2P", "WebTorrent", "magnet", " torrent "]) {
|
|
assert.equal(normalizeForcedSource(v), "torrent", `"${v}" -> torrent`);
|
|
}
|
|
});
|
|
|
|
test("maps CDN/url aliases to 'url'", () => {
|
|
for (const v of ["url", "cdn", "CDN", "hosted", "http", "https", " URL "]) {
|
|
assert.equal(normalizeForcedSource(v), "url", `"${v}" -> url`);
|
|
}
|
|
});
|
|
|
|
test("returns null for unset / unrecognized / non-string values", () => {
|
|
for (const v of ["", "bogus", "torrnt", "0", null, undefined, 42, {}, []]) {
|
|
assert.equal(
|
|
normalizeForcedSource(v),
|
|
null,
|
|
`${JSON.stringify(v)} must not coerce to a real source`,
|
|
);
|
|
}
|
|
});
|