Skip to content

Commit 8b8ef87

Browse files
committed
coverage for coverage sake
1 parent 0dac0e3 commit 8b8ef87

3 files changed

Lines changed: 173 additions & 13 deletions

File tree

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
import type { V1TransactionByHashResponse } from '@metamask/core-backend';
2+
import {
3+
TransactionStatus,
4+
TransactionType,
5+
} from '@metamask/transaction-controller';
6+
import {
7+
APPROVE_FUNCTION_SIGNATURE,
8+
TRANSFER_FUNCTION_SIGNATURE,
9+
} from '../../../../util/transactions';
10+
import { normalizeTransaction } from './adapters';
11+
12+
describe('normalizeTransaction', () => {
13+
const address = '0x0000000000000000000000000000000000000001';
14+
const otherAddress = '0x0000000000000000000000000000000000000002';
15+
const contractAddress = '0x00000000000000000000000000000000000000aa';
16+
17+
const buildTransaction = (
18+
overrides: Partial<V1TransactionByHashResponse> = {},
19+
): V1TransactionByHashResponse =>
20+
({
21+
hash: '0xhash',
22+
timestamp: '2024-01-01T00:00:00Z',
23+
chainId: 1,
24+
blockNumber: 100,
25+
blockHash: '0xblock',
26+
gas: 21000,
27+
gasUsed: 21000,
28+
gasPrice: '1000000000',
29+
effectiveGasPrice: '1000000000',
30+
nonce: 0,
31+
cumulativeGasUsed: 21000,
32+
value: '1000',
33+
to: otherAddress,
34+
from: address,
35+
methodId: '0x',
36+
isError: false,
37+
...overrides,
38+
}) as unknown as V1TransactionByHashResponse;
39+
40+
it('normalizes a simple outgoing send', () => {
41+
const meta = normalizeTransaction(address, buildTransaction());
42+
43+
expect(meta).toEqual(
44+
expect.objectContaining({
45+
hash: '0xhash',
46+
id: '0xhash-1',
47+
chainId: '0x1',
48+
status: TransactionStatus.confirmed,
49+
type: TransactionType.simpleSend,
50+
isTransfer: false,
51+
networkClientId: '',
52+
toSmartContract: false,
53+
verifiedOnBlockchain: false,
54+
blockNumber: '100',
55+
time: Date.parse('2024-01-01T00:00:00Z'),
56+
error: undefined,
57+
transferInformation: undefined,
58+
}),
59+
);
60+
expect(meta.txParams).toEqual(
61+
expect.objectContaining({
62+
chainId: '0x1',
63+
from: address,
64+
to: otherAddress,
65+
value: '0x3e8',
66+
gas: '0x5208',
67+
gasPrice: '0x3b9aca00',
68+
gasUsed: '0x5208',
69+
nonce: '0x0',
70+
}),
71+
);
72+
});
73+
74+
it('marks the transaction as failed when isError is true', () => {
75+
const meta = normalizeTransaction(
76+
address,
77+
buildTransaction({ isError: true }),
78+
);
79+
80+
expect(meta.status).toBe(TransactionStatus.failed);
81+
expect(meta.error).toBeInstanceOf(Error);
82+
expect(meta.error?.message).toBe('Transaction failed');
83+
});
84+
85+
it('marks an outgoing transaction with no `to` and calldata as deployContract', () => {
86+
const meta = normalizeTransaction(
87+
address,
88+
buildTransaction({
89+
to: undefined as unknown as string,
90+
methodId: '0xabcdef',
91+
}),
92+
);
93+
94+
expect(meta.type).toBe(TransactionType.deployContract);
95+
});
96+
97+
it('classifies an incoming transaction', () => {
98+
const meta = normalizeTransaction(
99+
address,
100+
buildTransaction({ from: otherAddress, to: address }),
101+
);
102+
103+
expect(meta.type).toBe(TransactionType.incoming);
104+
});
105+
106+
it('detects ERC20 transfer method', () => {
107+
const meta = normalizeTransaction(
108+
address,
109+
buildTransaction({
110+
methodId: TRANSFER_FUNCTION_SIGNATURE,
111+
value: '0',
112+
}),
113+
);
114+
115+
expect(meta.type).toBe(TransactionType.tokenMethodTransfer);
116+
});
117+
118+
it('detects ERC20 approve method', () => {
119+
const meta = normalizeTransaction(
120+
address,
121+
buildTransaction({
122+
methodId: APPROVE_FUNCTION_SIGNATURE,
123+
value: '0',
124+
}),
125+
);
126+
127+
expect(meta.type).toBe(TransactionType.tokenMethodApprove);
128+
});
129+
130+
it('classifies a contract interaction when calldata has value', () => {
131+
const meta = normalizeTransaction(
132+
address,
133+
buildTransaction({
134+
methodId: '0xdeadbeef',
135+
value: '1000',
136+
}),
137+
);
138+
139+
expect(meta.type).toBe(TransactionType.contractInteraction);
140+
});
141+
142+
it('extracts transfer information for an incoming token transfer and rewrites txParams', () => {
143+
const meta = normalizeTransaction(
144+
address,
145+
buildTransaction({
146+
from: otherAddress,
147+
to: contractAddress,
148+
value: '0',
149+
valueTransfers: [
150+
{
151+
from: otherAddress,
152+
to: address,
153+
amount: '5000',
154+
contractAddress,
155+
decimal: 6,
156+
symbol: 'USDC',
157+
},
158+
],
159+
} as Partial<V1TransactionByHashResponse>),
160+
);
161+
162+
expect(meta.isTransfer).toBe(true);
163+
expect(meta.transferInformation).toEqual({
164+
amount: '5000',
165+
contractAddress,
166+
decimals: 6,
167+
symbol: 'USDC',
168+
});
169+
expect(meta.txParams.to).toBe(address);
170+
expect(meta.txParams.value).toBe('0x1388');
171+
});
172+
});

app/components/Views/UnifiedTransactionsView/useTransactionsQuery.test.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { useSelector } from 'react-redux';
44
import { apiClient } from '../../../core/apiClient';
55
import { selectEvmAddress } from '../../../selectors/accountsController';
66
import { selectEvmEnabledCaipNetworks } from '../../../selectors/networkEnablementController';
7-
import { selectPrivacyMode } from '../../../selectors/preferencesController';
87
import { useTransactionsQuery } from './useTransactionsQuery';
98
import { MINUTE } from '../../../constants/time';
109

@@ -32,10 +31,6 @@ jest.mock('../../../selectors/networkEnablementController', () => ({
3231
selectEvmEnabledCaipNetworks: jest.fn(),
3332
}));
3433

35-
jest.mock('../../../selectors/preferencesController', () => ({
36-
selectPrivacyMode: jest.fn(),
37-
}));
38-
3934
const ADDRESS_MOCK = '0x1234567890123456789012345678901234567890';
4035
const NETWORKS_MOCK = ['eip155:1', 'eip155:137'];
4136
const QUERY_OPTIONS_MOCK = {
@@ -54,11 +49,9 @@ describe('useTransactionsQuery', () => {
5449
function setupSelectors({
5550
evmAddress = ADDRESS_MOCK,
5651
networks = NETWORKS_MOCK,
57-
privacyMode = false,
5852
}: {
5953
evmAddress?: string;
6054
networks?: string[];
61-
privacyMode?: boolean;
6255
} = {}) {
6356
useSelectorMock.mockImplementation((selector) => {
6457
if (selector === selectEvmAddress) {
@@ -67,9 +60,6 @@ describe('useTransactionsQuery', () => {
6760
if (selector === selectEvmEnabledCaipNetworks) {
6861
return networks;
6962
}
70-
if (selector === selectPrivacyMode) {
71-
return privacyMode;
72-
}
7363
return undefined;
7464
});
7565
}

app/core/apiClient.test.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createApiPlatformClient } from '@metamask/core-backend';
22
import Engine from './Engine';
3+
import './apiClient';
34

45
jest.mock('@metamask/core-backend', () => ({
56
createApiPlatformClient: jest.fn(() => ({ accounts: {} })),
@@ -21,9 +22,6 @@ const getBearerTokenMock = jest.mocked(
2122
Engine.context.AuthenticationController.getBearerToken,
2223
);
2324

24-
// Import once so the module-level createApiPlatformClient call is captured.
25-
require('./apiClient');
26-
2725
const [firstCallArgs] = createApiPlatformClientMock.mock.calls;
2826
const getBearerToken = firstCallArgs[0].getBearerToken as () => Promise<
2927
string | undefined

0 commit comments

Comments
 (0)