chore: remove dead exports and share copied view helpers (closes #168)
AddressDetail and AddressToken defined their own isoDate() and timeAgo(), hiding the shared pair in helpers.js, so a fix there would not have reached them. The copies were identical and are deleted; blockieHtml() and tokenLabel(), each defined twice, move to helpers.js. A new test shows the history rows and the transaction detail view write the time with the shared pair. Deleted as never called: explorerLink(), ETHEREUM_SEPOLIA_CHAIN_ID, getWalletValue() and getTotalValue() with their tests. Home's "Total:" is the active address's total, as README.md already says. addressColor() and etherscanAddressUrl() are no longer exported. Model: opus-5-5
This commit is contained in:
@@ -22,8 +22,6 @@ const {
|
||||
prices,
|
||||
clearPrices,
|
||||
getAddressValue,
|
||||
getWalletValue,
|
||||
getTotalValue,
|
||||
formatAddressTotal,
|
||||
} = require("../src/shared/prices");
|
||||
const { state } = require("../src/shared/state");
|
||||
@@ -136,17 +134,6 @@ describe("the value of an address, and whether it is the whole value", () => {
|
||||
partial: false,
|
||||
});
|
||||
});
|
||||
|
||||
test("one unpriced holding makes a wallet and the grand total partial", () => {
|
||||
const wallet = { addresses: [FULLY_PRICED, UNPRICED_ONLY] };
|
||||
expect(getWalletValue(wallet)).toEqual({ usd: 5500, partial: true });
|
||||
expect(getTotalValue([wallet])).toEqual({ usd: 5500, partial: true });
|
||||
});
|
||||
|
||||
test("a wallet of fully priced addresses stays complete", () => {
|
||||
const wallet = { addresses: [FULLY_PRICED, EMPTY] };
|
||||
expect(getWalletValue(wallet)).toEqual({ usd: 5500, partial: false });
|
||||
});
|
||||
});
|
||||
|
||||
describe("how that value is written on screen", () => {
|
||||
|
||||
@@ -253,8 +253,6 @@ async function bootPopup(stored, options) {
|
||||
formatUsd: () => "",
|
||||
formatAddressTotal: () => "",
|
||||
getAddressValue: () => ({ usd: null, partial: false }),
|
||||
getWalletValue: () => ({ usd: null, partial: false }),
|
||||
getTotalValue: () => ({ usd: null, partial: false }),
|
||||
}));
|
||||
jest.doMock("../../src/shared/balances", () => ({
|
||||
fetchTokenBalances: jest.fn(async () => []),
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
// A transaction's time is written by isoDate() and timeAgo() in
|
||||
// src/popup/views/helpers.js on every screen that shows one (README, Display
|
||||
// Consistency; https://git.eeqj.de/sneak/AutistMask/issues/168). AddressDetail
|
||||
// and AddressToken used to define their own copies, so a fix to the shared pair
|
||||
// would not have reached them.
|
||||
//
|
||||
// The pair is replaced before the views are loaded, because a view takes it
|
||||
// when it loads. A view that writes the time with a copy of its own shows the
|
||||
// real time instead of the replacement.
|
||||
//
|
||||
// Driven against a minimal DOM stub in the shape
|
||||
// tests/contractCreation.test.js uses.
|
||||
|
||||
jest.mock("../src/shared/log", () => ({
|
||||
log: {
|
||||
debugf: () => {},
|
||||
infof: () => {},
|
||||
warnf: () => {},
|
||||
errorf: () => {},
|
||||
},
|
||||
// The transaction detail view fetches on-chain details after drawing; an
|
||||
// answer that is not ok leaves the drawn lines as they are.
|
||||
debugFetch: async () => ({ ok: false }),
|
||||
setRuntimeDebug: () => {},
|
||||
isDebug: () => false,
|
||||
}));
|
||||
|
||||
// The history lists ask the explorer for their transactions and resolve ENS
|
||||
// names for them; here the explorer answers with mockHistory and no name
|
||||
// resolves.
|
||||
let mockHistory = [];
|
||||
jest.mock("../src/shared/transactions", () => ({
|
||||
...jest.requireActual("../src/shared/transactions"),
|
||||
fetchRecentTransactions: async () => mockHistory,
|
||||
}));
|
||||
jest.mock("../src/shared/ens", () => ({
|
||||
...jest.requireActual("../src/shared/ens"),
|
||||
resolveEnsNames: async () => new Map(),
|
||||
}));
|
||||
|
||||
globalThis.chrome = {
|
||||
storage: { local: { get: async () => ({}), set: async () => {} } },
|
||||
};
|
||||
|
||||
const helpers = require("../src/popup/views/helpers");
|
||||
jest.spyOn(helpers, "isoDate").mockReturnValue("SHARED-ISO-DATE");
|
||||
jest.spyOn(helpers, "timeAgo").mockReturnValue("SHARED-TIME-AGO");
|
||||
|
||||
const { state } = require("../src/shared/state");
|
||||
const addressDetail = require("../src/popup/views/addressDetail");
|
||||
const addressToken = require("../src/popup/views/addressToken");
|
||||
const transactionDetail = require("../src/popup/views/transactionDetail");
|
||||
|
||||
const FROM = "0x0000000000000000000000000000000000000a11";
|
||||
const RECIPIENT = "0x66133E8ea0f5D1d612D2502a968757D1048c214a";
|
||||
|
||||
function makeElement(id) {
|
||||
const el = {
|
||||
id,
|
||||
textContent: "",
|
||||
value: "",
|
||||
innerHTML: "",
|
||||
style: {},
|
||||
dataset: {},
|
||||
classList: {
|
||||
add: () => {},
|
||||
remove: () => {},
|
||||
contains: () => false,
|
||||
toggle: () => false,
|
||||
},
|
||||
addEventListener: () => {},
|
||||
querySelectorAll: () => [],
|
||||
appendChild: () => {},
|
||||
};
|
||||
// Views reach for .parentElement to hide whole sections.
|
||||
Object.defineProperty(el, "parentElement", {
|
||||
get: () => node(id + "-parent"),
|
||||
});
|
||||
return el;
|
||||
}
|
||||
|
||||
function makeDocument() {
|
||||
const els = new Map();
|
||||
return {
|
||||
getElementById(id) {
|
||||
// The debug banner is created on demand by helpers.js; absent
|
||||
// is the state a non-debug, non-testnet popup is in.
|
||||
if (id === "debug-banner") return null;
|
||||
if (!els.has(id)) els.set(id, makeElement(id));
|
||||
return els.get(id);
|
||||
},
|
||||
createElement: () => makeElement("created"),
|
||||
body: { prepend: () => {} },
|
||||
};
|
||||
}
|
||||
|
||||
function node(id) {
|
||||
return globalThis.document.getElementById(id);
|
||||
}
|
||||
|
||||
// A transaction FROM sent, as the history lists hold it.
|
||||
function historyTx() {
|
||||
return {
|
||||
hash: "0x85215772ed26ea8b39c2b3b18779030487efbe0b5fd7e882592b2f62b837be84",
|
||||
from: FROM,
|
||||
to: RECIPIENT,
|
||||
value: "0.0000",
|
||||
exactValue: "0.0",
|
||||
rawAmount: "0",
|
||||
rawUnit: "wei",
|
||||
symbol: "ETH",
|
||||
timestamp: 1790000000,
|
||||
isError: false,
|
||||
directionLabel: "Sent",
|
||||
direction: "sent",
|
||||
contractAddress: null,
|
||||
};
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
globalThis.document = makeDocument();
|
||||
globalThis.window = { location: { search: "" } };
|
||||
state.wallets = [
|
||||
{
|
||||
name: "Main",
|
||||
type: "key",
|
||||
addresses: [{ address: FROM, balance: "0.0000" }],
|
||||
},
|
||||
];
|
||||
state.trackedTokens = [];
|
||||
state.viewData = {};
|
||||
state.viewStack = [];
|
||||
state.currentView = null;
|
||||
state.selectedWallet = 0;
|
||||
state.selectedAddress = 0;
|
||||
state.selectedToken = "ETH";
|
||||
});
|
||||
|
||||
describe.each([
|
||||
["AddressDetail", "tx-list", () => addressDetail.show()],
|
||||
["AddressToken", "address-token-tx-list", () => addressToken.show()],
|
||||
])("a transaction history row on %s", (_name, listId, open) => {
|
||||
test("shows the time written by the shared isoDate() and timeAgo()", async () => {
|
||||
mockHistory = [historyTx()];
|
||||
open();
|
||||
// The list is drawn once the history has been fetched.
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
const html = node(listId).innerHTML;
|
||||
expect(html).toContain('title="SHARED-ISO-DATE"');
|
||||
expect(html).toContain(">SHARED-TIME-AGO<");
|
||||
});
|
||||
});
|
||||
|
||||
test("the transaction detail view shows the time written by the shared isoDate() and timeAgo()", () => {
|
||||
transactionDetail.show(historyTx());
|
||||
const html = node("tx-detail-time").innerHTML;
|
||||
expect(html).toContain("SHARED-ISO-DATE");
|
||||
expect(html).toContain("(SHARED-TIME-AGO)");
|
||||
});
|
||||
Reference in New Issue
Block a user