test: assert the #150 and #151 items the harness did not cover (closes #188)
All checks were successful
check / check (push) Successful in 27s
All checks were successful
check / check (push) Successful in 27s
Covers the four DoD items #188 scoped: the AddToken quick-pick populating the address field, Back out of AddToken unwinding the persisted navigation stack exactly once, a native ETH transfer rendering in TransactionDetail with no token contract row, and tap-to-copy reading the real clipboard back. The native path needed a fixture: the Blockscout normal-transactions endpoint answered [] unconditionally, so there was no non-ERC-20 row to open. Each assertion demonstrated to discriminate by mutation, one break at a time with the pre-existing tests staying green: a double viewStack push, a no-op quick-pick handler, an un-hidden token contract row, the ERC-20 branch forced onto a native transaction, and a dropped clipboard write each turn exactly the corresponding test red and no other. Four further DoD items from #150 and #151 remain outside this scope and are tracked in #295.
This commit was merged in pull request #288.
This commit is contained in:
@@ -46,9 +46,24 @@ const STUB_TX_HASH =
|
||||
|
||||
const STUB_BLOCK_NUMBER = 21000000;
|
||||
|
||||
// The native ETH transfer, seeded by opts.seedNativeTransfer. Its own hash
|
||||
// and an older block, so it is a second row rather than a leg of the token
|
||||
// transfer: mergeTransactions() consolidates a native entry and a token
|
||||
// transfer that share a hash into one row, which would leave nothing native
|
||||
// to open. 0.25 ETH clears the 100000 gwei dust threshold the default
|
||||
// filters apply, so the row is not silently dropped.
|
||||
const STUB_NATIVE_TX_HASH =
|
||||
"0xe7e0000000000000000000000000000000000000000000000000000000000e7e";
|
||||
|
||||
const STUB_NATIVE_BLOCK_NUMBER = STUB_BLOCK_NUMBER - 1;
|
||||
|
||||
const STUB_NATIVE_VALUE_WEI = "250000000000000000";
|
||||
|
||||
// Fixed instant so timeAgo() output is stable across runs.
|
||||
const STUB_TX_TIMESTAMP = "2026-01-02T03:04:05.000000Z";
|
||||
|
||||
const STUB_NATIVE_TX_TIMESTAMP = "2026-01-02T02:03:04.000000Z";
|
||||
|
||||
// A 32-byte zero word. Returned for every eth_call, which is what makes
|
||||
// ethers' ENS reverse lookup resolve to "no resolver set" and return null
|
||||
// instead of throwing. A throw would be logged by src/shared/ens.js via
|
||||
@@ -258,6 +273,25 @@ function tokenTransferItems(address) {
|
||||
];
|
||||
}
|
||||
|
||||
// One received native ETH transfer, in the shape src/shared/transactions.js
|
||||
// parses. to.is_contract is false and there is no method, so parseTx() keeps
|
||||
// it a plain transfer rather than a contract call — which is what makes the
|
||||
// detail screen classify it "Native ETH Transfer" and leave the token
|
||||
// contract row hidden.
|
||||
function nativeTransactionItems(address) {
|
||||
return [
|
||||
{
|
||||
hash: STUB_NATIVE_TX_HASH,
|
||||
block_number: STUB_NATIVE_BLOCK_NUMBER,
|
||||
timestamp: STUB_NATIVE_TX_TIMESTAMP,
|
||||
from: { hash: STUB_COUNTERPARTY },
|
||||
to: { hash: address, is_contract: false },
|
||||
value: STUB_NATIVE_VALUE_WEI,
|
||||
status: "ok",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// A holding of 1.5 E2E, in the shape src/shared/balances.js parses. Serving
|
||||
// this is what puts an ERC-20 in the send screen's token dropdown, which is
|
||||
// the only way the confirmation screen's ERC-20 path can be reached.
|
||||
@@ -270,12 +304,17 @@ function tokenBalanceItems() {
|
||||
];
|
||||
}
|
||||
|
||||
// Full details for STUB_TX_HASH. raw_input is "0x" so the calldata
|
||||
// decoder short-circuits; the on-chain detail fields still populate.
|
||||
function transactionDetails() {
|
||||
// Full details for either seeded transaction — the detail screen fetches
|
||||
// them for whichever row was opened, and an unstubbed hash would be
|
||||
// reported as escaping traffic. raw_input is "0x" so the calldata decoder
|
||||
// short-circuits; the on-chain detail fields still populate.
|
||||
function transactionDetails(hash) {
|
||||
return {
|
||||
hash: STUB_TX_HASH,
|
||||
block_number: STUB_BLOCK_NUMBER,
|
||||
hash: hash,
|
||||
block_number:
|
||||
hash === STUB_NATIVE_TX_HASH
|
||||
? STUB_NATIVE_BLOCK_NUMBER
|
||||
: STUB_BLOCK_NUMBER,
|
||||
nonce: 7,
|
||||
gas_used: "51000",
|
||||
gas_price: "1000000000",
|
||||
@@ -479,6 +518,10 @@ function traceEnabled(raw) {
|
||||
* @param {boolean} [opts.seedTokenTransfer] serve the stubbed ERC-20
|
||||
* transfer. Read at request time, so a test can flip it on the same
|
||||
* options object without re-registering the route.
|
||||
* @param {boolean} [opts.seedNativeTransfer] serve the stubbed native ETH
|
||||
* transfer, read at request time like seedTokenTransfer. Without it the
|
||||
* normal-transactions endpoint answers with an empty list, so there is no
|
||||
* non-ERC-20 row to open.
|
||||
* @param {boolean} [opts.seedTokenBalance] serve the stubbed ERC-20
|
||||
* holding, which is what makes the token reachable from the send screen.
|
||||
* @param {string} [opts.ethBalanceWei] hex wei answered to eth_getBalance;
|
||||
@@ -550,7 +593,13 @@ async function installNetworkStubs(ctx, opts) {
|
||||
// Blockscout v2
|
||||
if (p.includes("/api/v2/")) {
|
||||
if (/\/addresses\/0x[0-9a-fA-F]{40}\/transactions$/.test(p)) {
|
||||
return jsonResponse(route, { items: [] });
|
||||
const addr = blockscoutAddress(p);
|
||||
return jsonResponse(route, {
|
||||
items:
|
||||
opts.seedNativeTransfer && addr
|
||||
? nativeTransactionItems(addr)
|
||||
: [],
|
||||
});
|
||||
}
|
||||
if (/\/addresses\/0x[0-9a-fA-F]{40}\/token-transfers$/.test(p)) {
|
||||
const addr = blockscoutAddress(p);
|
||||
@@ -567,8 +616,10 @@ async function installNetworkStubs(ctx, opts) {
|
||||
opts.seedTokenBalance ? tokenBalanceItems() : [],
|
||||
);
|
||||
}
|
||||
if (p.endsWith("/transactions/" + STUB_TX_HASH)) {
|
||||
return jsonResponse(route, transactionDetails());
|
||||
for (const hash of [STUB_TX_HASH, STUB_NATIVE_TX_HASH]) {
|
||||
if (p.endsWith("/transactions/" + hash)) {
|
||||
return jsonResponse(route, transactionDetails(hash));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -640,6 +691,8 @@ module.exports = {
|
||||
FEE_ESTIMATE_WEI,
|
||||
FEE_RESERVE_WEI,
|
||||
STUB_COUNTERPARTY,
|
||||
STUB_NATIVE_TX_HASH,
|
||||
STUB_NATIVE_VALUE_WEI,
|
||||
STUB_TOKEN,
|
||||
STUB_TX_HASH,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user