Various component tests and some conditional statements (#7765)
* Various component tests and some conditional statements Conditional in account-menu in removeAccount when keyring sometimes is not initially provideed Conditional on unlock-page when there is no target.getBoundingClientRect on the element. * Update helpers * Remove component debugging * Add default params for render helpers * Remove stubComponent for old Mascot Changes in https://github.com/MetaMask/metamask-extension/pull/7893 has prevented the need to stub it out. Change logout to lock in account-menu testfeature/default_network_editable
parent
608a1fc298
commit
5d1c9313db
@ -0,0 +1,209 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import configureMockStore from 'redux-mock-store' |
||||
import { mountWithRouter } from '../../../../../../test/lib/render-helpers' |
||||
import AccountMenu from '../index' |
||||
import { Provider } from 'react-redux' |
||||
|
||||
describe('Account Menu', async () => { |
||||
|
||||
let wrapper |
||||
|
||||
const mockStore = { |
||||
metamask: { |
||||
provider: { |
||||
type: 'test', |
||||
}, |
||||
preferences: { |
||||
useNativeCurrencyAsPrimaryCurrency: true, |
||||
}, |
||||
}, |
||||
} |
||||
|
||||
const store = configureMockStore()(mockStore) |
||||
|
||||
const props = { |
||||
isAccountMenuOpen: true, |
||||
addressConnectedDomainMap: {}, |
||||
accounts: [ |
||||
{ |
||||
address: '0xAddress', |
||||
name: 'Account 1', |
||||
balance: '0x0', |
||||
}, |
||||
{ |
||||
address: '0xImportedAddress', |
||||
name: 'Imported Account 1', |
||||
balance: '0x0', |
||||
}, |
||||
], |
||||
keyrings: [ |
||||
{ |
||||
type: 'HD Key Tree', |
||||
accounts: [ |
||||
'0xAdress', |
||||
], |
||||
}, |
||||
{ |
||||
type: 'Simple Key Pair', |
||||
accounts: [ |
||||
'0xImportedAddress', |
||||
], |
||||
}, |
||||
], |
||||
prevIsAccountMenuOpen: false, |
||||
lockMetamask: sinon.spy(), |
||||
showAccountDetail: sinon.spy(), |
||||
showRemoveAccountConfirmationModal: sinon.spy(), |
||||
toggleAccountMenu: sinon.spy(), |
||||
history: { |
||||
push: sinon.spy(), |
||||
}, |
||||
|
||||
} |
||||
|
||||
before(() => { |
||||
wrapper = mountWithRouter( |
||||
<Provider store={store}> |
||||
<AccountMenu.WrappedComponent {...props} /> |
||||
</Provider>, store |
||||
) |
||||
}) |
||||
|
||||
afterEach(() => { |
||||
props.toggleAccountMenu.resetHistory() |
||||
props.history.push.resetHistory() |
||||
}) |
||||
|
||||
describe('Render Content', () => { |
||||
it('returns account name from identities', () => { |
||||
const accountName = wrapper.find('.account-menu__name') |
||||
assert.equal(accountName.length, 2) |
||||
}) |
||||
|
||||
it('renders user preference currency display balance from account balance', () => { |
||||
const accountBalance = wrapper.find('.currency-display-component.account-menu__balance') |
||||
assert.equal(accountBalance.length, 2) |
||||
}) |
||||
|
||||
it('simulate click', () => { |
||||
const click = wrapper.find('.account-menu__account.menu__item--clickable') |
||||
click.first().simulate('click') |
||||
|
||||
assert(props.showAccountDetail.calledOnce) |
||||
assert.equal(props.showAccountDetail.getCall(0).args[0], '0xAddress') |
||||
}) |
||||
|
||||
it('render imported account label', () => { |
||||
const importedAccount = wrapper.find('.keyring-label.allcaps') |
||||
assert.equal(importedAccount.text(), 'imported') |
||||
}) |
||||
|
||||
it('remove account', () => { |
||||
const removeAccount = wrapper.find('.remove-account-icon') |
||||
removeAccount.simulate('click', { |
||||
preventDefault: () => {}, |
||||
stopPropagation: () => {}, |
||||
}) |
||||
|
||||
assert(props.showRemoveAccountConfirmationModal.calledOnce) |
||||
assert.deepEqual(props.showRemoveAccountConfirmationModal.getCall(0).args[0], |
||||
{ address: '0xImportedAddress', balance: '0x0', name: 'Imported Account 1' } |
||||
) |
||||
}) |
||||
}) |
||||
|
||||
describe('Log Out', () => { |
||||
let logout |
||||
|
||||
it('logout', () => { |
||||
logout = wrapper.find('.account-menu__lock-button') |
||||
assert.equal(logout.length, 1) |
||||
}) |
||||
|
||||
it('simulate click', () => { |
||||
logout.simulate('click') |
||||
assert(props.lockMetamask.calledOnce) |
||||
assert.equal(props.history.push.getCall(0).args[0], '/') |
||||
}) |
||||
}) |
||||
|
||||
describe('Create Account', () => { |
||||
let createAccount |
||||
|
||||
it('renders create account item', () => { |
||||
createAccount = wrapper.find({ text: 'createAccount' }) |
||||
assert.equal(createAccount.length, 1) |
||||
}) |
||||
|
||||
it('calls toggle menu and push new-account route to history', () => { |
||||
createAccount.simulate('click') |
||||
assert(props.toggleAccountMenu.calledOnce) |
||||
assert.equal(props.history.push.getCall(0).args[0], '/new-account') |
||||
}) |
||||
}) |
||||
|
||||
describe('Import Account', () => { |
||||
let importAccount |
||||
|
||||
it('renders import account item', () => { |
||||
importAccount = wrapper.find({ text: 'importAccount' }) |
||||
assert.equal(importAccount.length, 1) |
||||
}) |
||||
|
||||
it('calls toggle menu and push /new-account/import route to history', () => { |
||||
importAccount.simulate('click') |
||||
assert(props.toggleAccountMenu.calledOnce) |
||||
assert(props.history.push.getCall(0).args[0], '/new-account/import') |
||||
}) |
||||
}) |
||||
|
||||
describe('Connect Hardware Wallet', () => { |
||||
|
||||
let connectHardwareWallet |
||||
|
||||
it('renders import account item', () => { |
||||
connectHardwareWallet = wrapper.find({ text: 'connectHardwareWallet' }) |
||||
assert.equal(connectHardwareWallet.length, 1) |
||||
}) |
||||
|
||||
it('calls toggle menu and push /new-account/connect route to history', () => { |
||||
connectHardwareWallet.simulate('click') |
||||
assert(props.toggleAccountMenu.calledOnce) |
||||
assert.equal(props.history.push.getCall(0).args[0], '/new-account/connect') |
||||
}) |
||||
}) |
||||
|
||||
describe('Info & Help', () => { |
||||
|
||||
let infoHelp |
||||
|
||||
it('renders import account item', () => { |
||||
infoHelp = wrapper.find({ text: 'infoHelp' }) |
||||
assert.equal(infoHelp.length, 1) |
||||
}) |
||||
|
||||
it('calls toggle menu and push /new-account/connect route to history', () => { |
||||
infoHelp.simulate('click') |
||||
assert(props.toggleAccountMenu.calledOnce) |
||||
assert.equal(props.history.push.getCall(0).args[0], '/settings/about-us') |
||||
}) |
||||
}) |
||||
|
||||
describe('Settings', () => { |
||||
|
||||
let settings |
||||
|
||||
it('renders import account item', () => { |
||||
settings = wrapper.find({ text: 'settings' }) |
||||
assert.equal(settings.length, 1) |
||||
}) |
||||
|
||||
it('calls toggle menu and push /new-account/connect route to history', () => { |
||||
settings.simulate('click') |
||||
assert(props.toggleAccountMenu.calledOnce) |
||||
assert.equal(props.history.push.getCall(0).args[0], '/settings') |
||||
}) |
||||
}) |
||||
}) |
@ -0,0 +1,99 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { shallow } from 'enzyme' |
||||
import MetaFoxLogo from '../../../ui/metafox-logo' |
||||
import AppHeader from '../index' |
||||
|
||||
describe('App Header', () => { |
||||
let wrapper |
||||
|
||||
const props = { |
||||
hideNetworkDropdown: sinon.spy(), |
||||
showNetworkDropdown: sinon.spy(), |
||||
toggleAccountMenu: sinon.spy(), |
||||
history: { |
||||
push: sinon.spy(), |
||||
}, |
||||
network: 'test', |
||||
provider: {}, |
||||
selectedAddress: '0xAddress', |
||||
disabled: false, |
||||
hideNetworkIndicator: false, |
||||
networkDropdownOpen: false, |
||||
isAccountMenuOpen: false, |
||||
isUnlocked: true, |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
wrapper = shallow( |
||||
<AppHeader.WrappedComponent {...props} />, { |
||||
context: { |
||||
t: str => str, |
||||
metricsEvent: () => {}, |
||||
}, |
||||
} |
||||
) |
||||
}) |
||||
|
||||
afterEach(() => { |
||||
props.toggleAccountMenu.resetHistory() |
||||
}) |
||||
|
||||
describe('App Header Logo', () => { |
||||
it('routes to default route when logo is clicked', () => { |
||||
const appLogo = wrapper.find(MetaFoxLogo) |
||||
appLogo.simulate('click') |
||||
assert(props.history.push.calledOnce) |
||||
assert.equal(props.history.push.getCall(0).args[0], '/') |
||||
}) |
||||
}) |
||||
|
||||
describe('Network', () => { |
||||
it('shows network dropdown when networkDropdownOpen is false', () => { |
||||
const network = wrapper.find({ network: 'test' }) |
||||
|
||||
network.simulate('click', { |
||||
preventDefault: () => {}, |
||||
stopPropagation: () => {}, |
||||
}) |
||||
|
||||
assert(props.showNetworkDropdown.calledOnce) |
||||
}) |
||||
|
||||
it('hides network dropdown when networkDropdownOpen is true', () => { |
||||
wrapper.setProps({ networkDropdownOpen: true }) |
||||
const network = wrapper.find({ network: 'test' }) |
||||
|
||||
network.simulate('click', { |
||||
preventDefault: () => {}, |
||||
stopPropagation: () => {}, |
||||
}) |
||||
|
||||
assert(props.hideNetworkDropdown.calledOnce) |
||||
}) |
||||
|
||||
it('hides network indicator', () => { |
||||
wrapper.setProps({ hideNetworkIndicator: true }) |
||||
const network = wrapper.find({ network: 'test' }) |
||||
assert.equal(network.length, 0) |
||||
}) |
||||
}) |
||||
|
||||
describe('Account Menu', () => { |
||||
|
||||
it('toggles account menu', () => { |
||||
const accountMenu = wrapper.find('.account-menu__icon') |
||||
accountMenu.simulate('click') |
||||
assert(props.toggleAccountMenu.calledOnce) |
||||
}) |
||||
|
||||
it('does not toggle account menu when disabled', () => { |
||||
wrapper.setProps({ disabled: true }) |
||||
const accountMenu = wrapper.find('.account-menu__icon') |
||||
accountMenu.simulate('click') |
||||
assert(props.toggleAccountMenu.notCalled) |
||||
}) |
||||
}) |
||||
|
||||
}) |
@ -0,0 +1,104 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mount } from 'enzyme' |
||||
import AdvancedTabContent from '../index' |
||||
|
||||
describe('Advanced Gas Inputs', () => { |
||||
let wrapper, clock |
||||
|
||||
const props = { |
||||
updateCustomGasPrice: sinon.spy(), |
||||
updateCustomGasLimit: sinon.spy(), |
||||
showGasPriceInfoModal: sinon.spy(), |
||||
showGasLimitInfoModal: sinon.spy(), |
||||
customGasPrice: 0, |
||||
customGasLimit: 0, |
||||
insufficientBalance: false, |
||||
customPriceIsSafe: true, |
||||
isSpeedUp: false, |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
clock = sinon.useFakeTimers() |
||||
|
||||
wrapper = mount( |
||||
<AdvancedTabContent.WrappedComponent |
||||
{...props} |
||||
/>, { |
||||
context: { |
||||
t: str => str, |
||||
}, |
||||
}) |
||||
}) |
||||
|
||||
afterEach(() => { |
||||
clock.restore() |
||||
}) |
||||
|
||||
it('wont update gasPrice in props before debounce', () => { |
||||
const event = { target: { value: 1 } } |
||||
|
||||
wrapper.find('input').at(0).simulate('change', event) |
||||
clock.tick(499) |
||||
|
||||
assert.equal(props.updateCustomGasPrice.callCount, 0) |
||||
}) |
||||
|
||||
it('simulates onChange on gas price after debounce', () => { |
||||
const event = { target: { value: 1 } } |
||||
|
||||
wrapper.find('input').at(0).simulate('change', event) |
||||
clock.tick(500) |
||||
|
||||
assert.equal(props.updateCustomGasPrice.calledOnce, true) |
||||
assert.equal(props.updateCustomGasPrice.calledWith(1), true) |
||||
}) |
||||
|
||||
it('wont update gasLimit in props before debounce', () => { |
||||
const event = { target: { value: 21000 } } |
||||
|
||||
wrapper.find('input').at(1).simulate('change', event) |
||||
clock.tick(499) |
||||
|
||||
assert.equal(props.updateCustomGasLimit.callCount, 0) |
||||
}) |
||||
|
||||
it('simulates onChange on gas limit after debounce', () => { |
||||
const event = { target: { value: 21000 } } |
||||
|
||||
wrapper.find('input').at(1).simulate('change', event) |
||||
clock.tick(500) |
||||
|
||||
assert.equal(props.updateCustomGasLimit.calledOnce, true) |
||||
assert.equal(props.updateCustomGasLimit.calledWith(21000), true) |
||||
}) |
||||
|
||||
it('errors when insuffientBalance under gas price and gas limit', () => { |
||||
wrapper.setProps({ insufficientBalance: true }) |
||||
const renderError = wrapper.find('.advanced-gas-inputs__gas-edit-row__error-text') |
||||
assert.equal(renderError.length, 2) |
||||
|
||||
assert.equal(renderError.at(0).text(), 'insufficientBalance') |
||||
assert.equal(renderError.at(1).text(), 'insufficientBalance') |
||||
}) |
||||
|
||||
it('errors zero gas price / speed up', () => { |
||||
wrapper.setProps({ isSpeedUp: true }) |
||||
|
||||
const renderError = wrapper.find('.advanced-gas-inputs__gas-edit-row__error-text') |
||||
assert.equal(renderError.length, 2) |
||||
|
||||
assert.equal(renderError.at(0).text(), 'zeroGasPriceOnSpeedUpError') |
||||
assert.equal(renderError.at(1).text(), 'gasLimitTooLow') |
||||
}) |
||||
|
||||
it('warns when custom gas price is too low', () => { |
||||
wrapper.setProps({ customPriceIsSafe: false }) |
||||
|
||||
const renderWarning = wrapper.find('.advanced-gas-inputs__gas-edit-row__warning-text') |
||||
assert.equal(renderWarning.length, 1) |
||||
|
||||
assert.equal(renderWarning.text(), 'gasPriceExtremelyLow') |
||||
}) |
||||
}) |
@ -0,0 +1,37 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { shallow } from 'enzyme' |
||||
|
||||
import InfoBox from '../index' |
||||
|
||||
describe('InfoBox', () => { |
||||
|
||||
let wrapper |
||||
|
||||
const props = { |
||||
title: 'Title', |
||||
description: 'Description', |
||||
onClose: sinon.spy(), |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
wrapper = shallow(<InfoBox {...props} />) |
||||
}) |
||||
|
||||
it('renders title from props', () => { |
||||
const title = wrapper.find('.info-box__title') |
||||
assert.equal(title.text(), props.title) |
||||
}) |
||||
|
||||
it('renders description from props', () => { |
||||
const description = wrapper.find('.info-box__description') |
||||
assert.equal(description.text(), props.description) |
||||
}) |
||||
|
||||
it('closes info box', () => { |
||||
const close = wrapper.find('.info-box__close') |
||||
close.simulate('click') |
||||
assert(props.onClose.calledOnce) |
||||
}) |
||||
}) |
@ -0,0 +1,94 @@ |
||||
import React from 'react' |
||||
import configureStore from 'redux-mock-store' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mountWithRouter } from '../../../../../../test/lib/render-helpers' |
||||
import MenuBar from '../index' |
||||
import { Provider } from 'react-redux' |
||||
|
||||
describe('MenuBar', () => { |
||||
let wrapper |
||||
|
||||
const mockStore = { |
||||
metamask: { |
||||
network: '1', |
||||
selectedAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', |
||||
identities: { |
||||
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': { |
||||
address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', |
||||
name: 'Account 1', |
||||
}, |
||||
}, |
||||
keyrings: [ |
||||
{ |
||||
type: 'HD Key Tree', |
||||
accounts: [ |
||||
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', |
||||
], |
||||
}, |
||||
], |
||||
frequentRpcListDetail: [], |
||||
}, |
||||
appState: { |
||||
sidebar: { |
||||
isOpen: false, |
||||
}, |
||||
}, |
||||
} |
||||
|
||||
const store = configureStore()(mockStore) |
||||
|
||||
afterEach(() => { |
||||
sinon.restore() |
||||
}) |
||||
|
||||
it('shows side bar when sidbarOpen is set to false', () => { |
||||
const props = { |
||||
showSidebar: sinon.spy(), |
||||
} |
||||
|
||||
wrapper = mountWithRouter( |
||||
<Provider store={store}> |
||||
<MenuBar.WrappedComponent {...props} /> |
||||
</Provider>, store |
||||
) |
||||
|
||||
const sidebarButton = wrapper.find('.menu-bar__sidebar-button') |
||||
sidebarButton.simulate('click') |
||||
assert(props.showSidebar.calledOnce) |
||||
}) |
||||
|
||||
it('hides side when sidebarOpen is set to true', () => { |
||||
const props = { |
||||
showSidebar: sinon.spy(), |
||||
hideSidebar: sinon.spy(), |
||||
sidebarOpen: true, |
||||
} |
||||
|
||||
wrapper = mountWithRouter( |
||||
<Provider store={store}> |
||||
<MenuBar.WrappedComponent {...props} /> |
||||
</Provider>, store |
||||
) |
||||
|
||||
const sidebarButton = wrapper.find('.menu-bar__sidebar-button') |
||||
sidebarButton.prop('onClick')() |
||||
assert(props.hideSidebar.calledOnce) |
||||
}) |
||||
|
||||
it('opens account detail menu when account options is clicked', () => { |
||||
const accountOptions = wrapper.find('.menu-bar__open-in-browser') |
||||
accountOptions.simulate('click') |
||||
assert.equal(wrapper.find('MenuBar').instance().state.accountDetailsMenuOpen, true) |
||||
}) |
||||
|
||||
it('sets accountDetailsMenuOpen to false when closed', () => { |
||||
wrapper.find('MenuBar').instance().setState({ accountDetailsMenuOpen: true }) |
||||
wrapper.update() |
||||
|
||||
const accountDetailsMenu = wrapper.find('AccountDetailsDropdown') |
||||
accountDetailsMenu.prop('onClose')() |
||||
|
||||
assert.equal(wrapper.find('MenuBar').instance().state.accountDetailsMenuOpen, false) |
||||
}) |
||||
}) |
@ -0,0 +1,58 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mount } from 'enzyme' |
||||
import ConfirmDeleteNetwork from '../index' |
||||
|
||||
describe('Confirm Delete Network', () => { |
||||
let wrapper |
||||
|
||||
const props = { |
||||
hideModal: sinon.spy(), |
||||
delRpcTarget: sinon.stub().resolves(), |
||||
onConfirm: sinon.spy(), |
||||
target: '', |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
wrapper = mount( |
||||
<ConfirmDeleteNetwork.WrappedComponent {...props} />, { |
||||
context: { |
||||
t: str => str, |
||||
}, |
||||
} |
||||
) |
||||
}) |
||||
|
||||
afterEach(() => { |
||||
props.hideModal.resetHistory() |
||||
props.delRpcTarget.resetHistory() |
||||
props.onConfirm.resetHistory() |
||||
}) |
||||
|
||||
it('renders delete network modal title', () => { |
||||
const modalTitle = wrapper.find('.modal-content__title') |
||||
assert.equal(modalTitle.text(), 'deleteNetwork') |
||||
}) |
||||
|
||||
it('clicks cancel to hide modal', () => { |
||||
const cancelButton = wrapper.find('.button.btn-default.modal-container__footer-button') |
||||
cancelButton.simulate('click') |
||||
|
||||
assert(props.hideModal.calledOnce) |
||||
|
||||
}) |
||||
|
||||
it('clicks delete to delete the target and hides modal', () => { |
||||
const deleteButton = wrapper.find('.button.btn-danger.modal-container__footer-button') |
||||
|
||||
deleteButton.simulate('click') |
||||
|
||||
setImmediate(() => { |
||||
assert(props.delRpcTarget.calledOnce) |
||||
assert(props.hideModal.calledOnce) |
||||
assert(props.onConfirm.calledOnce) |
||||
}) |
||||
}) |
||||
|
||||
}) |
@ -0,0 +1,82 @@ |
||||
import React from 'react' |
||||
import PropTypes from 'prop-types' |
||||
import { Provider } from 'react-redux' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import configureStore from 'redux-mock-store' |
||||
import { mount } from 'enzyme' |
||||
import ConfirmRemoveAccount from '../index' |
||||
|
||||
describe('Confirm Remove Account', () => { |
||||
let wrapper |
||||
|
||||
const state = { |
||||
metamask: { |
||||
|
||||
}, |
||||
} |
||||
|
||||
const props = { |
||||
hideModal: sinon.spy(), |
||||
removeAccount: sinon.stub().resolves(), |
||||
network: '101', |
||||
identity: { |
||||
address: '0xAddress', |
||||
name: 'Account 1', |
||||
}, |
||||
} |
||||
|
||||
|
||||
const mockStore = configureStore() |
||||
const store = mockStore(state) |
||||
|
||||
beforeEach(() => { |
||||
|
||||
wrapper = mount( |
||||
<Provider store={store} > |
||||
<ConfirmRemoveAccount.WrappedComponent {...props} /> |
||||
</Provider>, { |
||||
context: { |
||||
t: str => str, |
||||
store, |
||||
}, |
||||
childContextTypes: { |
||||
t: PropTypes.func, |
||||
store: PropTypes.object, |
||||
}, |
||||
} |
||||
) |
||||
}) |
||||
|
||||
afterEach(() => { |
||||
props.hideModal.resetHistory() |
||||
}) |
||||
|
||||
it('nevermind', () => { |
||||
const nevermind = wrapper.find({ type: 'default' }) |
||||
nevermind.simulate('click') |
||||
|
||||
assert(props.hideModal.calledOnce) |
||||
}) |
||||
|
||||
it('remove', (done) => { |
||||
const remove = wrapper.find({ type: 'secondary' }) |
||||
remove.simulate('click') |
||||
|
||||
assert(props.removeAccount.calledOnce) |
||||
assert.equal(props.removeAccount.getCall(0).args[0], props.identity.address) |
||||
|
||||
setImmediate(() => { |
||||
assert(props.hideModal.calledOnce) |
||||
done() |
||||
}) |
||||
|
||||
}) |
||||
|
||||
it('closes', () => { |
||||
const close = wrapper.find('.modal-container__header-close') |
||||
close.simulate('click') |
||||
|
||||
assert(props.hideModal.calledOnce) |
||||
}) |
||||
}) |
@ -0,0 +1,46 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mount } from 'enzyme' |
||||
import ConfirmResetAccount from '../index' |
||||
|
||||
describe('Confirm Reset Account', () => { |
||||
let wrapper |
||||
|
||||
const props = { |
||||
hideModal: sinon.spy(), |
||||
resetAccount: sinon.stub().resolves(), |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
wrapper = mount( |
||||
<ConfirmResetAccount.WrappedComponent {...props} />, { |
||||
context: { |
||||
t: str => str, |
||||
}, |
||||
} |
||||
) |
||||
}) |
||||
|
||||
afterEach(() => { |
||||
props.hideModal.resetHistory() |
||||
}) |
||||
|
||||
it('hides modal when nevermind button is clicked', () => { |
||||
const nevermind = wrapper.find('.btn-default.modal-container__footer-button') |
||||
nevermind.simulate('click') |
||||
|
||||
assert(props.hideModal.calledOnce) |
||||
}) |
||||
|
||||
it('resets account and hidels modal when reset button is clicked', (done) => { |
||||
const reset = wrapper.find('.btn-danger.modal-container__footer-button') |
||||
reset.simulate('click') |
||||
|
||||
setImmediate(() => { |
||||
assert(props.resetAccount.calledOnce) |
||||
assert(props.hideModal.calledOnce) |
||||
done() |
||||
}) |
||||
}) |
||||
}) |
@ -0,0 +1,55 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mount } from 'enzyme' |
||||
import MetaMetricsOptIn from '../index' |
||||
|
||||
describe('MetaMetrics Opt In', () => { |
||||
let wrapper |
||||
|
||||
const props = { |
||||
setParticipateInMetaMetrics: sinon.stub().resolves(), |
||||
hideModal: sinon.spy(), |
||||
participateInMetaMetrics: null, |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
wrapper = mount( |
||||
<MetaMetricsOptIn.WrappedComponent {...props} />, { |
||||
context: { |
||||
metricsEvent: () => {}, |
||||
}, |
||||
} |
||||
) |
||||
}) |
||||
|
||||
afterEach(() => { |
||||
props.setParticipateInMetaMetrics.resetHistory() |
||||
props.hideModal.resetHistory() |
||||
}) |
||||
|
||||
it('passes false to setParticipateInMetaMetrics and hides modal', (done) => { |
||||
const noThanks = wrapper.find('.btn-default.page-container__footer-button') |
||||
noThanks.simulate('click') |
||||
|
||||
setImmediate(() => { |
||||
assert(props.setParticipateInMetaMetrics.calledOnce) |
||||
assert.equal(props.setParticipateInMetaMetrics.getCall(0).args[0], false) |
||||
assert(props.hideModal.calledOnce) |
||||
done() |
||||
}) |
||||
}) |
||||
|
||||
it('passes true to setParticipateInMetaMetrics and hides modal', (done) => { |
||||
const iAgree = wrapper.find('.btn-primary.page-container__footer-button') |
||||
iAgree.simulate('click') |
||||
|
||||
setImmediate(() => { |
||||
assert(props.setParticipateInMetaMetrics.calledOnce) |
||||
assert.equal(props.setParticipateInMetaMetrics.getCall(0).args[0], true) |
||||
assert(props.hideModal.calledOnce) |
||||
done() |
||||
}) |
||||
}) |
||||
|
||||
}) |
@ -0,0 +1,48 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mount } from 'enzyme' |
||||
import RejectTransactionsModal from '../index' |
||||
|
||||
describe('Reject Transactions Model', () => { |
||||
let wrapper |
||||
|
||||
const props = { |
||||
onSubmit: sinon.spy(), |
||||
hideModal: sinon.spy(), |
||||
unapprovedTxCount: 2, |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
wrapper = mount( |
||||
<RejectTransactionsModal.WrappedComponent {...props} />, { |
||||
context: { |
||||
t: str => str, |
||||
}, |
||||
} |
||||
) |
||||
}) |
||||
|
||||
afterEach(() => { |
||||
props.hideModal.resetHistory() |
||||
}) |
||||
|
||||
it('hides modal when cancel button is clicked', () => { |
||||
const cancelButton = wrapper.find('.btn-default.modal-container__footer-button') |
||||
cancelButton.simulate('click') |
||||
|
||||
assert(props.hideModal.calledOnce) |
||||
}) |
||||
|
||||
it('onSubmit is called and hides modal when reject all clicked', (done) => { |
||||
const rejectAllButton = wrapper.find('.btn-secondary.modal-container__footer-button') |
||||
rejectAllButton.simulate('click') |
||||
|
||||
setImmediate(() => { |
||||
assert(props.onSubmit.calledOnce) |
||||
assert(props.hideModal.calledOnce) |
||||
done() |
||||
}) |
||||
|
||||
}) |
||||
}) |
@ -0,0 +1,82 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { shallow } from 'enzyme' |
||||
import AccountDetailsModal from '../account-details-modal' |
||||
|
||||
describe('Account Details Modal', () => { |
||||
let wrapper |
||||
|
||||
global.platform = { openWindow: sinon.spy() } |
||||
|
||||
const props = { |
||||
hideModal: sinon.spy(), |
||||
setAccountLabel: sinon.spy(), |
||||
showExportPrivateKeyModal: sinon.spy(), |
||||
showQrView: sinon.spy(), |
||||
network: 'test', |
||||
rpcPrefs: {}, |
||||
selectedIdentity: { |
||||
address: '0xAddress', |
||||
name: 'Account 1', |
||||
}, |
||||
keyrings: [ |
||||
{ |
||||
type: 'HD Key Tree', |
||||
accounts: [ |
||||
'0xAddress', |
||||
], |
||||
}, |
||||
], |
||||
identities: { |
||||
'0xAddress': { |
||||
address: '0xAddress', |
||||
name: 'Account 1', |
||||
}, |
||||
}, |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
wrapper = shallow( |
||||
<AccountDetailsModal.WrappedComponent {...props} />, { |
||||
context: { |
||||
t: str => str, |
||||
}, |
||||
} |
||||
) |
||||
}) |
||||
|
||||
it('sets account label when changing default account label', () => { |
||||
const accountLabel = wrapper.find('.account-modal__name').first() |
||||
accountLabel.simulate('submit', 'New Label') |
||||
|
||||
assert(props.setAccountLabel.calledOnce) |
||||
assert.equal(props.setAccountLabel.getCall(0).args[1], 'New Label') |
||||
}) |
||||
|
||||
it('opens new window when view block explorer is clicked', () => { |
||||
const modalButton = wrapper.find('.account-modal__button') |
||||
const etherscanLink = modalButton.first() |
||||
|
||||
etherscanLink.simulate('click') |
||||
assert(global.platform.openWindow.calledOnce) |
||||
}) |
||||
|
||||
it('shows export private key modal when clicked', () => { |
||||
const modalButton = wrapper.find('.account-modal__button') |
||||
const etherscanLink = modalButton.last() |
||||
|
||||
etherscanLink.simulate('click') |
||||
assert(props.showExportPrivateKeyModal.calledOnce) |
||||
}) |
||||
|
||||
it('sets blockexplorerview text when block explorer url in rpcPrefs exists', () => { |
||||
const blockExplorerUrl = 'https://block.explorer' |
||||
wrapper.setProps({ rpcPrefs: { blockExplorerUrl } }) |
||||
|
||||
const modalButton = wrapper.find('.account-modal__button') |
||||
const blockExplorerLink = modalButton.first() |
||||
|
||||
assert.equal(blockExplorerLink.html(), '<button class="button btn-secondary account-modal__button">blockExplorerView</button>') |
||||
}) |
||||
}) |
@ -0,0 +1,32 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mount } from 'enzyme' |
||||
import TransactionConfirmed from '../index' |
||||
|
||||
describe('Transaction Confirmed', () => { |
||||
let wrapper |
||||
|
||||
const props = { |
||||
onSubmit: sinon.spy(), |
||||
hideModal: sinon.spy(), |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
wrapper = mount( |
||||
<TransactionConfirmed.WrappedComponent {...props} />, { |
||||
context: { |
||||
t: str => str, |
||||
}, |
||||
} |
||||
) |
||||
}) |
||||
|
||||
it('clicks ok to submit and hide modal', () => { |
||||
const submit = wrapper.find('.btn-secondary.modal-container__footer-button') |
||||
submit.simulate('click') |
||||
|
||||
assert(props.onSubmit.calledOnce) |
||||
assert(props.hideModal.calledOnce) |
||||
}) |
||||
}) |
@ -0,0 +1,69 @@ |
||||
import React from 'react' |
||||
import { Provider } from 'react-redux' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import configureMockStore from 'redux-mock-store' |
||||
import { mountWithRouter } from '../../../../../test/lib/render-helpers' |
||||
import SignatureRequest from '../signature-request' |
||||
|
||||
describe('Signature Request', () => { |
||||
let wrapper |
||||
|
||||
const mockStore = { |
||||
metamask: { |
||||
provider: { |
||||
type: 'test', |
||||
}, |
||||
}, |
||||
} |
||||
const store = configureMockStore()(mockStore) |
||||
|
||||
const props = { |
||||
selectedAccount: '0xd8f6a2ffb0fc5952d16c9768b71cfd35b6399aa5', |
||||
history: { |
||||
push: sinon.spy(), |
||||
}, |
||||
clearConfirmTransaction: sinon.spy(), |
||||
cancelMessage: sinon.spy(), |
||||
cancel: sinon.stub().resolves(), |
||||
sign: sinon.stub().resolves(), |
||||
txData: { |
||||
msgParams: { |
||||
id: 1, |
||||
data: '{"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"Person":[{"name":"name","type":"string"},{"name":"wallet","type":"address"}],"Mail":[{"name":"from","type":"Person"},{"name":"to","type":"Person"},{"name":"contents","type":"string"}]},"primaryType":"Mail","domain":{"name":"Ether Mail","version":"1","chainId":"4","verifyingContract":"0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"},"message":{"from":{"name":"Cow","wallet":"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"},"to":{"name":"Bob","wallet":"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"},"contents":"Hello, Bob!"}}', |
||||
from: '0xd8f6a2ffb0fc5952d16c9768b71cfd35b6399aa5', |
||||
origin: 'test.domain', |
||||
}, |
||||
status: 'unapproved', |
||||
time: 1, |
||||
type: 'eth_sign', |
||||
}, |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
wrapper = mountWithRouter( |
||||
<Provider store={store}> |
||||
<SignatureRequest.WrappedComponent {...props} /> |
||||
</Provider>, store |
||||
) |
||||
}) |
||||
|
||||
afterEach(() => { |
||||
props.clearConfirmTransaction.resetHistory() |
||||
}) |
||||
|
||||
it('cancel', () => { |
||||
const cancelButton = wrapper.find('button.btn-default') |
||||
cancelButton.simulate('click') |
||||
|
||||
assert(props.cancel.calledOnce) |
||||
}) |
||||
|
||||
it('sign', () => { |
||||
const signButton = wrapper.find('button.btn-primary') |
||||
signButton.simulate('click') |
||||
|
||||
assert(props.sign.calledOnce) |
||||
}) |
||||
|
||||
}) |
@ -0,0 +1,69 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import thunk from 'redux-thunk' |
||||
import { Provider } from 'react-redux' |
||||
import configureMockStore from 'redux-mock-store' |
||||
import { mount } from 'enzyme' |
||||
|
||||
import TokenCell from '../token-cell' |
||||
import Identicon from '../../ui/identicon' |
||||
|
||||
describe('Token Cell', () => { |
||||
let wrapper |
||||
|
||||
const state = { |
||||
metamask: { |
||||
network: 'test', |
||||
currentCurrency: 'usd', |
||||
selectedTokenAddress: '0xToken', |
||||
selectedAddress: '0xAddress', |
||||
contractExchangeRates: { |
||||
'0xAnotherToken': 0.015, |
||||
}, |
||||
conversionRate: 7.00, |
||||
}, |
||||
appState: { |
||||
sidebar: { |
||||
isOpen: true, |
||||
}, |
||||
}, |
||||
} |
||||
|
||||
const middlewares = [thunk] |
||||
const mockStore = configureMockStore(middlewares) |
||||
const store = mockStore(state) |
||||
|
||||
beforeEach(() => { |
||||
wrapper = mount( |
||||
<Provider store={store}> |
||||
<TokenCell |
||||
address="0xAnotherToken" |
||||
symbol="TEST" |
||||
string="5.000" |
||||
network={22} |
||||
currentCurrency="usd" |
||||
image="./test-image" |
||||
/> |
||||
</Provider> |
||||
) |
||||
}) |
||||
|
||||
it('renders Identicon with props from token cell', () => { |
||||
assert.equal(wrapper.find(Identicon).prop('address'), '0xAnotherToken') |
||||
assert.equal(wrapper.find(Identicon).prop('network'), 'test') |
||||
assert.equal(wrapper.find(Identicon).prop('image'), './test-image') |
||||
}) |
||||
|
||||
it('renders token balance', () => { |
||||
assert.equal(wrapper.find('.token-list-item__token-balance').text(), '5.000') |
||||
}) |
||||
|
||||
it('renders token symbol', () => { |
||||
assert.equal(wrapper.find('.token-list-item__token-symbol').text(), 'TEST') |
||||
}) |
||||
|
||||
it('renders converted fiat amount', () => { |
||||
assert.equal(wrapper.find('.token-list-item__fiat-amount').text(), '0.52 USD') |
||||
}) |
||||
|
||||
}) |
@ -0,0 +1,43 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { shallow } from 'enzyme' |
||||
import Alert from '../index' |
||||
|
||||
describe('Alert', () => { |
||||
let wrapper |
||||
|
||||
beforeEach(() => { |
||||
wrapper = shallow( |
||||
<Alert /> |
||||
) |
||||
}) |
||||
|
||||
it('renders nothing with no visible boolean in state', () => { |
||||
const alert = wrapper.find('.global-alert') |
||||
assert.equal(alert.length, 0) |
||||
}) |
||||
|
||||
it('renders when visible in state is true, and message', () => { |
||||
const errorMessage = 'Error Message' |
||||
|
||||
wrapper.setState({ visible: true, msg: errorMessage }) |
||||
|
||||
const alert = wrapper.find('.global-alert') |
||||
assert.equal(alert.length, 1) |
||||
|
||||
const errorText = wrapper.find('.msg') |
||||
assert.equal(errorText.text(), errorMessage) |
||||
}) |
||||
|
||||
it('calls component method when componentWillReceiveProps is called', () => { |
||||
const animateInSpy = sinon.stub(wrapper.instance(), 'animateIn') |
||||
const animateOutSpy = sinon.stub(wrapper.instance(), 'animateOut') |
||||
|
||||
wrapper.setProps({ visible: true }) |
||||
assert(animateInSpy.calledOnce) |
||||
|
||||
wrapper.setProps({ visible: false }) |
||||
assert(animateOutSpy.calledOnce) |
||||
}) |
||||
}) |
@ -0,0 +1,44 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import { shallow } from 'enzyme' |
||||
import withTokenTracker from '../with-token-tracker.component' |
||||
import TokenBalance from '../../../../components/ui/token-balance/token-balance.component' |
||||
// import sinon from 'sinon'
|
||||
import TokenTracker from 'eth-token-tracker' |
||||
|
||||
const { createTestProviderTools } = require('../../../../../../test/stub/provider') |
||||
|
||||
const provider = createTestProviderTools({ scaffold: {} }).provider |
||||
|
||||
describe('WithTokenTracker HOC', () => { |
||||
let wrapper |
||||
|
||||
beforeEach(() => { |
||||
const TokenTracker = withTokenTracker(TokenBalance) |
||||
wrapper = shallow( |
||||
<TokenTracker |
||||
userAddress="0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc" |
||||
token={ |
||||
{ |
||||
address: 'test', |
||||
} |
||||
} |
||||
/> |
||||
) |
||||
}) |
||||
|
||||
it('#setError', () => { |
||||
wrapper.instance().setError('test') |
||||
assert.equal(wrapper.props().error, 'test') |
||||
}) |
||||
|
||||
it('#updateBalance', () => { |
||||
wrapper.instance().tracker = new TokenTracker({ |
||||
provider, |
||||
}) |
||||
wrapper.instance().updateBalance([{ string: 'test string', symbol: 'test symbol' }]) |
||||
assert.equal(wrapper.props().string, 'test string') |
||||
assert.equal(wrapper.props().symbol, 'test symbol') |
||||
}) |
||||
|
||||
}) |
@ -0,0 +1,100 @@ |
||||
import React from 'react' |
||||
import { Provider } from 'react-redux' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import configureMockStore from 'redux-mock-store' |
||||
import { mountWithRouter } from '../../../../../test/lib/render-helpers' |
||||
import AddToken from '../index' |
||||
|
||||
describe('Add Token', () => { |
||||
let wrapper |
||||
|
||||
const state = { |
||||
metamask: { |
||||
tokens: [], |
||||
}, |
||||
} |
||||
|
||||
const mockStore = configureMockStore() |
||||
const store = mockStore(state) |
||||
|
||||
const props = { |
||||
history: { |
||||
push: sinon.stub().callsFake(() => {}), |
||||
}, |
||||
setPendingTokens: sinon.spy(), |
||||
clearPendingTokens: sinon.spy(), |
||||
tokens: [], |
||||
identities: {}, |
||||
} |
||||
|
||||
before(() => { |
||||
wrapper = mountWithRouter( |
||||
<Provider store={store}> |
||||
<AddToken.WrappedComponent {...props} /> |
||||
</Provider>, store |
||||
) |
||||
|
||||
wrapper.find({ name: 'customToken' }).simulate('click') |
||||
}) |
||||
|
||||
afterEach(() => { |
||||
props.history.push.reset() |
||||
}) |
||||
|
||||
describe('Add Token', () => { |
||||
|
||||
it('next button is disabled when no fields are populated', () => { |
||||
const nextButton = wrapper.find('.button.btn-secondary.page-container__footer-button') |
||||
|
||||
assert.equal(nextButton.props().disabled, true) |
||||
}) |
||||
|
||||
it('edits token address', () => { |
||||
const tokenAddress = '0x617b3f8050a0BD94b6b1da02B4384eE5B4DF13F4' |
||||
const event = { target: { value: tokenAddress } } |
||||
const customAddress = wrapper.find('input#custom-address') |
||||
|
||||
customAddress.simulate('change', event) |
||||
assert.equal(wrapper.find('AddToken').instance().state.customAddress, tokenAddress) |
||||
}) |
||||
|
||||
|
||||
it('edits token symbol', () => { |
||||
const tokenSymbol = 'META' |
||||
const event = { target: { value: tokenSymbol } } |
||||
const customAddress = wrapper.find('#custom-symbol') |
||||
customAddress.last().simulate('change', event) |
||||
|
||||
assert.equal(wrapper.find('AddToken').instance().state.customSymbol, tokenSymbol) |
||||
}) |
||||
|
||||
it('edits token decimal precision', () => { |
||||
const tokenPrecision = '2' |
||||
const event = { target: { value: tokenPrecision } } |
||||
const customAddress = wrapper.find('#custom-decimals') |
||||
customAddress.last().simulate('change', event) |
||||
|
||||
assert.equal(wrapper.find('AddToken').instance().state.customDecimals, tokenPrecision) |
||||
|
||||
}) |
||||
|
||||
it('next', () => { |
||||
const nextButton = wrapper.find('.button.btn-secondary.page-container__footer-button') |
||||
nextButton.simulate('click') |
||||
|
||||
assert(props.setPendingTokens.calledOnce) |
||||
assert(props.history.push.calledOnce) |
||||
assert.equal(props.history.push.getCall(0).args[0], '/confirm-add-token') |
||||
}) |
||||
|
||||
it('cancels', () => { |
||||
const cancelButton = wrapper.find('button.btn-default.page-container__footer-button') |
||||
cancelButton.simulate('click') |
||||
|
||||
assert(props.clearPendingTokens.calledOnce) |
||||
assert.equal(props.history.push.getCall(0).args[0], '/') |
||||
}) |
||||
}) |
||||
|
||||
}) |
@ -0,0 +1,46 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mountWithRouter } from '../../../../../test/lib/render-helpers' |
||||
import CreateAccountPage from '../index' |
||||
|
||||
describe('Create Account Page', () => { |
||||
let wrapper |
||||
|
||||
const props = { |
||||
history: { |
||||
push: sinon.spy(), |
||||
}, |
||||
location: { |
||||
pathname: '/new-account', |
||||
}, |
||||
} |
||||
|
||||
before(() => { |
||||
wrapper = mountWithRouter( |
||||
<CreateAccountPage {...props} /> |
||||
) |
||||
}) |
||||
|
||||
afterEach(() => { |
||||
props.history.push.resetHistory() |
||||
}) |
||||
|
||||
it('clicks create account and routes to new-account path', () => { |
||||
const createAccount = wrapper.find('.new-account__tabs__tab').at(0) |
||||
createAccount.simulate('click') |
||||
assert.equal(props.history.push.getCall(0).args[0], '/new-account') |
||||
}) |
||||
|
||||
it('clicks import account and routes to import new account path', () => { |
||||
const importAccount = wrapper.find('.new-account__tabs__tab').at(1) |
||||
importAccount.simulate('click') |
||||
assert.equal(props.history.push.getCall(0).args[0], '/new-account/import') |
||||
}) |
||||
|
||||
it('clicks connect HD Wallet and routes to connect new account path', () => { |
||||
const connectHdWallet = wrapper.find('.new-account__tabs__tab').at(2) |
||||
connectHdWallet.simulate('click') |
||||
assert.equal(props.history.push.getCall(0).args[0], '/new-account/connect') |
||||
}) |
||||
}) |
@ -0,0 +1,39 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mountWithRouter } from '../../../../../../test/lib/render-helpers' |
||||
import { DEFAULT_ROUTE } from '../../../../helpers/constants/routes' |
||||
import EndOfFlowScreen from '../index' |
||||
|
||||
describe('End of Flow Screen', () => { |
||||
let wrapper |
||||
|
||||
const props = { |
||||
history: { |
||||
push: sinon.spy(), |
||||
}, |
||||
completeOnboarding: sinon.spy(), |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
wrapper = mountWithRouter( |
||||
<EndOfFlowScreen.WrappedComponent {...props} /> |
||||
) |
||||
}) |
||||
|
||||
it('renders', () => { |
||||
assert.equal(wrapper.length, 1) |
||||
}) |
||||
|
||||
it('', (done) => { |
||||
const endOfFlowButton = wrapper.find('.btn-primary.first-time-flow__button') |
||||
endOfFlowButton.simulate('click') |
||||
|
||||
setImmediate(() => { |
||||
assert(props.completeOnboarding.calledOnce) |
||||
assert(props.history.push.calledOnce) |
||||
assert.equal(props.history.push.getCall(0).args[0], DEFAULT_ROUTE) |
||||
done() |
||||
}) |
||||
}) |
||||
}) |
@ -0,0 +1,73 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import { mountWithRouter } from '../../../../../../test/lib/render-helpers' |
||||
import { |
||||
DEFAULT_ROUTE, |
||||
LOCK_ROUTE, |
||||
INITIALIZE_WELCOME_ROUTE, |
||||
INITIALIZE_UNLOCK_ROUTE, |
||||
} from '../../../../helpers/constants/routes' |
||||
import FirstTimeFlowSwitch from '../index' |
||||
|
||||
describe('FirstTimeFlowSwitch', () => { |
||||
|
||||
it('redirects to /welcome route with no props', () => { |
||||
const wrapper = mountWithRouter( |
||||
<FirstTimeFlowSwitch.WrappedComponent /> |
||||
) |
||||
assert.equal(wrapper.find('Lifecycle').find({ to: { pathname: INITIALIZE_WELCOME_ROUTE } }).length, 1) |
||||
}) |
||||
|
||||
it('redirects to / route when completedOnboarding is true', () => { |
||||
const props = { |
||||
completedOnboarding: true, |
||||
} |
||||
const wrapper = mountWithRouter( |
||||
<FirstTimeFlowSwitch.WrappedComponent {...props} /> |
||||
) |
||||
|
||||
assert.equal(wrapper.find('Lifecycle').find({ to: { pathname: DEFAULT_ROUTE } }).length, 1) |
||||
}) |
||||
|
||||
it('redirects to /lock route when isUnlocked is true ', () => { |
||||
const props = { |
||||
completedOnboarding: false, |
||||
isUnlocked: true, |
||||
} |
||||
|
||||
const wrapper = mountWithRouter( |
||||
<FirstTimeFlowSwitch.WrappedComponent {...props} /> |
||||
) |
||||
|
||||
assert.equal(wrapper.find('Lifecycle').find({ to: { pathname: LOCK_ROUTE } }).length, 1) |
||||
}) |
||||
|
||||
it('redirects to /welcome route when isInitialized is false', () => { |
||||
const props = { |
||||
completedOnboarding: false, |
||||
isUnlocked: false, |
||||
isInitialized: false, |
||||
} |
||||
|
||||
const wrapper = mountWithRouter( |
||||
<FirstTimeFlowSwitch.WrappedComponent {...props} /> |
||||
) |
||||
|
||||
assert.equal(wrapper.find('Lifecycle').find({ to: { pathname: INITIALIZE_WELCOME_ROUTE } }).length, 1) |
||||
}) |
||||
|
||||
it('redirects to /unlock route when isInitialized is true', () => { |
||||
const props = { |
||||
completedOnboarding: false, |
||||
isUnlocked: false, |
||||
isInitialized: true, |
||||
} |
||||
|
||||
const wrapper = mountWithRouter( |
||||
<FirstTimeFlowSwitch.WrappedComponent {...props} /> |
||||
) |
||||
|
||||
assert.equal(wrapper.find('Lifecycle').find({ to: { pathname: INITIALIZE_UNLOCK_ROUTE } }).length, 1) |
||||
}) |
||||
|
||||
}) |
@ -0,0 +1,43 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import configureMockStore from 'redux-mock-store' |
||||
import { mountWithRouter } from '../../../../../../test/lib/render-helpers' |
||||
import MetaMetricsOptIn from '../index' |
||||
|
||||
describe('MetaMetricsOptIn', () => { |
||||
let wrapper |
||||
|
||||
const props = { |
||||
history: { |
||||
push: sinon.spy(), |
||||
}, |
||||
setParticipateInMetaMetrics: sinon.stub().resolves(), |
||||
participateInMetaMetrics: false, |
||||
} |
||||
|
||||
const mockStore = { |
||||
metamask: {}, |
||||
} |
||||
|
||||
const store = configureMockStore()(mockStore) |
||||
|
||||
beforeEach(() => { |
||||
wrapper = mountWithRouter( |
||||
<MetaMetricsOptIn.WrappedComponent {...props} />, store |
||||
) |
||||
}) |
||||
|
||||
afterEach(() => { |
||||
props.setParticipateInMetaMetrics.resetHistory() |
||||
}) |
||||
|
||||
it('opt out of metametrics', () => { |
||||
const noThanksButton = wrapper.find('.btn-default.page-container__footer-button') |
||||
noThanksButton.simulate('click') |
||||
|
||||
assert(props.setParticipateInMetaMetrics.calledOnce) |
||||
assert.equal(props.setParticipateInMetaMetrics.getCall(0).args[0], false) |
||||
}) |
||||
|
||||
}) |
@ -0,0 +1,48 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mount } from 'enzyme' |
||||
import RevealSeedPhrase from '../index' |
||||
|
||||
describe('Reveal Seed Phrase', () => { |
||||
let wrapper |
||||
|
||||
const TEST_SEED = 'debris dizzy just program just float decrease vacant alarm reduce speak stadium' |
||||
|
||||
const props = { |
||||
history: { |
||||
push: sinon.spy(), |
||||
}, |
||||
seedPhrase: TEST_SEED, |
||||
setSeedPhraseBackedUp: sinon.spy(), |
||||
setCompletedOnboarding: sinon.spy(), |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
wrapper = mount( |
||||
<RevealSeedPhrase.WrappedComponent {...props} />, { |
||||
context: { |
||||
t: str => str, |
||||
metricsEvent: () => {}, |
||||
}, |
||||
} |
||||
) |
||||
}) |
||||
|
||||
it('seed phrase', () => { |
||||
const seedPhrase = wrapper.find('.reveal-seed-phrase__secret-words--hidden') |
||||
assert.equal(seedPhrase.length, 1) |
||||
assert.equal(seedPhrase.text(), TEST_SEED) |
||||
}) |
||||
|
||||
it('clicks to reveal', () => { |
||||
const reveal = wrapper.find('.reveal-seed-phrase__secret-blocker') |
||||
|
||||
assert.equal(wrapper.state().isShowingSeedPhrase, false) |
||||
reveal.simulate('click') |
||||
assert.equal(wrapper.state().isShowingSeedPhrase, true) |
||||
|
||||
const showSeed = wrapper.find('.reveal-seed-phrase__secret-words') |
||||
assert.equal(showSeed.length, 1) |
||||
}) |
||||
}) |
@ -0,0 +1,46 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mountWithRouter } from '../../../../../../test/lib/render-helpers' |
||||
import SelectAction from '../index' |
||||
|
||||
describe('Selection Action', () => { |
||||
let wrapper |
||||
|
||||
const props = { |
||||
isInitialized: false, |
||||
setFirstTimeFlowType: sinon.spy(), |
||||
history: { |
||||
push: sinon.spy(), |
||||
}, |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
wrapper = mountWithRouter( |
||||
<SelectAction.WrappedComponent {...props} /> |
||||
) |
||||
}) |
||||
|
||||
afterEach(() => { |
||||
props.setFirstTimeFlowType.resetHistory() |
||||
props.history.push.resetHistory() |
||||
}) |
||||
|
||||
it('clicks import wallet to route to import FTF', () => { |
||||
const importWalletButton = wrapper.find('.btn-primary.first-time-flow__button').at(0) |
||||
importWalletButton.simulate('click') |
||||
|
||||
assert(props.setFirstTimeFlowType.calledOnce) |
||||
assert.equal(props.setFirstTimeFlowType.getCall(0).args[0], 'import') |
||||
assert(props.history.push.calledOnce) |
||||
}) |
||||
|
||||
it('clicks create wallet to route to create FTF ', () => { |
||||
const createWalletButton = wrapper.find('.btn-primary.first-time-flow__button').at(1) |
||||
createWalletButton.simulate('click') |
||||
|
||||
assert(props.setFirstTimeFlowType.calledOnce) |
||||
assert.equal(props.setFirstTimeFlowType.getCall(0).args[0], 'create') |
||||
assert(props.history.push.calledOnce) |
||||
}) |
||||
}) |
@ -0,0 +1,55 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import configureMockStore from 'redux-mock-store' |
||||
import { mountWithRouter } from '../../../../../../test/lib/render-helpers' |
||||
import Welcome from '../index' |
||||
|
||||
describe('Welcome', () => { |
||||
const mockStore = { |
||||
metamask: {}, |
||||
} |
||||
|
||||
const store = configureMockStore()(mockStore) |
||||
|
||||
after(() => { |
||||
sinon.restore() |
||||
}) |
||||
|
||||
it('routes to select action when participateInMetaMetrics is not initialized', () => { |
||||
|
||||
const props = { |
||||
history: { |
||||
push: sinon.spy(), |
||||
}, |
||||
} |
||||
|
||||
const wrapper = mountWithRouter( |
||||
<Welcome.WrappedComponent {...props} />, store |
||||
) |
||||
|
||||
const getStartedButton = wrapper.find('.btn-primary.first-time-flow__button') |
||||
getStartedButton.simulate('click') |
||||
assert.equal(props.history.push.getCall(0).args[0], '/initialize/select-action') |
||||
|
||||
}) |
||||
|
||||
it('routes to correct password when participateInMetaMetrics is initialized', () => { |
||||
|
||||
const props = { |
||||
welcomeScreenSeen: true, |
||||
participateInMetaMetrics: false, |
||||
history: { |
||||
push: sinon.spy(), |
||||
}, |
||||
} |
||||
|
||||
const wrapper = mountWithRouter( |
||||
<Welcome.WrappedComponent {...props} />, store |
||||
) |
||||
|
||||
const getStartedButton = wrapper.find('.btn-primary.first-time-flow__button') |
||||
getStartedButton.simulate('click') |
||||
assert.equal(props.history.push.getCall(0).args[0], '/initialize/create-password') |
||||
}) |
||||
}) |
@ -0,0 +1,31 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mount } from 'enzyme' |
||||
import RevealSeedPage from '../reveal-seed' |
||||
|
||||
describe('Reveal Seed Page', () => { |
||||
let wrapper |
||||
|
||||
const props = { |
||||
history: { |
||||
push: sinon.spy(), |
||||
}, |
||||
requestRevealSeedWords: sinon.stub().resolves(), |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
wrapper = mount( |
||||
<RevealSeedPage.WrappedComponent {...props} />, { |
||||
context: { |
||||
t: str => str, |
||||
}, |
||||
} |
||||
) |
||||
}) |
||||
|
||||
it('form submit', () => { |
||||
wrapper.find('form').simulate('submit') |
||||
assert(props.requestRevealSeedWords.calledOnce) |
||||
}) |
||||
}) |
@ -0,0 +1,48 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mountWithRouter } from '../../../../../test/lib/render-helpers' |
||||
import Lock from '../index' |
||||
|
||||
describe('Lock', () => { |
||||
|
||||
it('replaces history with default route when isUnlocked false', () => { |
||||
|
||||
const props = { |
||||
isUnlocked: false, |
||||
history: { |
||||
replace: sinon.spy(), |
||||
}, |
||||
} |
||||
|
||||
mountWithRouter( |
||||
<Lock.WrappedComponent {...props} /> |
||||
) |
||||
|
||||
assert.equal(props.history.replace.getCall(0).args[0], '/') |
||||
|
||||
}) |
||||
|
||||
it('locks and pushes history with default route when isUnlocked true', (done) => { |
||||
|
||||
const props = { |
||||
isUnlocked: true, |
||||
lockMetamask: sinon.stub(), |
||||
history: { |
||||
push: sinon.spy(), |
||||
}, |
||||
} |
||||
|
||||
props.lockMetamask.resolves() |
||||
|
||||
mountWithRouter( |
||||
<Lock.WrappedComponent {...props} /> |
||||
) |
||||
|
||||
assert(props.lockMetamask.calledOnce) |
||||
setImmediate(() => { |
||||
assert.equal(props.history.push.getCall(0).args[0], '/') |
||||
done() |
||||
}) |
||||
}) |
||||
}) |
@ -0,0 +1,55 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mount } from 'enzyme' |
||||
import SecurityTab from '../index' |
||||
|
||||
describe('Security Tab', () => { |
||||
let wrapper |
||||
|
||||
const props = { |
||||
revealSeedConfirmation: sinon.spy(), |
||||
showClearApprovalModal: sinon.spy(), |
||||
setParticipateInMetaMetrics: sinon.spy(), |
||||
displayWarning: sinon.spy(), |
||||
setShowIncomingTransactionsFeatureFlag: sinon.spy(), |
||||
history: { |
||||
push: sinon.spy(), |
||||
}, |
||||
privacyMode: true, |
||||
warning: '', |
||||
participateInMetaMetrics: false, |
||||
} |
||||
|
||||
beforeEach(() => { |
||||
wrapper = mount( |
||||
<SecurityTab.WrappedComponent {...props} />, { |
||||
context: { |
||||
t: str => str, |
||||
metricsEvent: () => {}, |
||||
}, |
||||
} |
||||
) |
||||
}) |
||||
|
||||
it('navigates to reveal seed words page', () => { |
||||
const seedWords = wrapper.find('.button.btn-danger.btn--large') |
||||
|
||||
seedWords.simulate('click') |
||||
assert(props.history.push.calledOnce) |
||||
assert.equal(props.history.push.getCall(0).args[0], '/seed') |
||||
}) |
||||
|
||||
it('toggles incoming txs', () => { |
||||
const incomingTxs = wrapper.find({ type: 'checkbox' }).at(0) |
||||
incomingTxs.simulate('click') |
||||
assert(props.setShowIncomingTransactionsFeatureFlag.calledOnce) |
||||
}) |
||||
|
||||
it('toggles metaMetrics', () => { |
||||
const metaMetrics = wrapper.find({ type: 'checkbox' }).at(1) |
||||
|
||||
metaMetrics.simulate('click') |
||||
assert(props.setParticipateInMetaMetrics.calledOnce) |
||||
}) |
||||
}) |
@ -0,0 +1,61 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mount } from 'enzyme' |
||||
import SettingsTab from '../index' |
||||
|
||||
describe('Settings Tab', () => { |
||||
let wrapper |
||||
|
||||
const props = { |
||||
setCurrentCurrency: sinon.spy(), |
||||
displayWarning: sinon.spy(), |
||||
setUseBlockie: sinon.spy(), |
||||
updateCurrentLocale: sinon.spy(), |
||||
setUseNativeCurrencyAsPrimaryCurrencyPreference: sinon.spy(), |
||||
warning: '', |
||||
currentLocale: 'en', |
||||
useBlockie: false, |
||||
currentCurrency: 'usd', |
||||
conversionDate: 1, |
||||
nativeCurrency: 'eth', |
||||
useNativeCurrencyAsPrimaryCurrency: true, |
||||
} |
||||
beforeEach(() => { |
||||
wrapper = mount( |
||||
<SettingsTab.WrappedComponent {...props} />, { |
||||
context: { |
||||
t: str => str, |
||||
}, |
||||
} |
||||
) |
||||
}) |
||||
|
||||
it('selects currency', async () => { |
||||
const selectCurrency = wrapper.find({ placeholder: 'selectCurrency' }) |
||||
|
||||
selectCurrency.props().onSelect('eur') |
||||
assert(props.setCurrentCurrency.calledOnce) |
||||
}) |
||||
|
||||
it('selects locale', async () => { |
||||
const selectLocale = wrapper.find({ placeholder: 'selectLocale' }) |
||||
|
||||
await selectLocale.props().onSelect('ja') |
||||
assert(props.updateCurrentLocale.calledOnce) |
||||
}) |
||||
|
||||
it('sets fiat primary currency', () => { |
||||
const selectFiat = wrapper.find('#fiat-primary-currency') |
||||
|
||||
selectFiat.simulate('change') |
||||
assert(props.setUseNativeCurrencyAsPrimaryCurrencyPreference.calledOnce) |
||||
}) |
||||
|
||||
it('toggles blockies', () => { |
||||
const toggleBlockies = wrapper.find({ type: 'checkbox' }) |
||||
|
||||
toggleBlockies.simulate('click') |
||||
assert(props.setUseBlockie.calledOnce) |
||||
}) |
||||
}) |
@ -0,0 +1,69 @@ |
||||
import React from 'react' |
||||
import assert from 'assert' |
||||
import sinon from 'sinon' |
||||
import { mount } from 'enzyme' |
||||
import UnlockPage from '../index' |
||||
|
||||
describe('Unlock Page', () => { |
||||
let wrapper |
||||
|
||||
const props = { |
||||
history: { |
||||
push: sinon.spy(), |
||||
}, |
||||
isUnlocked: false, |
||||
onImport: sinon.spy(), |
||||
onRestore: sinon.spy(), |
||||
onSubmit: sinon.spy(), |
||||
forceUpdateMetamaskState: sinon.spy(), |
||||
showOptInModal: sinon.spy(), |
||||
} |
||||
|
||||
|
||||
beforeEach(() => { |
||||
|
||||
wrapper = mount( |
||||
<UnlockPage.WrappedComponent{...props} />, { |
||||
context: { |
||||
t: str => str, |
||||
}, |
||||
} |
||||
) |
||||
|
||||
}) |
||||
|
||||
after(() => { |
||||
sinon.restore() |
||||
}) |
||||
|
||||
it('renders', () => { |
||||
assert.equal(wrapper.length, 1) |
||||
}) |
||||
|
||||
it('changes password and submits', () => { |
||||
const passwordField = wrapper.find({ type: 'password', id: 'password' }) |
||||
const loginButton = wrapper.find({ type: 'submit' }).last() |
||||
|
||||
const event = { target: { value: 'password' } } |
||||
assert.equal(wrapper.instance().state.password, '') |
||||
passwordField.last().simulate('change', event) |
||||
assert.equal(wrapper.instance().state.password, 'password') |
||||
|
||||
loginButton.simulate('click') |
||||
assert(props.onSubmit.calledOnce) |
||||
}) |
||||
|
||||
it('clicks imports seed button', () => { |
||||
const importSeedButton = wrapper.find('.unlock-page__link--import') |
||||
|
||||
importSeedButton.simulate('click') |
||||
assert(props.onImport.calledOnce) |
||||
|
||||
}) |
||||
|
||||
it('clicks restore', () => { |
||||
const restoreFromSeedButton = wrapper.find('.unlock-page__link').at(0) |
||||
restoreFromSeedButton.simulate('click') |
||||
assert(props.onRestore.calledOnce) |
||||
}) |
||||
}) |
@ -0,0 +1,159 @@ |
||||
import assert from 'assert' |
||||
import { |
||||
unconfirmedTransactionsCountSelector, |
||||
tokenAmountAndToAddressSelector, |
||||
approveTokenAmountAndToAddressSelector, |
||||
sendTokenTokenAmountAndToAddressSelector, |
||||
contractExchangeRateSelector, |
||||
} from '../confirm-transaction' |
||||
|
||||
describe('Confirm Transaction Selector', () => { |
||||
|
||||
describe('unconfirmedTransactionsCountSelector', () => { |
||||
|
||||
const state = { |
||||
metamask: { |
||||
unapprovedTxs: { |
||||
1: { |
||||
metamaskNetworkId: 'test', |
||||
}, |
||||
2: { |
||||
metmaskNetworkId: 'other network', |
||||
}, |
||||
}, |
||||
unapprovedMsgCount: 1, |
||||
unapprovedPersonalMsgCount: 1, |
||||
unapprovedTypedMessagesCount: 1, |
||||
network: 'test', |
||||
}, |
||||
} |
||||
|
||||
it('returns number of txs in unapprovedTxs state with the same network plus unapproved signing method counts', () => { |
||||
assert.equal(unconfirmedTransactionsCountSelector(state), 4) |
||||
}) |
||||
|
||||
}) |
||||
|
||||
describe('tokenAmountAndToAddressSelector', () => { |
||||
|
||||
const state = { |
||||
confirmTransaction: { |
||||
tokenData: { |
||||
name: 'transfer', |
||||
params: [ |
||||
{ |
||||
name: '_to', |
||||
value: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', |
||||
type: 'address', |
||||
}, |
||||
{ |
||||
name: '_value', |
||||
value: '1', |
||||
type: 'uint256', |
||||
}, |
||||
], |
||||
}, |
||||
tokenProps: { |
||||
tokenDecimals: '2', |
||||
tokenSymbol: 'META', |
||||
}, |
||||
}, |
||||
} |
||||
|
||||
it('returns calulcated token amount based on token value and token decimals and recipient address', () => { |
||||
assert.deepEqual(tokenAmountAndToAddressSelector(state), |
||||
{ toAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', tokenAmount: 0.01 }) |
||||
}) |
||||
|
||||
}) |
||||
|
||||
describe('approveTokenAmountAndToAddressSelector', () => { |
||||
|
||||
const state = { |
||||
confirmTransaction: { |
||||
tokenData: { |
||||
name: 'approve', |
||||
params: [ |
||||
{ |
||||
name: '_spender', |
||||
value: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', |
||||
type: 'address', |
||||
}, |
||||
{ |
||||
name: '_value', |
||||
value: '1', |
||||
type: 'uint256', |
||||
}, |
||||
], |
||||
}, |
||||
tokenProps: { |
||||
tokenDecimals: '2', |
||||
tokenSymbol: 'META', |
||||
}, |
||||
}, |
||||
} |
||||
|
||||
it('returns token amount and recipient for approve token allocation spending', () => { |
||||
assert.deepEqual(approveTokenAmountAndToAddressSelector(state), |
||||
{ toAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', tokenAmount: 0.01 }) |
||||
}) |
||||
|
||||
}) |
||||
|
||||
describe('sendTokenTokenAmountAndToAddressSelector', () => { |
||||
|
||||
const state = { |
||||
confirmTransaction: { |
||||
tokenData: { |
||||
name: 'transfer', |
||||
params: [ |
||||
{ |
||||
name: '_to', |
||||
value: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', |
||||
type: 'address', |
||||
}, |
||||
{ |
||||
name: '_value', |
||||
value: '1', |
||||
type: 'uint256', |
||||
}, |
||||
], |
||||
}, |
||||
tokenProps: { |
||||
tokenDecimals: '2', |
||||
tokenSymbol: 'META', |
||||
}, |
||||
}, |
||||
} |
||||
|
||||
it('returns token address and calculated token amount', () => { |
||||
assert.deepEqual(sendTokenTokenAmountAndToAddressSelector(state), |
||||
{ toAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', tokenAmount: 0.01 }) |
||||
}) |
||||
|
||||
}) |
||||
|
||||
describe('contractExchangeRateSelector', () => { |
||||
|
||||
const state = { |
||||
metamask: { |
||||
contractExchangeRates: { |
||||
'0xTokenAddress': '10', |
||||
}, |
||||
}, |
||||
confirmTransaction: { |
||||
txData: { |
||||
txParams: { |
||||
to: '0xTokenAddress', |
||||
}, |
||||
}, |
||||
}, |
||||
} |
||||
|
||||
it('returns contract exchange rate in metamask state based on confirm transaction txParams token recipient', () => { |
||||
assert.equal(contractExchangeRateSelector(state), 10) |
||||
}) |
||||
|
||||
}) |
||||
}) |
||||
|
@ -0,0 +1,28 @@ |
||||
import assert from 'assert' |
||||
import { selectedTokenSelector } from '../tokens' |
||||
|
||||
const metaToken = { |
||||
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4', |
||||
'symbol': 'META', |
||||
'decimals': 18, |
||||
} |
||||
|
||||
const state = { |
||||
metamask: { |
||||
selectedTokenAddress: '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4', |
||||
tokens: [ |
||||
{ |
||||
'address': '0x06012c8cf97bead5deae237070f9587f8e7a266d', |
||||
'symbol': 'CK', |
||||
'decimals': 0, |
||||
}, |
||||
metaToken, |
||||
], |
||||
}, |
||||
} |
||||
describe('Selected Token Selector', () => { |
||||
it('selects token info from tokens based on selectedTokenAddress in state', () => { |
||||
const tokenInfo = selectedTokenSelector(state) |
||||
assert.equal(tokenInfo, metaToken) |
||||
}) |
||||
}) |
@ -0,0 +1,356 @@ |
||||
import assert from 'assert' |
||||
import { |
||||
unapprovedMessagesSelector, |
||||
transactionsSelector, |
||||
nonceSortedTransactionsSelector, |
||||
nonceSortedPendingTransactionsSelector, |
||||
nonceSortedCompletedTransactionsSelector, |
||||
submittedPendingTransactionsSelector, |
||||
} from '../transactions' |
||||
|
||||
describe('Transaction Selectors', () => { |
||||
|
||||
describe('unapprovedMessagesSelector', () => { |
||||
it('returns eth sign msg from unapprovedMsgs', () => { |
||||
|
||||
const msg = { |
||||
id: 1, |
||||
msgParams: { |
||||
from: '0xAddress', |
||||
data: '0xData', |
||||
origin: 'origin', |
||||
}, |
||||
time: 1, |
||||
status: 'unapproved', |
||||
type: 'eth_sign', |
||||
} |
||||
|
||||
const state = { |
||||
metamask: { |
||||
unapprovedMsgs: { |
||||
1: msg, |
||||
}, |
||||
}, |
||||
} |
||||
|
||||
const msgSelector = unapprovedMessagesSelector(state) |
||||
|
||||
assert(Array.isArray(msgSelector)) |
||||
assert.deepEqual(msgSelector, [msg]) |
||||
}) |
||||
|
||||
it('returns personal sign from unapprovedPersonalMsgsSelector', () => { |
||||
|
||||
const msg = { |
||||
id: 1, |
||||
msgParams: { |
||||
from: '0xAddress', |
||||
data: '0xData', |
||||
origin: 'origin', |
||||
}, |
||||
time: 1, |
||||
status: 'unapproved', |
||||
type: 'personal_sign', |
||||
} |
||||
|
||||
const state = { |
||||
metamask: { |
||||
unapprovedPersonalMsgs: { |
||||
1: msg, |
||||
}, |
||||
}, |
||||
} |
||||
|
||||
const msgSelector = unapprovedMessagesSelector(state) |
||||
|
||||
assert(Array.isArray(msgSelector)) |
||||
assert.deepEqual(msgSelector, [msg]) |
||||
}) |
||||
|
||||
it('returns typed message from unapprovedTypedMessagesSelector', () => { |
||||
|
||||
const msg = { |
||||
id: 1, |
||||
msgParams: { |
||||
data: '0xData', |
||||
from: '0xAddress', |
||||
version: 'V3', |
||||
origin: 'origin', |
||||
}, |
||||
time: 1, |
||||
status: 'unapproved', |
||||
type: 'eth_signTypedData', |
||||
} |
||||
|
||||
const state = { |
||||
metamask: { |
||||
unapprovedTypedMessages: { |
||||
1: msg, |
||||
}, |
||||
}, |
||||
} |
||||
|
||||
const msgSelector = unapprovedMessagesSelector(state) |
||||
|
||||
assert(Array.isArray(msgSelector)) |
||||
assert.deepEqual(msgSelector, [msg]) |
||||
|
||||
}) |
||||
}) |
||||
|
||||
describe('transactionsSelector', () => { |
||||
|
||||
it('selectedAddressTxList', () => { |
||||
|
||||
const state = { |
||||
metamask: { |
||||
featureFlags: { |
||||
showIncomingTransactions: false, |
||||
}, |
||||
selectedAddressTxList: [ |
||||
{ |
||||
id: 0, |
||||
time: 0, |
||||
txParams: { |
||||
from: '0xAddress', |
||||
to: '0xRecipient', |
||||
}, |
||||
}, |
||||
{ |
||||
id: 1, |
||||
time: 1, |
||||
txParams: { |
||||
from: '0xAddress', |
||||
to: '0xRecipient', |
||||
}, |
||||
}, |
||||
], |
||||
}, |
||||
} |
||||
|
||||
const orderedTxlist = state.metamask.selectedAddressTxList.sort((a, b) => b.time - a.time) |
||||
|
||||
const txSelector = transactionsSelector(state) |
||||
|
||||
assert(Array.isArray(txSelector)) |
||||
assert.deepEqual(txSelector, orderedTxlist) |
||||
}) |
||||
|
||||
it('returns token tx from selectedAddressTxList when selectedTokenAddress is valid', () => { |
||||
|
||||
const state = { |
||||
metamask: { |
||||
featureFlags: { |
||||
showIncomingTransactions: false, |
||||
}, |
||||
selectedTokenAddress: '0xToken', |
||||
selectedAddressTxList: [ |
||||
{ |
||||
id: 0, |
||||
time: 0, |
||||
txParams: { |
||||
from: '0xAddress', |
||||
to: '0xToken', |
||||
}, |
||||
}, |
||||
{ |
||||
id: 1, |
||||
time: 1, |
||||
txParams: { |
||||
from: '0xAddress', |
||||
to: '0xToken', |
||||
}, |
||||
}, |
||||
], |
||||
}, |
||||
|
||||
} |
||||
|
||||
const orderedTxlist = state.metamask.selectedAddressTxList.sort((a, b) => b.time - a.time) |
||||
|
||||
const txSelector = transactionsSelector(state) |
||||
|
||||
assert(Array.isArray(txSelector)) |
||||
assert.deepEqual(txSelector, orderedTxlist) |
||||
|
||||
}) |
||||
|
||||
}) |
||||
|
||||
describe('nonceSortedTransactionsSelector', () => { |
||||
|
||||
it('returns transaction group nonce sorted tx from from selectedTxList wit', () => { |
||||
|
||||
const tx1 = { |
||||
id: 0, |
||||
time: 0, |
||||
txParams: { |
||||
from: '0xAddress', |
||||
to: '0xRecipient', |
||||
nonce: '0x0', |
||||
}, |
||||
} |
||||
|
||||
const tx2 = { |
||||
id: 1, |
||||
time: 1, |
||||
txParams: { |
||||
from: '0xAddress', |
||||
to: '0xRecipient', |
||||
nonce: '0x1', |
||||
}, |
||||
} |
||||
|
||||
const state = { |
||||
metamask: { |
||||
featureFlags: { |
||||
showIncomingTransactions: false, |
||||
}, |
||||
selectedAddressTxList: [ |
||||
tx1, |
||||
tx2, |
||||
], |
||||
}, |
||||
} |
||||
|
||||
const expectedResult = [ |
||||
{ |
||||
nonce: '0x0', |
||||
transactions: [ tx1 ], |
||||
initialTransaction: tx1, |
||||
primaryTransaction: tx1, |
||||
hasRetried: false, |
||||
hasCancelled: false, |
||||
}, |
||||
{ |
||||
nonce: '0x1', |
||||
transactions: [ tx2 ], |
||||
initialTransaction: tx2, |
||||
primaryTransaction: tx2, |
||||
hasRetried: false, |
||||
hasCancelled: false, |
||||
}, |
||||
] |
||||
|
||||
assert.deepEqual(nonceSortedTransactionsSelector(state), expectedResult) |
||||
}) |
||||
}) |
||||
|
||||
describe('Sorting Transactions Selectors', () => { |
||||
|
||||
const submittedTx = { |
||||
id: 0, |
||||
time: 0, |
||||
txParams: { |
||||
from: '0xAddress', |
||||
to: '0xRecipient', |
||||
nonce: '0x0', |
||||
}, |
||||
status: 'submitted', |
||||
} |
||||
|
||||
const unapprovedTx = { |
||||
id: 1, |
||||
time: 1, |
||||
txParams: { |
||||
from: '0xAddress', |
||||
to: '0xRecipient', |
||||
nonce: '0x1', |
||||
}, |
||||
status: 'unapproved', |
||||
} |
||||
|
||||
const approvedTx = { |
||||
id: 2, |
||||
time: 2, |
||||
txParams: { |
||||
from: '0xAddress', |
||||
to: '0xRecipient', |
||||
nonce: '0x2', |
||||
}, |
||||
status: 'approved', |
||||
} |
||||
|
||||
const confirmedTx = { |
||||
id: 3, |
||||
time: 3, |
||||
txParams: { |
||||
from: '0xAddress', |
||||
to: '0xRecipient', |
||||
nonce: '0x3', |
||||
}, |
||||
status: 'confirmed', |
||||
} |
||||
|
||||
const state = { |
||||
metamask: { |
||||
featureFlags: { |
||||
showIncomingTransactions: false, |
||||
}, |
||||
selectedAddressTxList: [ |
||||
submittedTx, |
||||
unapprovedTx, |
||||
approvedTx, |
||||
confirmedTx, |
||||
], |
||||
}, |
||||
} |
||||
|
||||
it('nonceSortedPendingTransactionsSelector', () => { |
||||
|
||||
const expectedResult = [ |
||||
{ |
||||
nonce: submittedTx.txParams.nonce, |
||||
transactions: [ submittedTx ], |
||||
initialTransaction: submittedTx, |
||||
primaryTransaction: submittedTx, |
||||
hasRetried: false, |
||||
hasCancelled: false, |
||||
}, |
||||
{ |
||||
nonce: unapprovedTx.txParams.nonce, |
||||
transactions: [ unapprovedTx ], |
||||
initialTransaction: unapprovedTx, |
||||
primaryTransaction: unapprovedTx, |
||||
hasRetried: false, |
||||
hasCancelled: false, |
||||
}, |
||||
{ |
||||
nonce: approvedTx.txParams.nonce, |
||||
transactions: [ approvedTx ], |
||||
initialTransaction: approvedTx, |
||||
primaryTransaction: approvedTx, |
||||
hasRetried: false, |
||||
hasCancelled: false, |
||||
}, |
||||
] |
||||
|
||||
assert.deepEqual(nonceSortedPendingTransactionsSelector(state), expectedResult) |
||||
}) |
||||
|
||||
it('nonceSortedCompletedTransactionsSelector', () => { |
||||
|
||||
const expectedResult = [ |
||||
{ |
||||
nonce: confirmedTx.txParams.nonce, |
||||
transactions: [ confirmedTx ], |
||||
initialTransaction: confirmedTx, |
||||
primaryTransaction: confirmedTx, |
||||
hasRetried: false, |
||||
hasCancelled: false, |
||||
}, |
||||
] |
||||
|
||||
assert.deepEqual(nonceSortedCompletedTransactionsSelector(state), expectedResult) |
||||
}) |
||||
|
||||
it('submittedPendingTransactionsSelector', () => { |
||||
|
||||
const expectedResult = [ submittedTx ] |
||||
assert.deepEqual(submittedPendingTransactionsSelector(state), expectedResult) |
||||
|
||||
}) |
||||
|
||||
}) |
||||
|
||||
}) |
Loading…
Reference in new issue