mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-29 07:16:36 +01:00
154 lines
4.5 KiB
TypeScript
154 lines
4.5 KiB
TypeScript
|
import { handleFetch } from '@metamask/controller-utils';
|
||
|
|
||
|
import {
|
||
|
CHAIN_IDS,
|
||
|
ETHERSCAN_SUPPORTED_NETWORKS,
|
||
|
} from '../../../../shared/constants/network';
|
||
|
import type {
|
||
|
EtherscanTransactionMeta,
|
||
|
EtherscanTransactionRequest,
|
||
|
EtherscanTransactionResponse,
|
||
|
} from './etherscan';
|
||
|
import * as Etherscan from './etherscan';
|
||
|
|
||
|
jest.mock('@metamask/controller-utils', () => ({
|
||
|
...jest.requireActual('@metamask/controller-utils'),
|
||
|
handleFetch: jest.fn(),
|
||
|
}));
|
||
|
|
||
|
const ADDERSS_MOCK = '0x2A2D72308838A6A46a0B5FDA3055FE915b5D99eD';
|
||
|
|
||
|
const REQUEST_MOCK: EtherscanTransactionRequest = {
|
||
|
address: ADDERSS_MOCK,
|
||
|
chainId: CHAIN_IDS.GOERLI,
|
||
|
limit: 3,
|
||
|
fromBlock: 2,
|
||
|
apiKey: 'testApiKey',
|
||
|
};
|
||
|
|
||
|
const RESPONSE_MOCK: EtherscanTransactionResponse<EtherscanTransactionMeta> = {
|
||
|
result: [
|
||
|
{ from: ADDERSS_MOCK, nonce: '0x1' } as EtherscanTransactionMeta,
|
||
|
{ from: ADDERSS_MOCK, nonce: '0x2' } as EtherscanTransactionMeta,
|
||
|
],
|
||
|
};
|
||
|
|
||
|
describe('Etherscan', () => {
|
||
|
const handleFetchMock = handleFetch as jest.MockedFunction<
|
||
|
typeof handleFetch
|
||
|
>;
|
||
|
|
||
|
beforeEach(() => {
|
||
|
jest.resetAllMocks();
|
||
|
});
|
||
|
|
||
|
describe.each([
|
||
|
['fetchEtherscanTransactions', 'txlist'],
|
||
|
['fetchEtherscanTokenTransactions', 'tokentx'],
|
||
|
])('%s', (method, action) => {
|
||
|
it('returns fetched response', async () => {
|
||
|
handleFetchMock.mockResolvedValueOnce(RESPONSE_MOCK);
|
||
|
|
||
|
const result = await (Etherscan as any)[method](REQUEST_MOCK);
|
||
|
|
||
|
expect(result).toStrictEqual(RESPONSE_MOCK);
|
||
|
});
|
||
|
|
||
|
it('fetches from Etherscan URL', async () => {
|
||
|
handleFetchMock.mockResolvedValueOnce(RESPONSE_MOCK);
|
||
|
|
||
|
await (Etherscan as any)[method](REQUEST_MOCK);
|
||
|
|
||
|
expect(handleFetchMock).toHaveBeenCalledTimes(1);
|
||
|
expect(handleFetchMock).toHaveBeenCalledWith(
|
||
|
`https://${ETHERSCAN_SUPPORTED_NETWORKS[CHAIN_IDS.GOERLI].subdomain}.${
|
||
|
ETHERSCAN_SUPPORTED_NETWORKS[CHAIN_IDS.GOERLI].domain
|
||
|
}/api?` +
|
||
|
`module=account` +
|
||
|
`&address=${REQUEST_MOCK.address}` +
|
||
|
`&startBlock=${REQUEST_MOCK.fromBlock}` +
|
||
|
`&apikey=${REQUEST_MOCK.apiKey}` +
|
||
|
`&offset=${REQUEST_MOCK.limit}` +
|
||
|
`&order=desc` +
|
||
|
`&action=${action}` +
|
||
|
`&tag=latest` +
|
||
|
`&page=1`,
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('supports alternate networks', async () => {
|
||
|
handleFetchMock.mockResolvedValueOnce(RESPONSE_MOCK);
|
||
|
|
||
|
await (Etherscan as any)[method]({
|
||
|
...REQUEST_MOCK,
|
||
|
chainId: CHAIN_IDS.MAINNET,
|
||
|
});
|
||
|
|
||
|
expect(handleFetchMock).toHaveBeenCalledTimes(1);
|
||
|
expect(handleFetchMock).toHaveBeenCalledWith(
|
||
|
`https://${ETHERSCAN_SUPPORTED_NETWORKS[CHAIN_IDS.MAINNET].subdomain}.${
|
||
|
ETHERSCAN_SUPPORTED_NETWORKS[CHAIN_IDS.MAINNET].domain
|
||
|
}/api?` +
|
||
|
`module=account` +
|
||
|
`&address=${REQUEST_MOCK.address}` +
|
||
|
`&startBlock=${REQUEST_MOCK.fromBlock}` +
|
||
|
`&apikey=${REQUEST_MOCK.apiKey}` +
|
||
|
`&offset=${REQUEST_MOCK.limit}` +
|
||
|
`&order=desc` +
|
||
|
`&action=${action}` +
|
||
|
`&tag=latest` +
|
||
|
`&page=1`,
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('throws if message is not ok', async () => {
|
||
|
handleFetchMock.mockResolvedValueOnce({
|
||
|
status: '0',
|
||
|
message: 'NOTOK',
|
||
|
result: 'test error',
|
||
|
});
|
||
|
|
||
|
await expect((Etherscan as any)[method](REQUEST_MOCK)).rejects.toThrow(
|
||
|
'Etherscan request failed - test error',
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('throws if chain is not supported', async () => {
|
||
|
const unsupportedChainId = '0x11111111111111111111';
|
||
|
|
||
|
await expect(
|
||
|
(Etherscan as any)[method]({
|
||
|
...REQUEST_MOCK,
|
||
|
chainId: unsupportedChainId,
|
||
|
}),
|
||
|
).rejects.toThrow(
|
||
|
`Etherscan does not support chain with ID: ${unsupportedChainId}`,
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('does not include empty values in fetched URL', async () => {
|
||
|
handleFetchMock.mockResolvedValueOnce(RESPONSE_MOCK);
|
||
|
|
||
|
await (Etherscan as any)[method]({
|
||
|
...REQUEST_MOCK,
|
||
|
fromBlock: undefined,
|
||
|
apiKey: undefined,
|
||
|
});
|
||
|
|
||
|
expect(handleFetchMock).toHaveBeenCalledTimes(1);
|
||
|
expect(handleFetchMock).toHaveBeenCalledWith(
|
||
|
`https://${ETHERSCAN_SUPPORTED_NETWORKS[CHAIN_IDS.GOERLI].subdomain}.${
|
||
|
ETHERSCAN_SUPPORTED_NETWORKS[CHAIN_IDS.GOERLI].domain
|
||
|
}/api?` +
|
||
|
`module=account` +
|
||
|
`&address=${REQUEST_MOCK.address}` +
|
||
|
`&offset=${REQUEST_MOCK.limit}` +
|
||
|
`&order=desc` +
|
||
|
`&action=${action}` +
|
||
|
`&tag=latest` +
|
||
|
`&page=1`,
|
||
|
);
|
||
|
});
|
||
|
});
|
||
|
});
|