fix: Settings stores the URL on screen when another page stored a different one (closes #688) #694

Merged
clawbot merged 1 commits from issue-688-save-writes-url into next 2026-10-27 12:36:49 +01:00
2 changed files with 55 additions and 0 deletions
Showing only changes of commit 8399172f14 - Show all commits
+6
View File
@@ -334,6 +334,11 @@ function showNewSettings() {
// src/popup/index.js) between setting the URL and writing it. If the active
// network is no longer `networkId`, on this page or in the stored record,
// nothing is saved. The flash message then says that the network changed.
//
// The save writes only the fields that differ from what this page last saved.
// Another page may have stored a different URL since then. So `url` is set in
// the stored record too. "Saved." then means that the stored record holds
// `url`.
async function saveEndpoint(field, url, networkId) {
let refused = false;
await saveState((stored) => {
@@ -341,6 +346,7 @@ async function saveEndpoint(field, url, networkId) {
state.networkId !== networkId || stored.networkId !== networkId;
if (refused) return false;
state[field] = url;
stored[field] = url;
});
if (refused) {
showFlash("The URL was not saved because the network changed.");
+49
View File
@@ -0,0 +1,49 @@
// Another page stores a different RPC or Blockscout URL for the same network.
// Then the user taps "Save" in Settings on this page, on the URL that this page
// loaded. The URL on screen is stored, and the flash message reads "Saved."
// (https://git.eeqj.de/sneak/AutistMask/issues/688). Driven through the real
// popup over a stored profile on Ethereum Mainnet.
const {
bootPopup,
cleanupPopup,
unversionedValidProfile,
} = require("./support/popupBoot");
const { NETWORKS } = require("../src/shared/networks");
afterEach(() => {
cleanupPopup();
});
test.each([
{ button: "btn-save-rpc", input: "settings-rpc", field: "rpcUrl" },
{
button: "btn-save-blockscout",
input: "settings-blockscout",
field: "blockscoutUrl",
},
])(
"$button stores the URL on screen after another page stored a different one",
async ({ button, input, field }) => {
const page = await bootPopup(unversionedValidProfile());
await page.click("btn-settings");
const url = page.value(input);
// This write sends this page no storage change event.
page.storage.write("autistmask", {
...page.storage.read("autistmask"),
[field]: "https://other-page.example.invalid",
});
// This answer passes both endpoint checks on Ethereum Mainnet. The RPC
// check reads Ethereum Mainnet's chain id from it. The Blockscout check
// reads `ok`.
globalThis.fetch.mockResolvedValue({
ok: true,
json: async () => ({ result: NETWORKS.mainnet.chainId }),
});
await page.click(button);
expect(page.storage.read("autistmask")[field]).toBe(url);
expect(page.text("flash-msg")).toBe("Saved.");
},
);