A network switch now puts the outgoing network's tracked tokens away in a new persisted field, networkTrackedTokens, and brings back the incoming network's list, or an empty one, the way endpoints are already kept per network. trackedTokens stays the active network's list, so its readers are unchanged, and the background's switch keeps the lists too because it goes through the same function. The two add-token screens show their common-token picks, which come from the bundled list of mainnet contracts, on Ethereum Mainnet only; adding by contract address works on every network. Settings redraws its tracked-token list after a switch. Model: opus-5-5
103 lines
3.3 KiB
JavaScript
103 lines
3.3 KiB
JavaScript
// Tracked tokens are kept per network, and the two add-token screens offer the
|
|
// bundled token list, which holds Ethereum Mainnet contracts, on Ethereum
|
|
// Mainnet only (https://git.eeqj.de/sneak/AutistMask/issues/523). Driven
|
|
// through the real popup over a stored profile; the same switch made by the
|
|
// background is in tests/coldWorkerChainSwitch.test.js.
|
|
|
|
const {
|
|
bootPopup,
|
|
cleanupPopup,
|
|
unversionedValidProfile,
|
|
TOKEN_ADDRESS,
|
|
} = require("./support/popupBoot");
|
|
|
|
const SEPOLIA_TOKEN = {
|
|
address: TOKEN_ADDRESS,
|
|
symbol: "TST",
|
|
decimals: 18,
|
|
name: "Test Token",
|
|
};
|
|
const MAINNET_TOKEN = {
|
|
address: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
|
symbol: "DAI",
|
|
decimals: 18,
|
|
name: "Dai Stablecoin",
|
|
};
|
|
|
|
afterEach(() => {
|
|
cleanupPopup();
|
|
});
|
|
|
|
// The popup reopened onto SettingsAddToken, on `networkId`.
|
|
function bootOnAddToken(networkId, extra) {
|
|
return bootPopup(
|
|
unversionedValidProfile({
|
|
networkId,
|
|
currentView: "settings-addtoken",
|
|
...extra,
|
|
}),
|
|
);
|
|
}
|
|
|
|
// Picks `networkId` in the Settings network selector, as the user does.
|
|
async function chooseNetwork(boot, networkId) {
|
|
const select = boot.node("settings-network");
|
|
select.value = networkId;
|
|
for (const fn of select.listeners.change) await fn();
|
|
await boot.settle();
|
|
}
|
|
|
|
describe.each([
|
|
["mainnet", false],
|
|
["sepolia", true],
|
|
])("on %s", (networkId, hidden) => {
|
|
test(`the common tokens are hidden: ${hidden}`, async () => {
|
|
const boot = await bootOnAddToken(networkId);
|
|
expect(boot.pageErrors).toEqual([]);
|
|
expect(boot.visibleViews()).toEqual(["settings-addtoken"]);
|
|
expect(boot.hidden("settings-addtoken-common")).toBe(hidden);
|
|
|
|
require("../src/popup/views/addToken").show();
|
|
expect(boot.visibleViews()).toEqual(["add-token"]);
|
|
expect(boot.hidden("add-token-common")).toBe(hidden);
|
|
});
|
|
});
|
|
|
|
test("a token added by contract address on Sepolia is tracked on Sepolia only", async () => {
|
|
const boot = await bootOnAddToken("sepolia", {
|
|
networkTrackedTokens: { mainnet: [MAINNET_TOKEN] },
|
|
});
|
|
const stored = () => boot.storage.read("autistmask");
|
|
const { lookupTokenInfo } = require("../src/shared/balances");
|
|
lookupTokenInfo.mockResolvedValueOnce({
|
|
symbol: SEPOLIA_TOKEN.symbol,
|
|
decimals: SEPOLIA_TOKEN.decimals,
|
|
name: SEPOLIA_TOKEN.name,
|
|
});
|
|
|
|
boot.node("settings-addtoken-address").value = TOKEN_ADDRESS;
|
|
await boot.click("btn-settings-addtoken-manual");
|
|
|
|
expect(lookupTokenInfo).toHaveBeenCalledWith(
|
|
TOKEN_ADDRESS,
|
|
expect.any(String),
|
|
"sepolia",
|
|
expect.anything(),
|
|
);
|
|
expect(stored().trackedTokens).toEqual([SEPOLIA_TOKEN]);
|
|
|
|
await chooseNetwork(boot, "mainnet");
|
|
expect(stored().networkId).toBe("mainnet");
|
|
expect(stored().trackedTokens).toEqual([MAINNET_TOKEN]);
|
|
const onMainnet = boot.node("settings-tracked-tokens").innerHTML;
|
|
expect(onMainnet).toContain("DAI");
|
|
expect(onMainnet).not.toContain("TST");
|
|
|
|
await chooseNetwork(boot, "sepolia");
|
|
expect(stored().networkId).toBe("sepolia");
|
|
expect(stored().trackedTokens).toEqual([SEPOLIA_TOKEN]);
|
|
const onSepolia = boot.node("settings-tracked-tokens").innerHTML;
|
|
expect(onSepolia).toContain("TST");
|
|
expect(onSepolia).not.toContain("DAI");
|
|
});
|