| 1 | // The crumb copies the page's public address on a tap and says so briefly. |
| 2 | import test from "node:test" ; |
| 3 | import assert from "node:assert/strict" ; |
| 4 | import fs from "node:fs" ; |
| 5 | import vm from "node:vm" ; |
| 6 | |
| 7 | const source = fs.readFileSync("tinyclient/components.js" , "utf8" ); |
| 8 | const linkSource = source.slice(source.indexOf(" // PageLink is the crumb" ), source.indexOf(" // JsonView renders" )); |
| 9 | |
| 10 | function setup({url = "https://relay.example/wiki/notes" , clipboard = true} = {}) { |
| 11 | const written = []; |
| 12 | class HTMLElement { |
| 13 | constructor() { this.dataset = {}; this.listeners = {}; } |
| 14 | getAttribute(name) { return name === "url" ? url : null; } |
| 15 | addEventListener(name, fn) { this.listeners[name] = fn; } |
| 16 | } |
| 17 | const timers = []; |
| 18 | const sandbox = {HTMLElement, navigator: clipboard ? {clipboard: {writeText: async value => { written.push(value); }}} : {}, location: {href: "https://tailnet.example/wiki/notes#x" }, |
| 19 | setTimeout: (fn, ms) => { timers.push({fn, ms}); return timers.length; }, clearTimeout: () => {}}; |
| 20 | const Constructor = vm.runInNewContext(`${linkSource}\nPageLink` , sandbox); |
| 21 | const link = new Constructor(); |
| 22 | link.connectedCallback(); |
| 23 | return {link, written, timers}; |
| 24 | } |
| 25 | |
| 26 | test("a tap copies the public address from the server, not the browser's location" , async () => { |
| 27 | const s = setup(); |
| 28 | s.link.listeners.click(); |
| 29 | await new Promise(resolve => setImmediate(resolve)); |
| 30 | assert.deepEqual(s.written, ["https://relay.example/wiki/notes" ]); |
| 31 | assert.equal(s.link.dataset.copied, "" ); |
| 32 | assert.equal(s.timers[0].ms, 1500); |
| 33 | s.timers[0].fn(); |
| 34 | assert.equal("copied" in s.link.dataset, false); |
| 35 | }); |
| 36 | |
| 37 | test("without a clipboard nothing happens and nothing throws" , async () => { |
| 38 | const s = setup({clipboard: false}); |
| 39 | s.link.listeners.click(); |
| 40 | await new Promise(resolve => setImmediate(resolve)); |
| 41 | assert.deepEqual(s.written, []); |
| 42 | assert.equal("copied" in s.link.dataset, false); |
| 43 | }); |