mirror of
https://github.com/Anarios/return-youtube-dislike.git
synced 2026-09-12 10:22:10 +02:00
e500088e65
Add Firefox data consent, repair contributor sign-in, and introduce optional Hide clutter buttons. Harden video navigation, voting, and action layouts with shared browser regression coverage and reproducible release packaging.
173 lines
6.9 KiB
JavaScript
173 lines
6.9 KiB
JavaScript
jest.mock("../common/vote-client", () => ({ createVoteClient: jest.fn() }));
|
|
jest.mock("./src/data-collection-permissions", () => ({
|
|
hasAuthenticationDataPermission: jest.fn(),
|
|
onAuthenticationDataPermissionRemoved: jest.fn(),
|
|
usesFirefoxDataCollectionConsent: jest.fn(),
|
|
}));
|
|
|
|
const flushCallbacks = () => new Promise((resolve) => setTimeout(resolve, 0));
|
|
const VERSION = "4.0.5";
|
|
const CHANGELOG_URL = "moz-extension://test/changelog/4/changelog_4.0.html";
|
|
|
|
describe("background changelog lifecycle", () => {
|
|
let installedListener;
|
|
let startupListener;
|
|
let stored;
|
|
|
|
beforeEach(() => {
|
|
jest.resetModules();
|
|
stored = {};
|
|
require("../common/vote-client").createVoteClient.mockReturnValue({ ensureRegistered: () => Promise.resolve({}) });
|
|
global.__RYD_LIVE_TEST_BUILD__ = false;
|
|
global.chrome = {
|
|
runtime: {
|
|
getManifest: () => ({ version: VERSION }),
|
|
getURL: (relativePath) => `moz-extension://test/${relativePath}`,
|
|
onMessage: { addListener: jest.fn() },
|
|
onInstalled: { addListener: (listener) => (installedListener = listener) },
|
|
onStartup: { addListener: (listener) => (startupListener = listener) },
|
|
},
|
|
storage: {
|
|
sync: { get: jest.fn(), set: jest.fn(), remove: jest.fn() },
|
|
local: {
|
|
get: jest.fn((keys, callback) => queueMicrotask(() => callback({ ...stored }))),
|
|
set: jest.fn((values, callback) =>
|
|
queueMicrotask(() => {
|
|
Object.assign(stored, values);
|
|
callback?.();
|
|
}),
|
|
),
|
|
remove: jest.fn((keys, callback) =>
|
|
queueMicrotask(() => {
|
|
for (const key of [].concat(keys)) delete stored[key];
|
|
callback?.();
|
|
}),
|
|
),
|
|
},
|
|
onChanged: { addListener: jest.fn() },
|
|
},
|
|
tabs: {
|
|
create: jest.fn((properties, callback) => queueMicrotask(() => callback?.({ id: 1, ...properties }))),
|
|
},
|
|
};
|
|
// Firefox exposes the chrome callback namespace alongside browser.
|
|
global.browser = global.chrome;
|
|
jest.spyOn(console, "debug").mockImplementation(() => {});
|
|
require("./ryd.background");
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.restoreAllMocks();
|
|
delete global.chrome;
|
|
delete global.browser;
|
|
delete global.__RYD_LIVE_TEST_BUILD__;
|
|
});
|
|
|
|
test.each([false, true])("opens the changelog on a fresh install (temporary=%s)", async (temporary) => {
|
|
installedListener({ reason: "install", temporary });
|
|
await flushCallbacks();
|
|
expect(chrome.tabs.create).toHaveBeenCalledTimes(1);
|
|
expect(chrome.tabs.create).toHaveBeenCalledWith({ url: CHANGELOG_URL }, expect.any(Function));
|
|
expect(stored).toEqual({ lastShownChangelogVersion: VERSION });
|
|
});
|
|
|
|
test.each(["install", "update"])("preserves already-seen suppression on %s", async (reason) => {
|
|
stored.lastShownChangelogVersion = "4.0.4";
|
|
installedListener({ reason, temporary: true, previousVersion: "4.0.4" });
|
|
await flushCallbacks();
|
|
expect(chrome.tabs.create).not.toHaveBeenCalled();
|
|
expect(stored).toEqual({ lastShownChangelogVersion: "4.0.4" });
|
|
});
|
|
|
|
test("queues an unseen update and opens it on browser startup", async () => {
|
|
installedListener({ reason: "update", previousVersion: "4.0.4" });
|
|
await flushCallbacks();
|
|
expect(chrome.tabs.create).not.toHaveBeenCalled();
|
|
expect(stored).toEqual({ pendingChangelogVersion: VERSION });
|
|
|
|
startupListener();
|
|
await flushCallbacks();
|
|
expect(chrome.tabs.create).toHaveBeenCalledTimes(1);
|
|
expect(stored).toEqual({ lastShownChangelogVersion: VERSION });
|
|
|
|
startupListener();
|
|
await flushCallbacks();
|
|
expect(chrome.tabs.create).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
test("opens an unseen temporary update immediately after the shown marker is cleared", async () => {
|
|
installedListener({ reason: "update", temporary: true, previousVersion: VERSION });
|
|
await flushCallbacks();
|
|
expect(chrome.tabs.create).toHaveBeenCalledTimes(1);
|
|
expect(chrome.tabs.create).toHaveBeenCalledWith({ url: CHANGELOG_URL }, expect.any(Function));
|
|
expect(stored).toEqual({ lastShownChangelogVersion: VERSION });
|
|
});
|
|
|
|
test("consumes an existing pending changelog when a temporary update opens it", async () => {
|
|
stored.pendingChangelogVersion = VERSION;
|
|
installedListener({ reason: "update", temporary: true, previousVersion: VERSION });
|
|
await flushCallbacks();
|
|
expect(chrome.tabs.create).toHaveBeenCalledTimes(1);
|
|
expect(stored).toEqual({ lastShownChangelogVersion: VERSION });
|
|
});
|
|
|
|
test("does not reopen the changelog on the next already-seen temporary reload", async () => {
|
|
const details = { reason: "update", temporary: true, previousVersion: VERSION };
|
|
installedListener(details);
|
|
await flushCallbacks();
|
|
expect(chrome.tabs.create).toHaveBeenCalledTimes(1);
|
|
|
|
installedListener(details);
|
|
await flushCallbacks();
|
|
expect(chrome.tabs.create).toHaveBeenCalledTimes(1);
|
|
expect(stored).toEqual({ lastShownChangelogVersion: VERSION });
|
|
});
|
|
|
|
test("opens a previously persisted pending version on startup", async () => {
|
|
stored.pendingChangelogVersion = VERSION;
|
|
startupListener();
|
|
await flushCallbacks();
|
|
expect(chrome.tabs.create).toHaveBeenCalledWith({ url: CHANGELOG_URL }, expect.any(Function));
|
|
expect(stored).toEqual({ lastShownChangelogVersion: VERSION });
|
|
});
|
|
|
|
test("clears a redundant pending update when the changelog was already shown", async () => {
|
|
stored.lastShownChangelogVersion = "4.0.4";
|
|
stored.pendingChangelogVersion = VERSION;
|
|
startupListener();
|
|
await flushCallbacks();
|
|
expect(chrome.tabs.create).not.toHaveBeenCalled();
|
|
expect(stored).toEqual({ lastShownChangelogVersion: "4.0.4" });
|
|
});
|
|
|
|
test("does not mark the changelog as shown when tabs.create reports a callback error", async () => {
|
|
chrome.tabs.create.mockImplementationOnce((properties, callback) =>
|
|
queueMicrotask(() => {
|
|
chrome.runtime.lastError = { message: "No browser window is available" };
|
|
try {
|
|
callback(undefined);
|
|
} finally {
|
|
delete chrome.runtime.lastError;
|
|
}
|
|
}),
|
|
);
|
|
installedListener({ reason: "install", temporary: true });
|
|
await flushCallbacks();
|
|
expect(chrome.tabs.create).toHaveBeenCalledTimes(1);
|
|
expect(stored.lastShownChangelogVersion).toBeUndefined();
|
|
expect(chrome.storage.local.set).not.toHaveBeenCalledWith(
|
|
expect.objectContaining({ lastShownChangelogVersion: expect.anything() }),
|
|
expect.any(Function),
|
|
);
|
|
|
|
installedListener({ reason: "install", temporary: true });
|
|
await flushCallbacks();
|
|
expect(chrome.tabs.create).toHaveBeenCalledTimes(2);
|
|
expect(stored).toEqual({ lastShownChangelogVersion: VERSION });
|
|
const shownWrites = chrome.storage.local.set.mock.calls.filter(([values]) =>
|
|
Object.prototype.hasOwnProperty.call(values, "lastShownChangelogVersion"),
|
|
);
|
|
expect(shownWrites).toHaveLength(1);
|
|
});
|
|
});
|