From da464201f3360068e39c9c5b0247b2c3cdd9480b Mon Sep 17 00:00:00 2001 From: sneak Date: Mon, 21 Sep 2026 07:29:47 +0000 Subject: [PATCH] chore: keep the internal view id out of the release banner (closes #375) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The debug/testnet banner appended the active view's internal id, so the user saw text like "[TESTNET] (approve-tx)" — developer vocabulary, and on the approval screen it sat directly above the carefully worded line stating what is being authorized. The view id is now gated on the compile-time DEBUG constant instead of 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, which is what a release build shows. Model: opus-4-8 --- TODO.md | 10 +++++++ src/popup/views/helpers.js | 7 ++++- tests/debugBanner.test.js | 59 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 tests/debugBanner.test.js 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]"); + }); +});