Files
YouTubeDL/tests/ui-connection.test.mjs
DepressedCat 5f2aad00f4
Check extension and helper / check (push) Canceled after 0s
Publish YouTubeDL 1.4.5 and website on Gitea
2026-10-10 23:53:17 +03:00

74 lines
3.6 KiB
JavaScript

import test from "node:test";
import assert from "node:assert/strict";
import { createUiConnection } from "../extension/ui-connection.js";
function harness() {
const ports = [], events = [];
const runtime = { connect() {
const messages = [], disconnects = [];
const port = { sent: [], dead: false,
onMessage: { addListener: listener => messages.push(listener) },
onDisconnect: { addListener: listener => disconnects.push(listener) },
postMessage(message) {
if (this.dead) throw new Error("Attempting to use a disconnected port object");
this.sent.push(message);
},
respond(result, index = this.sent.length - 1) { messages.forEach(listener => listener({ id: this.sent[index].id, ok: true, result })); },
emit(message) { messages.forEach(listener => listener(message)); },
disconnect() { this.dead = true; disconnects.forEach(listener => listener()); },
};
ports.push(port); return port;
} };
const connection = createUiConnection({ runtime, onEvent: event => events.push(event), onDisconnect: () => events.push({ disconnected: true }) });
return { ...connection, ports, events, runtime };
}
test("a menu reconnects after worker shutdown, without resending an in-flight operation", async () => {
const h = harness();
const pending = h.call("helper_remove");
const rejected = assert.rejects(pending, /Связь с расширением прервана/);
const old = h.ports[0]; old.disconnect(); await rejected;
const next = h.call("helper_start");
assert.equal(h.ports.length, 2); assert.equal(old.sent.length, 1);
assert.equal(h.ports[1].sent[0].action, "helper_start");
h.ports[1].respond({ ready: true }); assert.deepEqual(await next, { ready: true });
// Late events from the old worker must not change the new status.
const count = h.events.length;
old.emit({ event: "helper", helper: { status: "missing" } }); old.disconnect();
assert.equal(h.events.length, count);
h.ports[1].emit({ event: "helper", helper: { status: "running" } });
assert.equal(h.events.at(-1).helper.status, "running");
});
test("a disconnected-port exception before its callback reconnects in the same click", async () => {
const h = harness();
const initial = h.call("hello"); h.ports[0].respond({ ready: true }); await initial;
h.ports[0].dead = true;
const retry = h.call("helper_start");
assert.equal(h.ports.length, 2);
h.ports[0].disconnect();
h.ports[1].respond({ ready: true }); assert.equal((await retry).ready, true);
assert.equal(h.ports[0].sent.length, 1, "Failed post was never delivered");
});
test("repeated disconnected-port failures stop after one retry with a readable error", async () => {
let attempts = 0;
const h = createUiConnection({ runtime: { connect() {
attempts++;
return { onMessage: { addListener() {} }, onDisconnect: { addListener() {} },
postMessage() { throw new Error("Attempting to use a disconnected port object"); } };
} } });
await assert.rejects(h.call("helper_start"), /Проверить подключение/);
assert.equal(attempts, 2);
});
test("helper errors are delivered once and do not replay updates or removal", async () => {
for (const action of ["helper_update", "helper_remove", "download"]) {
const h = harness(), result = h.call(action);
const rejected = assert.rejects(result, /Дождитесь завершения/);
h.ports[0].emit({ id: h.ports[0].sent[0].id, ok: false, error: "Дождитесь завершения загрузок" });
await rejected;
assert.equal(h.ports.length, 1); assert.equal(h.ports[0].sent.length, 1);
}
});