Files
rustpad/tests/share_url_test.mjs
T

91 lines
2.9 KiB
JavaScript

import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import test from "node:test";
const origin = "https://pad.example";
let currentUrl;
let historyCall;
let dispatchedEvent;
globalThis.CustomEvent = class CustomEvent {
constructor(type, init = {}) {
this.type = type;
this.detail = init.detail;
}
};
globalThis.window = {
location: null,
history: {
pushState(state, _title, url) {
historyCall = { method: "pushState", state };
setLocation(url);
},
replaceState(state, _title, url) {
historyCall = { method: "replaceState", state };
setLocation(url);
},
},
dispatchEvent(event) {
dispatchedEvent = event;
},
};
function setLocation(value) {
currentUrl = new URL(value, origin);
window.location = {
get href() { return currentUrl.href; },
get search() { return currentUrl.search; },
};
}
function resetWindow(value) {
setLocation(value);
historyCall = undefined;
dispatchedEvent = undefined;
}
const source = await readFile(new URL("../static/js/url-state.js", import.meta.url), "utf8");
const moduleUrl = `data:text/javascript;base64,${Buffer.from(source).toString("base64")}`;
const { currentShareUrl, readEditorState, writeEditorState } = await import(moduleUrl);
test("editor state reads supported values", () => {
resetWindow("/w/demo/n/note?view=preview&mode=text");
assert.deepEqual(readEditorState(), { view: "preview", mode: "text" });
});
test("editor state rejects unsupported values", () => {
resetWindow("/w/demo/n/note?view=invalid&mode=html");
assert.deepEqual(readEditorState(), { view: "split", mode: "markdown" });
});
test("writing editor state preserves unrelated query and hash", () => {
resetWindow("/w/demo/n/note?filter=recent#section");
const result = new URL(writeEditorState({ view: "edit", mode: "text" }));
assert.equal(result.searchParams.get("filter"), "recent");
assert.equal(result.searchParams.get("view"), "edit");
assert.equal(result.searchParams.get("mode"), "text");
assert.equal(result.hash, "#section");
assert.equal(historyCall.method, "pushState");
assert.deepEqual(historyCall.state, { view: "edit", mode: "text" });
assert.equal(dispatchedEvent.type, "rustpad:urlchange");
});
test("replace mode uses replaceState", () => {
resetWindow("/p/demo");
writeEditorState({ view: "split", mode: "markdown" }, { replace: true });
assert.equal(historyCall.method, "replaceState");
});
test("current share URL adds view state without inventing access tokens", () => {
resetWindow("/w/demo/n/note?filter=recent#section");
const result = new URL(currentShareUrl({ view: "preview", mode: "markdown" }));
assert.equal(result.searchParams.get("filter"), "recent");
assert.equal(result.searchParams.get("view"), "preview");
assert.equal(result.searchParams.get("mode"), "markdown");
assert.equal(result.searchParams.has("share"), false);
assert.equal(result.hash, "#section");
});