mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-01 21:57:06 +01:00
291 lines
8.7 KiB
JavaScript
291 lines
8.7 KiB
JavaScript
|
import React from 'react';
|
||
|
import configureMockStore from 'redux-mock-store';
|
||
|
import thunk from 'redux-thunk';
|
||
|
|
||
|
import ReactRouterDOM from 'react-router-dom';
|
||
|
|
||
|
import * as ConfirmTransactionDucks from '../../ducks/confirm-transaction/confirm-transaction.duck';
|
||
|
import * as Actions from '../../store/actions';
|
||
|
import _mockState from '../../../test/data/mock-state.json';
|
||
|
import { renderWithProvider } from '../../../test/lib/render-helpers';
|
||
|
import { setBackgroundConnection } from '../../../test/jest';
|
||
|
|
||
|
import {
|
||
|
CONFIRM_TRANSACTION_ROUTE,
|
||
|
CONFIRM_DEPLOY_CONTRACT_PATH,
|
||
|
CONFIRM_SEND_ETHER_PATH,
|
||
|
CONFIRM_TOKEN_METHOD_PATH,
|
||
|
SIGNATURE_REQUEST_PATH,
|
||
|
DECRYPT_MESSAGE_REQUEST_PATH,
|
||
|
ENCRYPTION_PUBLIC_KEY_REQUEST_PATH,
|
||
|
} from '../../helpers/constants/routes';
|
||
|
|
||
|
import ConfirmTransaction from '.';
|
||
|
|
||
|
const mockUnapprovedTx = Object.values(_mockState.metamask.unapprovedTxs)[0];
|
||
|
|
||
|
const middleware = [thunk];
|
||
|
|
||
|
const mockState = {
|
||
|
metamask: {
|
||
|
..._mockState.metamask,
|
||
|
},
|
||
|
appState: {
|
||
|
gasLoadingAnimationIsShowing: false,
|
||
|
},
|
||
|
history: {
|
||
|
mostRecentOverviewPage: '/',
|
||
|
},
|
||
|
send: {
|
||
|
draftTransactions: {},
|
||
|
},
|
||
|
};
|
||
|
|
||
|
setBackgroundConnection({
|
||
|
addPollingTokenToAppState: jest.fn(),
|
||
|
disconnectGasFeeEstimatePoller: jest.fn(),
|
||
|
getContractMethodData: jest.fn(),
|
||
|
getGasFeeEstimatesAndStartPolling: jest.fn(),
|
||
|
removePollingTokenFromAppState: jest.fn(),
|
||
|
setDefaultHomeActiveTabName: jest.fn(),
|
||
|
});
|
||
|
|
||
|
jest.mock('../../ducks/confirm-transaction/confirm-transaction.duck', () => ({
|
||
|
setTransactionToConfirm: jest.fn().mockImplementation((txId) => {
|
||
|
return { type: 'mock-set-transaction-to-confirm', value: txId };
|
||
|
}),
|
||
|
}));
|
||
|
|
||
|
jest.mock('react-router-dom', () => {
|
||
|
const original = jest.requireActual('react-router-dom');
|
||
|
return {
|
||
|
...original,
|
||
|
useHistory: () => ({
|
||
|
replace: jest.fn(),
|
||
|
}),
|
||
|
};
|
||
|
});
|
||
|
|
||
|
jest.mock('../confirm-contract-interaction', () => {
|
||
|
return {
|
||
|
__esModule: true,
|
||
|
default: () => {
|
||
|
return <div className="mock-confirm-contract-interaction" />;
|
||
|
},
|
||
|
};
|
||
|
});
|
||
|
jest.mock('../confirm-decrypt-message', () => {
|
||
|
return {
|
||
|
__esModule: true,
|
||
|
default: () => {
|
||
|
return <div className="mock-confirm-decrypt-message" />;
|
||
|
},
|
||
|
};
|
||
|
});
|
||
|
jest.mock('../confirm-deploy-contract', () => {
|
||
|
return {
|
||
|
__esModule: true,
|
||
|
default: () => {
|
||
|
return <div className="mock-confirm-deploy-contract" />;
|
||
|
},
|
||
|
};
|
||
|
});
|
||
|
jest.mock('../confirm-encryption-public-key', () => {
|
||
|
return {
|
||
|
__esModule: true,
|
||
|
default: () => {
|
||
|
return <div className="mock-confirm-encryption-public-key" />;
|
||
|
},
|
||
|
};
|
||
|
});
|
||
|
jest.mock('../confirm-send-ether', () => {
|
||
|
return {
|
||
|
__esModule: true,
|
||
|
default: () => {
|
||
|
return <div className="mock-confirm-send-ether" />;
|
||
|
},
|
||
|
};
|
||
|
});
|
||
|
jest.mock('../confirm-signature-request', () => {
|
||
|
return {
|
||
|
__esModule: true,
|
||
|
default: () => {
|
||
|
return <div className="mock-confirm-signature-request" />;
|
||
|
},
|
||
|
};
|
||
|
});
|
||
|
jest.mock('./confirm-token-transaction-switch', () => {
|
||
|
return {
|
||
|
__esModule: true,
|
||
|
default: () => {
|
||
|
return <div className="mock-confirm-token-transaction-switch" />;
|
||
|
},
|
||
|
};
|
||
|
});
|
||
|
jest.mock('../confirm-transaction-switch', () => {
|
||
|
return {
|
||
|
__esModule: true,
|
||
|
default: () => {
|
||
|
return <div className="mock-confirm-transaction-switch" />;
|
||
|
},
|
||
|
};
|
||
|
});
|
||
|
|
||
|
describe('Confirmation Transaction Page', () => {
|
||
|
it('should display the Loading component when the transaction is invalid', () => {
|
||
|
const mockStore = configureMockStore(middleware)({
|
||
|
...mockState,
|
||
|
metamask: {
|
||
|
...mockState.metamask,
|
||
|
unapprovedTxs: {},
|
||
|
},
|
||
|
});
|
||
|
const { container } = renderWithProvider(<ConfirmTransaction />, mockStore);
|
||
|
|
||
|
expect(container.querySelector('.loading-overlay')).toBeInTheDocument();
|
||
|
expect(container.querySelector('.loading-overlay')).toMatchSnapshot();
|
||
|
});
|
||
|
|
||
|
it('should not display the Loading component when the transaction is valid', () => {
|
||
|
const mockStore = configureMockStore(middleware)({ ...mockState });
|
||
|
const { container } = renderWithProvider(<ConfirmTransaction />, mockStore);
|
||
|
expect(container.querySelector('.loading-overlay')).toBeNull();
|
||
|
});
|
||
|
|
||
|
[
|
||
|
[CONFIRM_DEPLOY_CONTRACT_PATH, '.mock-confirm-deploy-contract'],
|
||
|
[CONFIRM_SEND_ETHER_PATH, '.mock-confirm-send-ether'],
|
||
|
[CONFIRM_TOKEN_METHOD_PATH, '.mock-confirm-contract-interaction'],
|
||
|
[DECRYPT_MESSAGE_REQUEST_PATH, '.mock-confirm-decrypt-message'],
|
||
|
[ENCRYPTION_PUBLIC_KEY_REQUEST_PATH, '.mock-confirm-encryption-public-key'],
|
||
|
[SIGNATURE_REQUEST_PATH, '.mock-confirm-signature-request'],
|
||
|
].forEach(([componentPath, mockClassNameMatch]) => {
|
||
|
it(`should render "${componentPath}" route`, () => {
|
||
|
const mockStore = configureMockStore(middleware)(mockState);
|
||
|
const { container } = renderWithProvider(
|
||
|
<ConfirmTransaction />,
|
||
|
mockStore,
|
||
|
`${CONFIRM_TRANSACTION_ROUTE}/${mockUnapprovedTx.id}${componentPath}`,
|
||
|
);
|
||
|
|
||
|
expect(container.querySelector(mockClassNameMatch)).toBeInTheDocument();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it(`should render ConfirmTokenTransactionSwitch component if it's a valid ERC20 token method`, () => {
|
||
|
const mockStore = configureMockStore(middleware)({
|
||
|
...mockState,
|
||
|
metamask: {
|
||
|
...mockState.metamask,
|
||
|
unapprovedTxs: {
|
||
|
[mockUnapprovedTx.id]: {
|
||
|
...mockUnapprovedTx,
|
||
|
type: 'transfer',
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
});
|
||
|
const { container } = renderWithProvider(
|
||
|
<ConfirmTransaction />,
|
||
|
mockStore,
|
||
|
// use valid matched route path to check against ConfirmTokenTransactionSwitch
|
||
|
`${CONFIRM_TRANSACTION_ROUTE}/${mockUnapprovedTx.id}${CONFIRM_DEPLOY_CONTRACT_PATH}`,
|
||
|
);
|
||
|
|
||
|
expect(
|
||
|
container.querySelector('.mock-confirm-token-transaction-switch'),
|
||
|
).toBeInTheDocument();
|
||
|
});
|
||
|
|
||
|
it(`should render ConfirmTransactionSwitch component if the route path is unmatched and the transaction is valid`, () => {
|
||
|
const mockStore = configureMockStore(middleware)(mockState);
|
||
|
const { container } = renderWithProvider(
|
||
|
<ConfirmTransaction />,
|
||
|
mockStore,
|
||
|
`/unknown-path`,
|
||
|
);
|
||
|
|
||
|
expect(
|
||
|
container.querySelector('.mock-confirm-transaction-switch'),
|
||
|
).toBeInTheDocument();
|
||
|
});
|
||
|
|
||
|
describe('initialization', () => {
|
||
|
it('should poll for gas estimates', () => {
|
||
|
const mockStore = configureMockStore(middleware)(mockState);
|
||
|
const gasEstimationPollingSpy = jest.spyOn(
|
||
|
Actions,
|
||
|
'getGasFeeEstimatesAndStartPolling',
|
||
|
);
|
||
|
|
||
|
renderWithProvider(<ConfirmTransaction />, mockStore);
|
||
|
|
||
|
expect(gasEstimationPollingSpy).toHaveBeenCalled();
|
||
|
});
|
||
|
|
||
|
it('should call setTransactionToConfirm if transaction id is provided', () => {
|
||
|
const mockStore = configureMockStore(middleware)({ ...mockState });
|
||
|
ConfirmTransactionDucks.setTransactionToConfirm.mockClear();
|
||
|
|
||
|
renderWithProvider(<ConfirmTransaction />, mockStore);
|
||
|
|
||
|
expect(
|
||
|
ConfirmTransactionDucks.setTransactionToConfirm,
|
||
|
).toHaveBeenCalled();
|
||
|
});
|
||
|
|
||
|
it('should not call setTransactionToConfirm when transaction id is not provided', () => {
|
||
|
const mockStore = configureMockStore(middleware)({
|
||
|
...mockState,
|
||
|
metamask: { ...mockState.metamask, unapprovedTxs: {} },
|
||
|
});
|
||
|
jest.spyOn(ReactRouterDOM, 'useParams').mockImplementation(() => {
|
||
|
return { id: null };
|
||
|
});
|
||
|
ConfirmTransactionDucks.setTransactionToConfirm.mockClear();
|
||
|
|
||
|
renderWithProvider(<ConfirmTransaction />, mockStore);
|
||
|
|
||
|
expect(
|
||
|
ConfirmTransactionDucks.setTransactionToConfirm,
|
||
|
).not.toHaveBeenCalled();
|
||
|
});
|
||
|
|
||
|
describe('when unapproved transactions exist or a sendTo recipient exists', () => {
|
||
|
it('should not call history.replace(mostRecentOverviewPage)', () => {
|
||
|
const mockStore = configureMockStore(middleware)(mockState);
|
||
|
const replaceSpy = jest.fn();
|
||
|
jest.spyOn(ReactRouterDOM, 'useHistory').mockImplementation(() => {
|
||
|
return {
|
||
|
replace: replaceSpy,
|
||
|
};
|
||
|
});
|
||
|
|
||
|
renderWithProvider(<ConfirmTransaction />, mockStore);
|
||
|
expect(replaceSpy).not.toHaveBeenCalled();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('when no unapproved transactions and no sendTo recipient exist', () => {
|
||
|
it('should call history.replace(mostRecentOverviewPage)', () => {
|
||
|
const mockStore = configureMockStore(middleware)({
|
||
|
...mockState,
|
||
|
metamask: {
|
||
|
...mockState.metamask,
|
||
|
unapprovedTxs: {},
|
||
|
},
|
||
|
});
|
||
|
const replaceSpy = jest.fn();
|
||
|
jest.spyOn(ReactRouterDOM, 'useHistory').mockImplementation(() => {
|
||
|
return {
|
||
|
replace: replaceSpy,
|
||
|
};
|
||
|
});
|
||
|
|
||
|
renderWithProvider(<ConfirmTransaction />, mockStore, '/asdfb');
|
||
|
expect(replaceSpy).toHaveBeenCalled();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|