From 59f679bf1fcff3fba0de6eef53c30d7da1882cac Mon Sep 17 00:00:00 2001 From: gabrieledm Date: Tue, 4 Aug 2026 22:52:05 +0200 Subject: [PATCH 1/2] test: removed beforeEach usage from saveMany tests --- .../transactions/TransactionsService.test.ts | 342 +++++++++--------- 1 file changed, 177 insertions(+), 165 deletions(-) diff --git a/packages/tron-wallet-snap/src/services/transactions/TransactionsService.test.ts b/packages/tron-wallet-snap/src/services/transactions/TransactionsService.test.ts index e384e340..227d2219 100644 --- a/packages/tron-wallet-snap/src/services/transactions/TransactionsService.test.ts +++ b/packages/tron-wallet-snap/src/services/transactions/TransactionsService.test.ts @@ -1197,194 +1197,206 @@ describe('TransactionsService', () => { describe('saveMany', () => { it('should save multiple transactions and emit keyring event', async () => { - const mockTransactions: Transaction[] = [ - { - id: 'tx-bulk-1', - type: 'send', - account: mockAccount.id, - chain: Network.Mainnet, - status: 'confirmed', - timestamp: Math.floor(Date.now() / 1000), - from: [ - { - address: mockAccount.address, - asset: { - type: KnownCaip19Id.TrxMainnet, - amount: '100', - unit: 'TRX', - fungible: true, - }, - }, - ], - to: [ - { - address: 'other-address', - asset: { - type: KnownCaip19Id.TrxMainnet, - amount: '100', - unit: 'TRX', - fungible: true, - }, - }, - ], - events: [], - fees: [], - }, - { - id: 'tx-bulk-2', - type: 'receive', - account: mockAccount.id, - chain: Network.Mainnet, - status: 'confirmed', - timestamp: Math.floor(Date.now() / 1000), - from: [ + await withTransactionService( + async ({ mockTransactionsRepository, transactionsService }) => { + const mockTransactions: Transaction[] = [ { - address: 'other-address', - asset: { - type: KnownCaip19Id.TrxMainnet, - amount: '50', - unit: 'TRX', - fungible: true, - }, + id: 'tx-bulk-1', + type: 'send', + account: mockAccount.id, + chain: Network.Mainnet, + status: 'confirmed', + timestamp: Math.floor(Date.now() / 1000), + from: [ + { + address: mockAccount.address, + asset: { + type: KnownCaip19Id.TrxMainnet, + amount: '100', + unit: 'TRX', + fungible: true, + }, + }, + ], + to: [ + { + address: 'other-address', + asset: { + type: KnownCaip19Id.TrxMainnet, + amount: '100', + unit: 'TRX', + fungible: true, + }, + }, + ], + events: [], + fees: [], }, - ], - to: [ { - address: mockAccount.address, - asset: { - type: KnownCaip19Id.TrxMainnet, - amount: '50', - unit: 'TRX', - fungible: true, - }, + id: 'tx-bulk-2', + type: 'receive', + account: mockAccount.id, + chain: Network.Mainnet, + status: 'confirmed', + timestamp: Math.floor(Date.now() / 1000), + from: [ + { + address: 'other-address', + asset: { + type: KnownCaip19Id.TrxMainnet, + amount: '50', + unit: 'TRX', + fungible: true, + }, + }, + ], + to: [ + { + address: mockAccount.address, + asset: { + type: KnownCaip19Id.TrxMainnet, + amount: '50', + unit: 'TRX', + fungible: true, + }, + }, + ], + events: [], + fees: [], }, - ], - events: [], - fees: [], - }, - ]; + ]; - await transactionsService.saveMany(mockTransactions); + await transactionsService.saveMany(mockTransactions); - expect(mockTransactionsRepository.saveMany).toHaveBeenCalledWith( - mockTransactions, + expect(mockTransactionsRepository.saveMany).toHaveBeenCalledWith( + mockTransactions, + ); + expect(true).toBe(true); + }, ); - expect(true).toBe(true); }); it('should handle empty transactions array', async () => { - await transactionsService.saveMany([]); + await withTransactionService( + async ({ mockTransactionsRepository, transactionsService }) => { + await transactionsService.saveMany([]); - expect(mockTransactionsRepository.saveMany).toHaveBeenCalledWith([]); - expect(true).toBe(true); + expect(mockTransactionsRepository.saveMany).toHaveBeenCalledWith([]); + expect(true).toBe(true); + }, + ); }); it('should group transactions by account ID correctly', async () => { - const mockTransactions: Transaction[] = [ - { - id: 'tx-account1-1', - type: 'send', - account: mockAccount.id, - chain: Network.Mainnet, - status: 'confirmed', - timestamp: Math.floor(Date.now() / 1000), - from: [ - { - address: mockAccount.address, - asset: { - type: KnownCaip19Id.TrxMainnet, - amount: '100', - unit: 'TRX', - fungible: true, - }, - }, - ], - to: [ - { - address: 'other-address', - asset: { - type: KnownCaip19Id.TrxMainnet, - amount: '100', - unit: 'TRX', - fungible: true, - }, - }, - ], - events: [], - fees: [], - }, - { - id: 'tx-account1-2', - type: 'receive', - account: mockAccount.id, - chain: Network.Mainnet, - status: 'confirmed', - timestamp: Math.floor(Date.now() / 1000), - from: [ - { - address: 'other-address', - asset: { - type: KnownCaip19Id.TrxMainnet, - amount: '25', - unit: 'TRX', - fungible: true, - }, - }, - ], - to: [ + await withTransactionService( + async ({ mockTransactionsRepository, transactionsService }) => { + const mockTransactions: Transaction[] = [ { - address: mockAccount.address, - asset: { - type: KnownCaip19Id.TrxMainnet, - amount: '25', - unit: 'TRX', - fungible: true, - }, + id: 'tx-account1-1', + type: 'send', + account: mockAccount.id, + chain: Network.Mainnet, + status: 'confirmed', + timestamp: Math.floor(Date.now() / 1000), + from: [ + { + address: mockAccount.address, + asset: { + type: KnownCaip19Id.TrxMainnet, + amount: '100', + unit: 'TRX', + fungible: true, + }, + }, + ], + to: [ + { + address: 'other-address', + asset: { + type: KnownCaip19Id.TrxMainnet, + amount: '100', + unit: 'TRX', + fungible: true, + }, + }, + ], + events: [], + fees: [], }, - ], - events: [], - fees: [], - }, - { - id: 'tx-account2-1', - type: 'send', - account: mockAccount2.id, - chain: Network.Mainnet, - status: 'confirmed', - timestamp: Math.floor(Date.now() / 1000), - from: [ { - address: mockAccount2.address, - asset: { - type: KnownCaip19Id.TrxMainnet, - amount: '75', - unit: 'TRX', - fungible: true, - }, + id: 'tx-account1-2', + type: 'receive', + account: mockAccount.id, + chain: Network.Mainnet, + status: 'confirmed', + timestamp: Math.floor(Date.now() / 1000), + from: [ + { + address: 'other-address', + asset: { + type: KnownCaip19Id.TrxMainnet, + amount: '25', + unit: 'TRX', + fungible: true, + }, + }, + ], + to: [ + { + address: mockAccount.address, + asset: { + type: KnownCaip19Id.TrxMainnet, + amount: '25', + unit: 'TRX', + fungible: true, + }, + }, + ], + events: [], + fees: [], }, - ], - to: [ { - address: 'other-address', - asset: { - type: KnownCaip19Id.TrxMainnet, - amount: '75', - unit: 'TRX', - fungible: true, - }, + id: 'tx-account2-1', + type: 'send', + account: mockAccount2.id, + chain: Network.Mainnet, + status: 'confirmed', + timestamp: Math.floor(Date.now() / 1000), + from: [ + { + address: mockAccount2.address, + asset: { + type: KnownCaip19Id.TrxMainnet, + amount: '75', + unit: 'TRX', + fungible: true, + }, + }, + ], + to: [ + { + address: 'other-address', + asset: { + type: KnownCaip19Id.TrxMainnet, + amount: '75', + unit: 'TRX', + fungible: true, + }, + }, + ], + events: [], + fees: [], }, - ], - events: [], - fees: [], - }, - ]; + ]; - await transactionsService.saveMany(mockTransactions); + await transactionsService.saveMany(mockTransactions); - expect(mockTransactionsRepository.saveMany).toHaveBeenCalledWith( - mockTransactions, + expect(mockTransactionsRepository.saveMany).toHaveBeenCalledWith( + mockTransactions, + ); + expect(true).toBe(true); + }, ); - expect(true).toBe(true); }); }); From 0f262f843240cdbe66390c0f96f047a77ad0a3a1 Mon Sep 17 00:00:00 2001 From: Gabriele Del Monte <37625739+gabrieledm@users.noreply.github.com> Date: Wed, 5 Aug 2026 10:49:55 +0200 Subject: [PATCH 2/2] test: removed beforeEach usage from 'Integration scenarios' tests (#117) ## Explanation Seventh PR of Stacked pull requests to remove the usage of `beforeEach` and follow the [Unit Testing Guidelines ](https://github.com/MetaMask/contributor-docs/blob/main/docs/testing/unit-testing.md#avoid-the-use-of-beforeeach) in the file `packages/tron-wallet-snap/src/services/transactions/TransactionsService.test.ts`. The base PR is: https://github.com/MetaMask/internal-snaps/pull/110 To split the PRs is used the [Stacked pull requests](https://docs.github.com/en/pull-requests/reference/stacked-pull-requests) feature from GitHub ## References ## Checklist - [X] I've updated the test suite for new or updated code as appropriate - [X] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [ ] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/internal-snaps/tree/main/docs/processes/updating-changelogs.md) - [ ] I've introduced [breaking changes](https://github.com/MetaMask/internal-snaps/tree/main/docs/processes/breaking-changes.md) in this PR and have prepared draft pull requests for clients and consumer packages to resolve them --- eslint-suppressions.json | 5 - .../transactions/TransactionsService.test.ts | 163 ++++++------------ 2 files changed, 57 insertions(+), 111 deletions(-) diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 44ec2b25..8d0f6735 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -1702,11 +1702,6 @@ "count": 4 } }, - "packages/tron-wallet-snap/src/services/transactions/TransactionsService.test.ts": { - "@typescript-eslint/no-explicit-any": { - "count": 1 - } - }, "packages/tron-wallet-snap/src/services/wallet/WalletService.test.ts": { "@typescript-eslint/explicit-function-return-type": { "count": 2 diff --git a/packages/tron-wallet-snap/src/services/transactions/TransactionsService.test.ts b/packages/tron-wallet-snap/src/services/transactions/TransactionsService.test.ts index 227d2219..9c59145e 100644 --- a/packages/tron-wallet-snap/src/services/transactions/TransactionsService.test.ts +++ b/packages/tron-wallet-snap/src/services/transactions/TransactionsService.test.ts @@ -62,6 +62,13 @@ type WithTransactionServiceCallback = (payload: { async function withTransactionService( testFunction: WithTransactionServiceCallback, ): Promise { + // Mock the global snap object + Object.defineProperty(globalThis, 'snap', { + value: { request: jest.fn() }, + writable: true, + configurable: true, + }); + const mockTransactionsRepository: jest.Mocked< Pick< TransactionsRepository, @@ -135,14 +142,6 @@ async function withTransactionService( // Import simplified mock data (each file now contains only one transaction) describe('TransactionsService', () => { - let transactionsService: TransactionsService; - let mockLogger: jest.Mocked; - let mockTransactionsRepository: jest.Mocked; - let mockTrongridApiClient: jest.Mocked; - let mockTronHttpClient: jest.Mocked; - let mockPriceApiClient: jest.Mocked; - let mockSnapClient: jest.Mocked; - const mockAccount: TronKeyringAccount = { id: 'test-account-id', address: 'TGJn1wnUYHJbvN88cynZbsAz2EMeZq73yx', @@ -167,65 +166,6 @@ describe('TransactionsService', () => { index: 1, }; - beforeEach(() => { - // Mock the global snap object - const snap = { - request: jest.fn(), - }; - (globalThis as any).snap = snap; - - // Create mocks - mockLogger = { - log: jest.fn(), - debug: jest.fn(), - info: jest.fn(), - warn: jest.fn(), - error: jest.fn(), - }; - - // Create mock repository - mockTransactionsRepository = { - getAll: jest.fn(), - findByAccountId: jest.fn().mockResolvedValue([]), - getTransactionIdsByAccountId: jest.fn().mockResolvedValue(new Set()), - getConfirmedTransactionIds: jest.fn().mockResolvedValue(new Set()), - save: jest.fn(), - saveMany: jest.fn(), - } as unknown as jest.Mocked; - - // Create mock API client - mockTrongridApiClient = { - getAccountInfoByAddress: jest.fn(), - getTransactionInfoByAddress: jest.fn(), - getContractTransactionInfoByAddress: jest.fn(), - } as unknown as jest.Mocked; - - // Create mock TronHttpClient - mockTronHttpClient = { - getTRC10TokenMetadata: jest.fn(), - getTransactionInfoById: jest.fn(), - } as unknown as jest.Mocked; - - // Create mock PriceApiClient — default: no price data (all tokens filtered unless overridden) - mockPriceApiClient = { - getMultipleSpotPrices: jest.fn().mockResolvedValue({}), - } as unknown as jest.Mocked; - - mockSnapClient = { - trackError: jest.fn().mockResolvedValue(undefined), - } as unknown as jest.Mocked; - - // Create service instance - transactionsService = new TransactionsService({ - logger: mockLogger, - transactionsRepository: mockTransactionsRepository, - trongridApiClient: mockTrongridApiClient, - tronHttpClient: mockTronHttpClient, - priceApiClient: mockPriceApiClient, - snapClient: mockSnapClient, - }); - }); - describe('checkAddressActivity', () => { it('returns true when the address has at least one transaction', async () => { await withTransactionService( @@ -361,7 +301,7 @@ describe('TransactionsService', () => { it('should fetch and map transactions for an account using native transfers mock data', async () => { await withTransactionService( - async ({ mockTrongridApiClient, transactionsService, mockLogger }) => { + async ({ mockTrongridApiClient, transactionsService }) => { // Setup mock responses with simplified single-transaction structure mockTrongridApiClient.getTransactionInfoByAddress.mockResolvedValue([ nativeTransferMock, @@ -626,7 +566,7 @@ describe('TransactionsService', () => { it('should handle API errors gracefully', async () => { await withTransactionService( - async ({ mockTrongridApiClient, transactionsService, mockLogger }) => { + async ({ mockTrongridApiClient, transactionsService }) => { // Setup API to throw error const apiError = new Error('API request failed'); mockTrongridApiClient.getTransactionInfoByAddress.mockRejectedValue( @@ -988,7 +928,6 @@ describe('TransactionsService', () => { async ({ mockPriceApiClient, mockTrongridApiClient, - mockLogger, mockSnapClient, transactionsService, }) => { @@ -1402,51 +1341,63 @@ describe('TransactionsService', () => { describe('Integration scenarios', () => { it('should handle a complete flow: fetch, process, and save transactions', async () => { - // Setup API responses with simplified single-transaction structure - mockTrongridApiClient.getTransactionInfoByAddress.mockResolvedValue([ - nativeTransferMock, - ] as TransactionInfo[]); - mockTrongridApiClient.getContractTransactionInfoByAddress.mockResolvedValue( - contractInfoMock.data.slice(0, 1) as ContractTransactionInfo[], - ); + await withTransactionService( + async ({ + mockTransactionsRepository, + mockTrongridApiClient, + transactionsService, + }) => { + // Setup API responses with simplified single-transaction structure + mockTrongridApiClient.getTransactionInfoByAddress.mockResolvedValue([ + nativeTransferMock, + ] as TransactionInfo[]); + mockTrongridApiClient.getContractTransactionInfoByAddress.mockResolvedValue( + contractInfoMock.data.slice(0, 1) as ContractTransactionInfo[], + ); - // Fetch transactions - const fetchedTransactions = - await transactionsService.fetchNewTransactionsForAccount( - Network.Mainnet, - mockAccount, - ); + // Fetch transactions + const fetchedTransactions = + await transactionsService.fetchNewTransactionsForAccount( + Network.Mainnet, + mockAccount, + ); - // Save the fetched transactions - await transactionsService.saveMany(fetchedTransactions); + // Save the fetched transactions + await transactionsService.saveMany(fetchedTransactions); - expect(mockTransactionsRepository.saveMany).toHaveBeenCalledWith( - fetchedTransactions, + expect(mockTransactionsRepository.saveMany).toHaveBeenCalledWith( + fetchedTransactions, + ); + expect(true).toBe(true); + }, ); - expect(true).toBe(true); }); it('should handle mixed transaction types from different mock data sources', async () => { - // Mix different types of transactions with simplified structure - const mixedRawTransactions = [ - nativeTransferMock, // Native TRX transfer - trc10TransferMock, // TRC10 transfer - trc20TransferMock, // TRC20 transfer - ] as TransactionInfo[]; - - mockTrongridApiClient.getTransactionInfoByAddress.mockResolvedValue( - mixedRawTransactions, - ); - mockTrongridApiClient.getContractTransactionInfoByAddress.mockResolvedValue( - [], - ); + await withTransactionService( + async ({ mockTrongridApiClient, transactionsService }) => { + // Mix different types of transactions with simplified structure + const mixedRawTransactions = [ + nativeTransferMock, // Native TRX transfer + trc10TransferMock, // TRC10 transfer + trc20TransferMock, // TRC20 transfer + ] as TransactionInfo[]; - await transactionsService.fetchNewTransactionsForAccount( - Network.Mainnet, - mockAccount2, - ); + mockTrongridApiClient.getTransactionInfoByAddress.mockResolvedValue( + mixedRawTransactions, + ); + mockTrongridApiClient.getContractTransactionInfoByAddress.mockResolvedValue( + [], + ); - expect(true).toBe(true); + await transactionsService.fetchNewTransactionsForAccount( + Network.Mainnet, + mockAccount2, + ); + + expect(true).toBe(true); + }, + ); }); }); });