You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
6.9 KiB
229 lines
6.9 KiB
import React from 'react';
|
|
import configureMockStore from 'redux-mock-store';
|
|
import thunk from 'redux-thunk';
|
|
import { useLocation } from 'react-router-dom';
|
|
import { SEND_STAGES, startNewDraftTransaction } from '../../ducks/send';
|
|
import { domainInitialState } from '../../ducks/domains';
|
|
import { renderWithProvider } from '../../../test/jest';
|
|
import { CHAIN_IDS } from '../../../shared/constants/network';
|
|
import { GAS_ESTIMATE_TYPES } from '../../../shared/constants/gas';
|
|
import { KEYRING_TYPES } from '../../../shared/constants/keyrings';
|
|
import { INITIAL_SEND_STATE_FOR_EXISTING_DRAFT } from '../../../test/jest/mocks';
|
|
import Send from './send';
|
|
|
|
const middleware = [thunk];
|
|
|
|
jest.mock('../../ducks/send/send', () => {
|
|
const original = jest.requireActual('../../ducks/send/send');
|
|
return {
|
|
...original,
|
|
// We don't really need to start a draft transaction, and the mock store
|
|
// does not update as a result of action calls so instead we just ensure
|
|
// that the action WOULD be called.
|
|
startNewDraftTransaction: jest.fn(() => ({
|
|
type: 'TEST_START_NEW_DRAFT',
|
|
payload: null,
|
|
})),
|
|
};
|
|
});
|
|
|
|
jest.mock('react-router-dom', () => {
|
|
const original = jest.requireActual('react-router-dom');
|
|
return {
|
|
...original,
|
|
useLocation: jest.fn(() => ({ search: '' })),
|
|
useHistory: () => ({
|
|
push: jest.fn(),
|
|
}),
|
|
};
|
|
});
|
|
|
|
jest.mock('ethers', () => {
|
|
const originalModule = jest.requireActual('ethers');
|
|
return {
|
|
...originalModule,
|
|
ethers: {
|
|
...originalModule.ethers,
|
|
providers: {
|
|
Web3Provider: jest.fn().mockImplementation(() => {
|
|
return {};
|
|
}),
|
|
},
|
|
},
|
|
};
|
|
});
|
|
const baseStore = {
|
|
send: INITIAL_SEND_STATE_FOR_EXISTING_DRAFT,
|
|
DNS: domainInitialState,
|
|
gas: {
|
|
customData: { limit: null, price: null },
|
|
},
|
|
history: { mostRecentOverviewPage: 'activity' },
|
|
metamask: {
|
|
gasEstimateType: GAS_ESTIMATE_TYPES.LEGACY,
|
|
gasFeeEstimates: {
|
|
low: '0',
|
|
medium: '1',
|
|
fast: '2',
|
|
},
|
|
selectedAddress: '0x0',
|
|
keyrings: [
|
|
{
|
|
type: KEYRING_TYPES.HD_KEY_TREE,
|
|
accounts: ['0x0'],
|
|
},
|
|
],
|
|
networkDetails: {
|
|
EIPS: {},
|
|
},
|
|
tokens: [],
|
|
preferences: {
|
|
useNativeCurrencyAsPrimaryCurrency: false,
|
|
},
|
|
currentCurrency: 'USD',
|
|
provider: {
|
|
chainId: CHAIN_IDS.GOERLI,
|
|
},
|
|
nativeCurrency: 'ETH',
|
|
featureFlags: {
|
|
sendHexData: false,
|
|
},
|
|
addressBook: {
|
|
[CHAIN_IDS.GOERLI]: [],
|
|
},
|
|
cachedBalances: {
|
|
[CHAIN_IDS.GOERLI]: {},
|
|
},
|
|
accounts: {
|
|
'0x0': { balance: '0x0', address: '0x0' },
|
|
},
|
|
identities: { '0x0': { address: '0x0' } },
|
|
tokenAddress: '0x32e6c34cd57087abbd59b5a4aecc4cb495924356',
|
|
tokenList: {
|
|
'0x32e6c34cd57087abbd59b5a4aecc4cb495924356': {
|
|
name: 'BitBase',
|
|
symbol: 'BTBS',
|
|
decimals: 18,
|
|
address: '0x32E6C34Cd57087aBBD59B5A4AECC4cB495924356',
|
|
iconUrl: 'BTBS.svg',
|
|
occurrences: null,
|
|
},
|
|
'0x3fa400483487a489ec9b1db29c4129063eec4654': {
|
|
name: 'Cryptokek.com',
|
|
symbol: 'KEK',
|
|
decimals: 18,
|
|
address: '0x3fa400483487A489EC9b1dB29C4129063EEC4654',
|
|
iconUrl: 'cryptokek.svg',
|
|
occurrences: null,
|
|
},
|
|
},
|
|
},
|
|
appState: {
|
|
sendInputCurrencySwitched: false,
|
|
},
|
|
};
|
|
|
|
describe('Send Page', () => {
|
|
describe('Send Flow Initialization', () => {
|
|
it('should initialize the ENS slice on render', () => {
|
|
const store = configureMockStore(middleware)(baseStore);
|
|
renderWithProvider(<Send />, store);
|
|
const actions = store.getActions();
|
|
expect(actions).toStrictEqual(
|
|
expect.arrayContaining([
|
|
expect.objectContaining({
|
|
type: 'DNS/enableDomainLookup',
|
|
}),
|
|
]),
|
|
);
|
|
});
|
|
|
|
it('should showQrScanner when location.search is ?scan=true', () => {
|
|
useLocation.mockImplementation(() => ({ search: '?scan=true' }));
|
|
const store = configureMockStore(middleware)(baseStore);
|
|
renderWithProvider(<Send />, store);
|
|
const actions = store.getActions();
|
|
expect(actions).toStrictEqual(
|
|
expect.arrayContaining([
|
|
expect.objectContaining({
|
|
type: 'DNS/enableDomainLookup',
|
|
}),
|
|
expect.objectContaining({
|
|
type: 'UI_MODAL_OPEN',
|
|
payload: { name: 'QR_SCANNER' },
|
|
}),
|
|
]),
|
|
);
|
|
useLocation.mockImplementation(() => ({ search: '' }));
|
|
});
|
|
});
|
|
|
|
describe('Send Flow', () => {
|
|
it('should render the header with Send to displayed', () => {
|
|
const store = configureMockStore(middleware)(baseStore);
|
|
const { getByText } = renderWithProvider(<Send />, store);
|
|
expect(getByText('Send to')).toBeTruthy();
|
|
});
|
|
|
|
it('should render the DomainInput field', () => {
|
|
const store = configureMockStore(middleware)(baseStore);
|
|
const { getByPlaceholderText } = renderWithProvider(<Send />, store);
|
|
expect(
|
|
getByPlaceholderText('Search, public address (0x), or ENS'),
|
|
).toBeTruthy();
|
|
});
|
|
|
|
it('should not render the footer', () => {
|
|
const store = configureMockStore(middleware)(baseStore);
|
|
const { queryByText } = renderWithProvider(<Send />, store);
|
|
expect(queryByText('Next')).toBeNull();
|
|
});
|
|
|
|
it('should render correctly even when a draftTransaction does not exist', () => {
|
|
const modifiedStore = {
|
|
...baseStore,
|
|
send: {
|
|
...baseStore.send,
|
|
currentTransactionUUID: null,
|
|
},
|
|
};
|
|
const store = configureMockStore(middleware)(modifiedStore);
|
|
const { getByPlaceholderText } = renderWithProvider(<Send />, store);
|
|
// Ensure that the send flow renders on the add recipient screen when
|
|
// there is no draft transaction.
|
|
expect(
|
|
getByPlaceholderText('Search, public address (0x), or ENS'),
|
|
).toBeTruthy();
|
|
// Ensure we start a new draft transaction when its missing.
|
|
expect(startNewDraftTransaction).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|
|
|
|
describe('Send and Edit Flow (draft)', () => {
|
|
it('should render the header with Send displayed', () => {
|
|
const store = configureMockStore(middleware)({
|
|
...baseStore,
|
|
send: { ...baseStore.send, stage: SEND_STAGES.DRAFT },
|
|
});
|
|
const { getByText } = renderWithProvider(<Send />, store);
|
|
expect(getByText('Send')).toBeTruthy();
|
|
});
|
|
|
|
it('should render the DomainInput field', () => {
|
|
const store = configureMockStore(middleware)(baseStore);
|
|
const { getByPlaceholderText } = renderWithProvider(<Send />, store);
|
|
expect(
|
|
getByPlaceholderText('Search, public address (0x), or ENS'),
|
|
).toBeTruthy();
|
|
});
|
|
|
|
it('should render the footer', () => {
|
|
const store = configureMockStore(middleware)({
|
|
...baseStore,
|
|
send: { ...baseStore.send, stage: SEND_STAGES.DRAFT },
|
|
});
|
|
const { getByText } = renderWithProvider(<Send />, store);
|
|
expect(getByText('Next')).toBeTruthy();
|
|
});
|
|
});
|
|
});
|
|
|