diff --git a/TODO.md b/TODO.md index 55adffe..6f20168 100644 --- a/TODO.md +++ b/TODO.md @@ -45,6 +45,16 @@ but the review is broader than any of them. # Completed Steps +- 2026-09-21: The debug/testnet banner no longer shows the internal view id to + the user in a release build + ([#375](https://git.eeqj.de/sneak/AutistMask/issues/375)). The banner appended + the active view's id (e.g. `[TESTNET] (approve-tx)`), which is developer + vocabulary sitting directly above the approval screen's carefully worded + authorization text. The suffix is now gated on the compile-time `DEBUG` + constant rather than `isDebug()`, so it survives only in a debug build; a + testnet or the runtime debug toggle still raises the banner but without the + view id. + - 2026-09-21: A transaction response is honoured only for a transaction approval, and the three remaining approval-settlement paths are pinned ([#262](https://git.eeqj.de/sneak/AutistMask/issues/262)). The liveness fix diff --git a/src/popup/views/helpers.js b/src/popup/views/helpers.js index 057739f..f1e5f9f 100644 --- a/src/popup/views/helpers.js +++ b/src/popup/views/helpers.js @@ -12,6 +12,7 @@ // escapeHtml lives in src/shared/html.js, where the escape and the // reasoning behind it are; it is re-exported below so views keep importing // it from here. +const { DEBUG } = require("../../shared/constants"); const { escapeHtml } = require("../../shared/html"); const { isDebug } = require("../../shared/log"); const { formatUsd, getPrice } = require("../../shared/prices"); @@ -119,7 +120,11 @@ function updateDebugBanner(viewName) { "background:#c00;color:#fff;text-align:center;font-size:10px;padding:1px 0;font-family:monospace;position:sticky;top:0;z-index:9999;"; document.body.prepend(banner); } - const suffix = viewName ? " (" + viewName + ")" : ""; + // The view id is internal vocabulary; it helps while developing but + // means nothing to a user. Only a debug build appends it, gated on the + // compile-time DEBUG constant so a release build never shows it — not + // isDebug(), which is also true for a testnet or the runtime toggle. + const suffix = DEBUG && viewName ? " (" + viewName + ")" : ""; if (debug && net.isTestnet) { banner.textContent = "DEBUG / INSECURE [TESTNET]" + suffix; } else if (net.isTestnet) { diff --git a/tests/debugBanner.test.js b/tests/debugBanner.test.js new file mode 100644 index 0000000..42e9804 --- /dev/null +++ b/tests/debugBanner.test.js @@ -0,0 +1,59 @@ +// Tests for the debug/testnet banner (issue #375). +// +// On a testnet the banner is raised even in a release build, but it must not +// append the active view's internal id: the user should see "[TESTNET]", never +// "[TESTNET] (approve-tx)". The suffix is gated on the compile-time DEBUG +// constant, which is false in a plain test load, so this drives exactly the +// text a shipped build renders. Revert the gate to the old unconditional +// suffix and this fails. +// +// The banner is created on demand by updateDebugBanner(); the document stub +// records what it prepends so the assertion can read the resulting text. + +function makeBanner() { + return { + id: "", + textContent: "", + style: { cssText: "" }, + remove() {}, + }; +} + +function makeDocument() { + let banner = null; + return { + getElementById(id) { + return id === "debug-banner" ? banner : null; + }, + createElement: () => makeBanner(), + body: { + prepend(node) { + banner = node; + }, + }, + }; +} + +function load() { + jest.resetModules(); + globalThis.chrome = { + storage: { local: { get: async () => ({}), set: async () => {} } }, + }; + globalThis.document = makeDocument(); + const helpers = require("../src/popup/views/helpers"); + const { state } = require("../src/shared/state"); + return { helpers, state }; +} + +describe("the release banner on a testnet", () => { + test("carries no internal view id", () => { + const { helpers, state } = load(); + state.networkId = "sepolia"; + + helpers.updateDebugBanner("approve-tx"); + + expect( + globalThis.document.getElementById("debug-banner").textContent, + ).toBe("[TESTNET]"); + }); +});