mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
test: Add unit tests for linkPreviewSettings.js
- 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]>
This commit is contained in:
1 parent
9913e484ab
commit
c4fc0cdb16
1 file changed
+199
@@ -0,0 +1,199 @@
|
||||
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
|
||||
});
|
||||
Reference in new issue
Block a user