Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: align transaction controller with mobile patch #4706

Merged
merged 8 commits into from
Sep 19, 2024
8 changes: 4 additions & 4 deletions packages/transaction-controller/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ module.exports = merge(baseConfig, {
// An object that configures minimum threshold enforcement for coverage results
coverageThreshold: {
global: {
branches: 94.37,
functions: 97.94,
lines: 98.52,
statements: 98.53,
branches: 94.42,
functions: 97.46,
lines: 98.44,
statements: 98.46,
},
},

Expand Down
206 changes: 205 additions & 1 deletion packages/transaction-controller/src/TransactionController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
buildCustomNetworkClientConfiguration,
buildMockGetNetworkClientById,
} from '../../network-controller/tests/helpers';
import { CHAIN_IDS } from './constants';
import { DefaultGasFeeFlow } from './gas-flows/DefaultGasFeeFlow';
import { LineaGasFeeFlow } from './gas-flows/LineaGasFeeFlow';
import { TestGasFeeFlow } from './gas-flows/TestGasFeeFlow';
Expand All @@ -69,6 +70,7 @@ import type {
SimulationData,
GasFeeFlow,
GasFeeFlowResponse,
SubmitHistoryEntry,
} from './types';
import {
GasFeeEstimateType,
Expand Down Expand Up @@ -97,6 +99,7 @@ type UnrestrictedControllerMessenger = ControllerMessenger<
>;

const MOCK_V1_UUID = '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d';
const TRANSACTION_HASH_MOCK = '0x123456';

jest.mock('@metamask/eth-query');
jest.mock('./gas-flows/DefaultGasFeeFlow');
Expand Down Expand Up @@ -191,7 +194,7 @@ function buildMockEthQuery(): EthQuery {
// TODO: Replace `any` with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sendRawTransaction: (_transaction: unknown, callback: any) => {
callback(undefined, 'somehash');
callback(undefined, TRANSACTION_HASH_MOCK);
},
// TODO: Replace `any` with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -873,6 +876,7 @@ describe('TransactionController', () => {
methodData: {},
transactions: [],
lastFetchedBlockNumbers: {},
submitHistory: [],
});
});

Expand Down Expand Up @@ -2264,6 +2268,100 @@ describe('TransactionController', () => {
);
});
});

describe('updates submit history', () => {
it('adds entry to start of array', async () => {
const { controller } = setupController({
messengerOptions: {
addTransactionApprovalRequest: {
state: 'approved',
},
},
options: {
state: {
submitHistory: [
{
chainId: CHAIN_IDS.LINEA_MAINNET,
} as unknown as SubmitHistoryEntry,
],
},
},
});

const { result } = await controller.addTransaction(
{
from: ACCOUNT_MOCK,
to: ACCOUNT_MOCK,
},
{ origin: ORIGIN_METAMASK },
);

await result;

expect(controller.state.submitHistory).toStrictEqual([
{
chainId: MOCK_NETWORK.chainId,
hash: TRANSACTION_HASH_MOCK,
networkType: NetworkType.goerli,
networkUrl: expect.stringContaining('goerli.infura.io'),
origin: ORIGIN_METAMASK,
rawTransaction: expect.stringContaining('0x'),
time: expect.any(Number),
transaction: {
from: ACCOUNT_MOCK,
nonce: '0xc',
to: ACCOUNT_MOCK,
value: '0x0',
},
},
{
chainId: CHAIN_IDS.LINEA_MAINNET,
},
]);
});

it('removes last entry if reached maximum size', async () => {
const existingSubmitHistory = Array(100);

existingSubmitHistory[99] = {
chainId: CHAIN_IDS.LINEA_MAINNET,
} as unknown as SubmitHistoryEntry;

const { controller } = setupController({
messengerOptions: {
addTransactionApprovalRequest: {
state: 'approved',
},
},
options: {
state: {
submitHistory: existingSubmitHistory,
},
},
});

const { result } = await controller.addTransaction(
{
from: ACCOUNT_MOCK,
to: ACCOUNT_MOCK,
},
{
origin: ORIGIN_METAMASK,
},
);

await result;

expect(controller.state.submitHistory).toHaveLength(100);
expect(controller.state.submitHistory[0]).toStrictEqual(
expect.objectContaining({
chainId: MOCK_NETWORK.chainId,
origin: ORIGIN_METAMASK,
}),
);
expect(controller.state.submitHistory[99]).toBeUndefined();
});
});
});

describe('wipeTransactions', () => {
Expand Down Expand Up @@ -2733,6 +2831,59 @@ describe('TransactionController', () => {
expect(finishedEventListener).toHaveBeenCalledTimes(2);
expect(finishedEventListener).toHaveBeenCalledWith(cancelTransaction);
});

it('updates submit history', async () => {
const { controller } = setupController({
messengerOptions: {
addTransactionApprovalRequest: {
state: 'approved',
},
},
});

const { result } = await controller.addTransaction(
{
from: ACCOUNT_MOCK,
gas: '0xFF',
gasPrice: '0xEE',
to: ACCOUNT_MOCK,
value: '0x0',
},
{
origin: ORIGIN_METAMASK,
},
);

await result;

await controller.stopTransaction(controller.state.transactions[0].id);

const { submitHistory } = controller.state;

expect(submitHistory).toStrictEqual([
{
chainId: MOCK_NETWORK.chainId,
hash: TRANSACTION_HASH_MOCK,
networkType: NetworkType.goerli,
networkUrl: expect.stringContaining('goerli.infura.io'),
origin: 'cancel',
rawTransaction: expect.stringContaining('0x'),
time: expect.any(Number),
transaction: {
from: ACCOUNT_MOCK,
gas: '0xFF',
gasLimit: '0xFF',
gasPrice: '0x105',
nonce: '0xc',
to: ACCOUNT_MOCK,
value: '0x0',
},
},
expect.objectContaining({
origin: ORIGIN_METAMASK,
}),
]);
});
});

describe('speedUpTransaction', () => {
Expand Down Expand Up @@ -3095,6 +3246,59 @@ describe('TransactionController', () => {
expect(speedupEventListener).toHaveBeenCalledTimes(1);
expect(speedupEventListener).toHaveBeenCalledWith(speedUpTransaction);
});

it('updates submit history', async () => {
const { controller } = setupController({
messengerOptions: {
addTransactionApprovalRequest: {
state: 'approved',
},
},
});

const { result } = await controller.addTransaction(
{
from: ACCOUNT_MOCK,
gas: '0xFF',
gasPrice: '0xEE',
to: ACCOUNT_MOCK,
value: '0x0',
},
{
origin: ORIGIN_METAMASK,
},
);

await result;

await controller.speedUpTransaction(controller.state.transactions[0].id);

const { submitHistory } = controller.state;

expect(submitHistory).toStrictEqual([
{
chainId: MOCK_NETWORK.chainId,
hash: TRANSACTION_HASH_MOCK,
networkType: NetworkType.goerli,
networkUrl: expect.stringContaining('goerli.infura.io'),
origin: 'speed up',
rawTransaction: expect.stringContaining('0x'),
time: expect.any(Number),
transaction: {
from: ACCOUNT_MOCK,
gas: '0xFF',
gasLimit: '0xFF',
gasPrice: '0x105',
nonce: '0xc',
to: ACCOUNT_MOCK,
value: '0x0',
},
},
expect.objectContaining({
origin: ORIGIN_METAMASK,
}),
]);
});
});

describe('confirmExternalTransaction', () => {
Expand Down
Loading
Loading