71 lines
4.0 KiB
JavaScript
71 lines
4.0 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import {
|
|
UI_MODE_STORAGE_KEY,
|
|
buildUiModeUrl,
|
|
persistUiModePreference,
|
|
prefersLiteUi,
|
|
readUiModePreference,
|
|
resolveUiRoute,
|
|
} from "../src/lib/ui-mode.ts";
|
|
|
|
const location = (path = "/") => new URL(path, "https://sybil.test");
|
|
const reader = { userAgent: "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/531.2 Kindle/3.0" };
|
|
|
|
test("clear reader tokens and explicit data saving select Lite without treating all mobile devices as readers", () => {
|
|
assert.equal(prefersLiteUi(reader), true);
|
|
assert.equal(prefersLiteUi({ userAgent: "Kobo Touch" }), true);
|
|
assert.equal(prefersLiteUi({ userAgent: "PocketBook/1.0" }), true);
|
|
assert.equal(prefersLiteUi({ userAgent: "Mozilla/5.0 Silk/44.1 like Chrome/44.0" }), false);
|
|
assert.equal(prefersLiteUi({ userAgent: "Mozilla/5.0 Kindle Fire Build/ABC" }), false);
|
|
assert.equal(prefersLiteUi({ userAgent: "Mozilla/5.0 iPhone Mobile Safari" }), false);
|
|
assert.equal(prefersLiteUi({ userAgent: "Mozilla/5.0 Android Mobile Chrome/140" }), false);
|
|
assert.equal(prefersLiteUi({ saveData: true }), true);
|
|
assert.equal(prefersLiteUi({}), false);
|
|
});
|
|
|
|
test("automatic routing preserves deep links and hashes and only applies at the workspace entry", () => {
|
|
assert.deepEqual(resolveUiRoute(location("/?chat=abc&extra=value#reply"), reader, null), {
|
|
mode: "lite", url: "/lite?chat=abc&extra=value#reply", preference: null,
|
|
});
|
|
assert.equal(resolveUiRoute(location("/?agent=root"), reader, null).url, "/lite?agent=root");
|
|
assert.equal(resolveUiRoute(location("/search?q=eink"), reader, "lite").url, "/search?q=eink");
|
|
assert.equal(resolveUiRoute(location("/other"), reader, "lite").url, "/other");
|
|
});
|
|
|
|
test("explicit preference wins over detection and storage; a direct Lite visit wins over stored full", () => {
|
|
assert.deepEqual(resolveUiRoute(location("/?ui=full&chat=a"), reader, "lite"), {
|
|
mode: "full", url: "/?ui=full&chat=a", preference: "full",
|
|
});
|
|
assert.equal(resolveUiRoute(location("/?ui=lite"), {}, "full").url, "/lite?ui=lite");
|
|
assert.equal(resolveUiRoute(location("/lite?ui=full&chat=a"), reader, "lite").url, "/?ui=full&chat=a");
|
|
assert.equal(resolveUiRoute(location("/lite/"), {}, "full").url, "/lite");
|
|
assert.equal(resolveUiRoute(location("/"), {}, "lite").url, "/lite");
|
|
assert.equal(resolveUiRoute(location("/"), reader, "full").url, "/");
|
|
assert.equal(resolveUiRoute(location("/?ui=invalid"), {}, null).url, "/?ui=invalid");
|
|
});
|
|
|
|
test("manual mode links preserve workspace selection, standalone query and hash", () => {
|
|
assert.equal(buildUiModeUrl("lite", location("/?chat=abc&ui=full#reply")), "/lite?chat=abc&ui=lite#reply");
|
|
assert.equal(buildUiModeUrl("full", location("/lite?search=abc&ui=lite")), "/?search=abc&ui=full");
|
|
assert.equal(buildUiModeUrl("lite", location("/search?q=black+tea")), "/lite?q=black+tea&ui=lite");
|
|
assert.equal(buildUiModeUrl("full", location("/lite?q=black+tea")), "/search?q=black+tea&ui=full");
|
|
assert.equal(buildUiModeUrl("full", location("/lite?q=old&chat=current")), "/?q=old&chat=current&ui=full");
|
|
assert.equal(resolveUiRoute(location("/lite?q=black+tea&ui=full"), {}, null).url, "/search?q=black+tea&ui=full");
|
|
});
|
|
|
|
test("mode preference survives visits but denied or malformed storage cannot block startup", () => {
|
|
const values = new Map();
|
|
const storage = { getItem: key => values.get(key) ?? null, setItem: (key, value) => values.set(key, value) };
|
|
assert.equal(readUiModePreference(storage), null);
|
|
persistUiModePreference(storage, "lite");
|
|
assert.equal(readUiModePreference(storage), "lite");
|
|
values.set(UI_MODE_STORAGE_KEY, "unknown");
|
|
assert.equal(readUiModePreference(storage), null);
|
|
const blocked = { getItem() { throw new Error("denied"); }, setItem() { throw new Error("denied"); } };
|
|
assert.equal(readUiModePreference(blocked), null);
|
|
assert.doesNotThrow(() => persistUiModePreference(blocked, "full"));
|
|
assert.equal(readUiModePreference(null), null);
|
|
assert.doesNotThrow(() => persistUiModePreference(null, "lite"));
|
|
});
|