Files
YouTubeDL/tests/session.test.mjs
T
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

94 lines
6.5 KiB
JavaScript

import test from "node:test";
import assert from "node:assert/strict";
import { readSession, SESSION_PERMISSION } from "../extension/session.js";
const sampleCookie = value => ({ name: "SAPISID", value, domain: ".youtube.com", path: "/", secure: true, httpOnly: true, hostOnly: false });
test("session access needs both opt-in and permission and does not return secrets to the UI", async () => {
let enabled = false, permission = false, reads = 0;
globalThis.chrome = {
storage: { local: { get: async () => ({ youtubeSession: enabled }) } },
permissions: { contains: async () => permission },
cookies: {
getAllCookieStores: async () => [{ id: "current-profile", tabIds: [42] }],
getAll: async options => {
reads++; assert.equal(options.domain, "youtube.com"); assert.equal(options.storeId, "current-profile");
return [sampleCookie("synthetic-session"), { ...sampleCookie("other"), domain: ".google.com" },
{ ...sampleCookie("evil"), domain: "youtube.com.evil.test" }, { ...sampleCookie("expired"), expirationDate: 1 },
{ ...sampleCookie("partitioned"), partitionKey: { topLevelSite: "https://another.test" } }];
},
},
};
assert.equal((await readSession(42)).status, "disabled"); assert.equal(reads, 0);
enabled = true;
assert.equal((await readSession(42)).status, "permission_required"); assert.equal(reads, 0);
permission = true;
const status = await readSession(42);
assert.equal(status.status, "connected"); assert.ok(!JSON.stringify(status).includes("synthetic-session"));
const authenticated = await readSession(42, true);
assert.equal(authenticated.cookies.length, 1); assert.equal(authenticated.cookies[0].value, "synthetic-session");
await assert.rejects(readSession(999, true), /профиль вкладки/);
});
test("background passes fresh YouTube cookies to both worker actions and never persists them", async () => {
const storage = {}, requests = [], listeners = {}, pendingUi = new Map();
let permission = false, cookieValue = "synthetic-original", cookieReads = 0, nativeListener;
const noEvent = { addListener() {} };
const native = {
onMessage: { addListener(listener) { nativeListener = listener; } }, onDisconnect: noEvent, disconnect() {},
postMessage(message) {
requests.push(message);
const result = message.action === "hello" ? { version: "1.3.2", ready: true, supportsBrowserCookies: true } : message.action === "ping" ? { alive: true }
: message.action === "download" ? { jobId: "auth-test-job" } : { title: "Synthetic video", videos: [], audios: [] };
queueMicrotask(() => nativeListener({ id: message.id, ok: true, result }));
},
};
globalThis.chrome = {
runtime: { id: "test-id", getManifest: () => ({ version: "1.4.5" }), getURL: name => `chrome-extension://test-id/${name}`, connectNative: () => native,
onConnect: { addListener(listener) { listeners.connect = listener; } }, onMessage: noEvent },
permissions: { contains: async () => permission, remove: async input => { assert.deepEqual(input, SESSION_PERMISSION); permission = false; return true; } },
cookies: { getAllCookieStores: async () => [{ id: "0", tabIds: [42] }], getAll: async () => { cookieReads++; return [sampleCookie(cookieValue)]; } },
storage: { local: { get: async key => Object.fromEntries((Array.isArray(key) ? key : [key]).map(name => [name, storage[name]])),
set: async values => Object.assign(storage, structuredClone(values)) } },
notifications: { clear: async () => {}, create: async () => {}, onButtonClicked: noEvent },
tabs: { sendMessage: async () => {} }, action: { onClicked: noEvent, setBadgeText() {}, setBadgeBackgroundColor() {} },
};
await import("../extension/background.js?session-test");
let uiListener;
listeners.connect({ name: "ytdl-ui", sender: { id: "test-id", url: "chrome-extension://test-id/downloader.html" },
onDisconnect: noEvent, onMessage: { addListener(listener) { uiListener = listener; } },
postMessage(message) { if (message.id) { const done = pendingUi.get(message.id); pendingUi.delete(message.id); done(message); } } });
const call = (action, payload = {}) => new Promise(resolve => {
const id = crypto.randomUUID(); pendingUi.set(id, resolve); uiListener({ id, action, payload });
});
assert.equal((await call("hello")).ok, true);
assert.equal((await call("session_enable", { enabled: true, tabId: 42 })).ok, false);
const url = "https://www.youtube.com/watch?v=jNQXAC9IVRw";
await call("inspect", { url, tabId: 42, browserCookies: [sampleCookie("caller-injected")] });
assert.equal(cookieReads, 0); assert.ok(!requests.at(-1).payload.browserCookies);
permission = true;
const enabled = await call("session_enable", { enabled: true, tabId: 42 });
assert.equal(enabled.result.status, "connected"); assert.ok(!JSON.stringify(enabled).includes(cookieValue));
await call("inspect", { url, tabId: 42 });
assert.equal(requests.at(-1).payload.browserCookies[0].value, cookieValue);
const inspectionRequests = requests.filter(request => request.action === "inspect").length;
await call("inspect", { url, tabId: 42 });
assert.equal(requests.filter(request => request.action === "inspect").length, inspectionRequests, "Reuse a recently inspected video's quality without another YouTube request");
await call("inspect", { url, tabId: 42, refresh: true });
assert.equal(requests.filter(request => request.action === "inspect").length, inspectionRequests + 1, "Explicit refresh bypasses the summary cache");
cookieValue = "synthetic-rotated";
await call("download", { url, tabId: 42, title: "Test", folder: "D:/Videos" });
assert.equal(requests.at(-1).payload.browserCookies[0].value, cookieValue);
nativeListener({ event: "job", job: { id: "auth-test-job", status: "complete", stage: "complete", result: { title: "Test", filename: "test.mp4", path: "D:/Videos/test.mp4" } } });
await new Promise(resolve => setTimeout(resolve, 20));
assert.ok(!JSON.stringify(storage).includes("synthetic-")); assert.ok(!JSON.stringify(storage).includes("browserCookies"));
await call("session_enable", { enabled: false, tabId: 42 });
const readsBefore = cookieReads;
await call("inspect", { url, tabId: 42 });
assert.equal(cookieReads, readsBefore); assert.ok(!requests.at(-1).payload.browserCookies);
// An expired/removed permission must still allow ordinary public downloads.
storage.youtubeSession = true;
assert.equal((await call("inspect", { url, tabId: 42, refresh: true })).ok, true);
assert.ok(!requests.at(-1).payload.browserCookies);
});