mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
- Added comprehensive tests for default settings, storage parsing, and error handling. - Covered `setLinkPreviewAutoFetch` and `allowLinkPreviewDomain` (including normalization and silent mode). - Verified `isLinkPreviewDomainAllowed` and event subscriptions. - Mocked `window.dispatchEvent`, `addEventListener`, and `CustomEvent` locally as they are missing from test helpers. Co-authored-by: PR0M3TH3AN <[email protected]>
200 lines
6.3 KiB
JavaScript
200 lines
6.3 KiB
JavaScript
import test, { beforeEach } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
// Mock Event if not present (unlikely in Node 22, but safe)
|
|
if (typeof globalThis.Event === "undefined") {
|
|
globalThis.Event = class Event {
|
|
constructor(type, options = {}) {
|
|
this.type = type;
|
|
this.bubbles = !!options.bubbles;
|
|
this.cancelable = !!options.cancelable;
|
|
}
|
|
};
|
|
}
|
|
|
|
// Mock CustomEvent if not present (Node environment)
|
|
if (typeof globalThis.CustomEvent === "undefined") {
|
|
globalThis.CustomEvent = class CustomEvent extends globalThis.Event {
|
|
constructor(type, options = {}) {
|
|
super(type, options);
|
|
this.detail = options.detail || null;
|
|
}
|
|
};
|
|
}
|
|
|
|
// Mock EventTarget methods on window if not present
|
|
// setup-localstorage.mjs provides window object but not these methods
|
|
if (typeof window.dispatchEvent === "undefined") {
|
|
const listeners = new Map();
|
|
|
|
window.addEventListener = (type, handler) => {
|
|
if (!listeners.has(type)) {
|
|
listeners.set(type, new Set());
|
|
}
|
|
listeners.get(type).add(handler);
|
|
};
|
|
|
|
window.removeEventListener = (type, handler) => {
|
|
if (listeners.has(type)) {
|
|
listeners.get(type).delete(handler);
|
|
}
|
|
};
|
|
|
|
window.dispatchEvent = (event) => {
|
|
const type = event.type;
|
|
if (listeners.has(type)) {
|
|
for (const handler of listeners.get(type)) {
|
|
handler(event);
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
// Helper to clear listeners between tests
|
|
window._clearListeners = () => listeners.clear();
|
|
}
|
|
|
|
// Import the module under test
|
|
import {
|
|
getLinkPreviewSettings,
|
|
setLinkPreviewAutoFetch,
|
|
allowLinkPreviewDomain,
|
|
isLinkPreviewDomainAllowed,
|
|
subscribeToLinkPreviewSettings,
|
|
} from "../js/utils/linkPreviewSettings.js";
|
|
|
|
beforeEach(() => {
|
|
window.localStorage.clear();
|
|
if (window._clearListeners) window._clearListeners();
|
|
});
|
|
|
|
test("getLinkPreviewSettings returns default settings when storage is empty", () => {
|
|
const settings = getLinkPreviewSettings();
|
|
assert.equal(settings.autoFetchUnknownDomains, true);
|
|
assert.deepEqual(settings.allowedDomains, []);
|
|
});
|
|
|
|
test("getLinkPreviewSettings parses stored settings correctly", () => {
|
|
const stored = {
|
|
autoFetchUnknownDomains: false,
|
|
allowedDomains: ["example.com", "test.org"],
|
|
};
|
|
window.localStorage.setItem("bitvid:linkPreviewSettings:v1", JSON.stringify(stored));
|
|
|
|
const settings = getLinkPreviewSettings();
|
|
assert.equal(settings.autoFetchUnknownDomains, false);
|
|
assert.deepEqual(settings.allowedDomains, ["example.com", "test.org"]);
|
|
});
|
|
|
|
test("getLinkPreviewSettings handles corrupted JSON", () => {
|
|
window.localStorage.setItem("bitvid:linkPreviewSettings:v1", "{invalid-json");
|
|
|
|
const settings = getLinkPreviewSettings();
|
|
assert.equal(settings.autoFetchUnknownDomains, true); // Fallback to default
|
|
assert.deepEqual(settings.allowedDomains, []);
|
|
});
|
|
|
|
test("getLinkPreviewSettings sanitizes invalid types in storage", () => {
|
|
const invalidTypes = {
|
|
autoFetchUnknownDomains: "invalid-string", // Should be boolean
|
|
allowedDomains: "not-an-array", // Should be array
|
|
};
|
|
window.localStorage.setItem("bitvid:linkPreviewSettings:v1", JSON.stringify(invalidTypes));
|
|
|
|
const settings = getLinkPreviewSettings();
|
|
assert.equal(settings.autoFetchUnknownDomains, true); // Default
|
|
assert.deepEqual(settings.allowedDomains, []); // Default
|
|
});
|
|
|
|
test("getLinkPreviewSettings handles non-object JSON", () => {
|
|
window.localStorage.setItem("bitvid:linkPreviewSettings:v1", "123");
|
|
|
|
const settings = getLinkPreviewSettings();
|
|
assert.equal(settings.autoFetchUnknownDomains, true);
|
|
assert.deepEqual(settings.allowedDomains, []);
|
|
});
|
|
|
|
test("setLinkPreviewAutoFetch updates setting and persists", () => {
|
|
const newSettings = setLinkPreviewAutoFetch(false);
|
|
assert.equal(newSettings.autoFetchUnknownDomains, false);
|
|
|
|
const stored = JSON.parse(window.localStorage.getItem("bitvid:linkPreviewSettings:v1"));
|
|
assert.equal(stored.autoFetchUnknownDomains, false);
|
|
});
|
|
|
|
test("setLinkPreviewAutoFetch emits event", () => {
|
|
return new Promise((resolve, reject) => {
|
|
subscribeToLinkPreviewSettings((e) => {
|
|
try {
|
|
assert.equal(e.detail.settings.autoFetchUnknownDomains, false);
|
|
resolve();
|
|
} catch (err) {
|
|
reject(err);
|
|
}
|
|
});
|
|
setLinkPreviewAutoFetch(false);
|
|
});
|
|
});
|
|
|
|
test("allowLinkPreviewDomain adds domain and persists", () => {
|
|
let settings = allowLinkPreviewDomain("example.com");
|
|
assert.deepEqual(settings.allowedDomains, ["example.com"]);
|
|
|
|
settings = allowLinkPreviewDomain("TEST.ORG"); // Should normalize
|
|
assert.deepEqual(settings.allowedDomains, ["example.com", "test.org"]);
|
|
|
|
const stored = JSON.parse(window.localStorage.getItem("bitvid:linkPreviewSettings:v1"));
|
|
assert.deepEqual(stored.allowedDomains, ["example.com", "test.org"]);
|
|
});
|
|
|
|
test("allowLinkPreviewDomain ignores duplicates", () => {
|
|
allowLinkPreviewDomain("example.com");
|
|
const settings = allowLinkPreviewDomain("example.com");
|
|
assert.deepEqual(settings.allowedDomains, ["example.com"]);
|
|
});
|
|
|
|
test("allowLinkPreviewDomain respects silent option", () => {
|
|
let eventEmitted = false;
|
|
subscribeToLinkPreviewSettings(() => {
|
|
eventEmitted = true;
|
|
});
|
|
|
|
allowLinkPreviewDomain("silent.com", { silent: true });
|
|
assert.equal(eventEmitted, false);
|
|
|
|
const settings = getLinkPreviewSettings();
|
|
assert.ok(settings.allowedDomains.includes("silent.com"));
|
|
});
|
|
|
|
test("isLinkPreviewDomainAllowed checks against settings", () => {
|
|
allowLinkPreviewDomain("allowed.com");
|
|
|
|
assert.equal(isLinkPreviewDomainAllowed("allowed.com"), true);
|
|
assert.equal(isLinkPreviewDomainAllowed("ALLOWED.COM"), true); // Case insensitive
|
|
assert.equal(isLinkPreviewDomainAllowed("blocked.com"), false);
|
|
});
|
|
|
|
test("isLinkPreviewDomainAllowed checks against provided settings", () => {
|
|
const customSettings = {
|
|
allowedDomains: ["custom.com"],
|
|
};
|
|
|
|
assert.equal(isLinkPreviewDomainAllowed("custom.com", customSettings), true);
|
|
assert.equal(isLinkPreviewDomainAllowed("other.com", customSettings), false);
|
|
});
|
|
|
|
test("subscribeToLinkPreviewSettings returns unsubscribe function", () => {
|
|
let callCount = 0;
|
|
const unsubscribe = subscribeToLinkPreviewSettings(() => {
|
|
callCount++;
|
|
});
|
|
|
|
setLinkPreviewAutoFetch(false);
|
|
assert.equal(callCount, 1);
|
|
|
|
unsubscribe();
|
|
setLinkPreviewAutoFetch(true);
|
|
assert.equal(callCount, 1); // Should not increase
|
|
});
|