Skip to content

Commit

Permalink
refactor: remove Interface Mock
Browse files Browse the repository at this point in the history
  • Loading branch information
cryptodev-2s committed Jan 29, 2025
1 parent 934d4c6 commit 455ba54
Showing 1 changed file with 55 additions and 70 deletions.
125 changes: 55 additions & 70 deletions packages/transaction-controller/src/helpers/MethodDataHelper.test.ts
Original file line number Diff line number Diff line change
@@ -1,84 +1,58 @@
import { type FunctionFragment, Interface } from '@ethersproject/abi';

import { MethodDataHelper } from './MethodDataHelper';
import type { MethodData } from '../TransactionController';

jest.mock('@ethersproject/abi');

const FOUR_BYTE_PREFIX_MOCK = '0x12345678';
const NETWORK_CLIENT_ID_MOCK = 'testNetworkClientId';
const SIGNATURE_MOCK = 'testMethod(uint256,uint256)';

const METHOD_DATA_MOCK: MethodData = {
registryMethod: SIGNATURE_MOCK,
parsedRegistryMethod: {
name: 'testMethod',
args: [{ type: 'uint256' }, { type: 'uint256' }],
},
};

/**
* Creates a mock Interface instance.
*
* @returns The mocked Interface instance.
*/
function createInterfaceMock() {
return {
getFunction: jest.fn(),
} as unknown as jest.Mocked<Interface>;
}

describe('MethodDataHelper', () => {
const interfaceClassMock = jest.mocked(Interface);

beforeEach(() => {
jest.resetAllMocks();
});

describe('lookup', () => {
it('returns method data from cache', async () => {
const cachedMethodData: MethodData = {
registryMethod: 'cached()',
parsedRegistryMethod: {
name: 'cached',
args: [],
},
};

const methodDataHelper = new MethodDataHelper({
getState: () => ({ [FOUR_BYTE_PREFIX_MOCK]: METHOD_DATA_MOCK }),
getState: () => ({ [FOUR_BYTE_PREFIX_MOCK]: cachedMethodData }),
});

const result = await methodDataHelper.lookup(
FOUR_BYTE_PREFIX_MOCK,
NETWORK_CLIENT_ID_MOCK,
);

expect(result).toStrictEqual(METHOD_DATA_MOCK);
expect(result).toStrictEqual(cachedMethodData);
});

it('returns method data from interface lookup', async () => {
const interfaceMock = createInterfaceMock();
interfaceMock.getFunction.mockReturnValueOnce({
name: 'testMethod',
inputs: [{ type: 'uint256' }, { type: 'uint256' }],
format: jest.fn(() => SIGNATURE_MOCK),
} as unknown as FunctionFragment);

interfaceClassMock.mockReturnValueOnce(interfaceMock);

it('correctly parses a known method signature', async () => {
const methodDataHelper = new MethodDataHelper({
getState: () => ({}),
});

const fourBytePrefix = '0x13af4035';

const result = await methodDataHelper.lookup(
FOUR_BYTE_PREFIX_MOCK,
fourBytePrefix,
NETWORK_CLIENT_ID_MOCK,
);

expect(result).toStrictEqual(METHOD_DATA_MOCK);
});

it('returns empty method data if not found in interface', async () => {
const interfaceMock = createInterfaceMock();
interfaceMock.getFunction.mockImplementationOnce(() => {
throw new Error('Function not found');
expect(result).toStrictEqual({
registryMethod: 'setOwner(address)',
parsedRegistryMethod: {
name: 'setOwner',
args: [{ type: 'address' }],
},
});
});

interfaceClassMock.mockReturnValueOnce(interfaceMock);

it('returns empty result for unknown method signature', async () => {
const methodDataHelper = new MethodDataHelper({
getState: () => ({}),
});
Expand All @@ -95,12 +69,22 @@ describe('MethodDataHelper', () => {
});

it('creates interface instance for each unique network client ID', async () => {
const interfaceMock = createInterfaceMock();
interfaceMock.getFunction.mockImplementationOnce(() => {
throw new Error('Function not found');
});
const mockInterface = jest.fn().mockImplementation(() => ({
getFunction: jest.fn().mockImplementation(() => {
throw new Error('Function not found');
}),
}));

jest.doMock('@ethersproject/abi', () => ({
Interface: mockInterface,
}));

interfaceClassMock.mockReturnValueOnce(interfaceMock);
// Clear the module cache
jest.resetModules();

// Re-import dependencies after mocking
// eslint-disable-next-line @typescript-eslint/no-require-imports, n/global-require, @typescript-eslint/no-shadow
const { MethodDataHelper } = require('./MethodDataHelper');

const methodDataHelper = new MethodDataHelper({
getState: () => ({}),
Expand All @@ -121,35 +105,36 @@ describe('MethodDataHelper', () => {
'anotherNetworkClientId',
);

expect(interfaceClassMock).toHaveBeenCalledTimes(2);
});
await methodDataHelper.lookup(
FOUR_BYTE_PREFIX_MOCK,
'anotherNetworkClientId',
);

it('emits event when method data is fetched', async () => {
const interfaceMock = createInterfaceMock();
interfaceMock.getFunction.mockReturnValueOnce({
name: 'testMethod',
inputs: [{ type: 'uint256' }, { type: 'uint256' }],
format: jest.fn(() => SIGNATURE_MOCK),
} as unknown as FunctionFragment);
expect(mockInterface).toHaveBeenCalledTimes(2);

interfaceClassMock.mockReturnValueOnce(interfaceMock);
jest.unmock('@ethersproject/abi');
});

it('emits an update event for new lookups', async () => {
const methodDataHelper = new MethodDataHelper({
getState: () => ({}),
});

const updateListener = jest.fn();
methodDataHelper.hub.on('update', updateListener);

await methodDataHelper.lookup(
FOUR_BYTE_PREFIX_MOCK,
NETWORK_CLIENT_ID_MOCK,
);
const fourBytePrefix = '0x13af4035';
await methodDataHelper.lookup(fourBytePrefix, NETWORK_CLIENT_ID_MOCK);

expect(updateListener).toHaveBeenCalledTimes(1);
expect(updateListener).toHaveBeenCalledWith({
fourBytePrefix: FOUR_BYTE_PREFIX_MOCK,
methodData: METHOD_DATA_MOCK,
fourBytePrefix,
methodData: {
registryMethod: 'setOwner(address)',
parsedRegistryMethod: {
name: 'setOwner',
args: [{ type: 'address' }],
},
},
});
});
});
Expand Down

0 comments on commit 455ba54

Please sign in to comment.