mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 17:33:23 +01:00
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 test
This commit is contained in:
parent
608a1fc298
commit
5d1c9313db
@ -56,6 +56,9 @@ require('jsdom-global')()
|
||||
// localStorage
|
||||
window.localStorage = {}
|
||||
|
||||
// override metamask-logo
|
||||
window.requestAnimationFrame = () => {}
|
||||
|
||||
// crypto.getRandomValues
|
||||
if (!window.crypto) {
|
||||
window.crypto = {}
|
||||
|
@ -1,14 +1,7 @@
|
||||
import { shallow, mount } from 'enzyme'
|
||||
import React from 'react'
|
||||
import { BrowserRouter } from 'react-router-dom'
|
||||
import { shape } from 'prop-types'
|
||||
|
||||
export function shallowWithStore (component, store) {
|
||||
const context = {
|
||||
store,
|
||||
}
|
||||
return shallow(component, { context })
|
||||
}
|
||||
import { mount } from 'enzyme'
|
||||
import { MemoryRouter } from 'react-router-dom'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
export function mountWithStore (component, store) {
|
||||
const context = {
|
||||
@ -17,26 +10,40 @@ export function mountWithStore (component, store) {
|
||||
return mount(component, { context })
|
||||
}
|
||||
|
||||
export function mountWithRouter (node) {
|
||||
export function mountWithRouter (component, store = {}, pathname = '/') {
|
||||
|
||||
// Instantiate router context
|
||||
const router = {
|
||||
history: new BrowserRouter().history,
|
||||
history: new MemoryRouter().history,
|
||||
route: {
|
||||
location: {},
|
||||
location: {
|
||||
pathname: pathname,
|
||||
},
|
||||
match: {},
|
||||
},
|
||||
}
|
||||
|
||||
const createContext = () => ({
|
||||
context: { router, t: () => {} },
|
||||
childContextTypes: { router: shape({}), t: () => {} },
|
||||
context: {
|
||||
router,
|
||||
t: str => str,
|
||||
tOrKey: str => str,
|
||||
metricsEvent: () => {},
|
||||
store,
|
||||
},
|
||||
childContextTypes: {
|
||||
router: PropTypes.object,
|
||||
t: PropTypes.func,
|
||||
tOrKey: PropTypes.func,
|
||||
metricsEvent: PropTypes.func,
|
||||
store: PropTypes.object,
|
||||
},
|
||||
})
|
||||
|
||||
const Wrapper = () => (
|
||||
<BrowserRouter>
|
||||
{node}
|
||||
</BrowserRouter>
|
||||
<MemoryRouter initialEntries={[{ pathname }]} initialIndex={0}>
|
||||
{component}
|
||||
</MemoryRouter>
|
||||
)
|
||||
|
||||
return mount(<Wrapper />, createContext())
|
||||
|
@ -193,6 +193,12 @@ export default class AccountMenu extends Component {
|
||||
|
||||
renderRemoveAccount (keyring, identity) {
|
||||
const { t } = this.context
|
||||
|
||||
// Sometimes keyrings aren't loaded yet
|
||||
if (!keyring) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Any account that's not from the HD wallet Keyring can be removed
|
||||
const { type } = keyring
|
||||
const isRemovable = type !== 'HD Key Tree'
|
||||
|
209
ui/app/components/app/account-menu/tests/account-menu.test.js
Normal file
209
ui/app/components/app/account-menu/tests/account-menu.test.js
Normal file
@ -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')
|
||||
})
|
||||
})
|
||||
})
|
99
ui/app/components/app/app-header/tests/app-header.test.js
Normal file
99
ui/app/components/app/app-header/tests/app-header.test.js
Normal file
@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
})
|
@ -40,7 +40,7 @@ class AccountDetailsDropdown extends Component {
|
||||
|
||||
static propTypes = {
|
||||
selectedIdentity: PropTypes.object.isRequired,
|
||||
network: PropTypes.number.isRequired,
|
||||
network: PropTypes.string.isRequired,
|
||||
keyrings: PropTypes.array.isRequired,
|
||||
showAccountDetailModal: PropTypes.func.isRequired,
|
||||
viewOnEtherscan: PropTypes.func.isRequired,
|
||||
|
@ -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')
|
||||
})
|
||||
})
|
37
ui/app/components/app/info-box/tests/info-box.test.js
Normal file
37
ui/app/components/app/info-box/tests/info-box.test.js
Normal file
@ -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)
|
||||
})
|
||||
})
|
94
ui/app/components/app/menu-bar/tests/menu-bar.test.js
Normal file
94
ui/app/components/app/menu-bar/tests/menu-bar.test.js
Normal file
@ -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)
|
||||
})
|
||||
})
|
69
ui/app/components/app/tests/signature-request.test.js
Normal file
69
ui/app/components/app/tests/signature-request.test.js
Normal file
@ -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)
|
||||
})
|
||||
|
||||
})
|
69
ui/app/components/app/tests/token-cell.spec.js
Normal file
69
ui/app/components/app/tests/token-cell.spec.js
Normal file
@ -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')
|
||||
})
|
||||
|
||||
})
|
43
ui/app/components/ui/alert/tests/alert.test.js
Normal file
43
ui/app/components/ui/alert/tests/alert.test.js
Normal file
@ -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')
|
||||
})
|
||||
|
||||
})
|
100
ui/app/pages/add-token/tests/add-token.test.js
Normal file
100
ui/app/pages/add-token/tests/add-token.test.js
Normal file
@ -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], '/')
|
||||
})
|
||||
})
|
||||
|
||||
})
|
46
ui/app/pages/create-account/tests/create-account.test.js
Normal file
46
ui/app/pages/create-account/tests/create-account.test.js
Normal file
@ -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)
|
||||
})
|
||||
})
|
55
ui/app/pages/first-time-flow/welcome/tests/welcome.test.js
Normal file
55
ui/app/pages/first-time-flow/welcome/tests/welcome.test.js
Normal file
@ -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')
|
||||
})
|
||||
})
|
31
ui/app/pages/keychains/tests/reveal-seed.test.js
Normal file
31
ui/app/pages/keychains/tests/reveal-seed.test.js
Normal file
@ -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)
|
||||
})
|
||||
})
|
48
ui/app/pages/lock/tests/lock.test.js
Normal file
48
ui/app/pages/lock/tests/lock.test.js
Normal file
@ -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)
|
||||
})
|
||||
})
|
69
ui/app/pages/unlock-page/tests/unlock-page.test.js
Normal file
69
ui/app/pages/unlock-page/tests/unlock-page.test.js
Normal file
@ -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)
|
||||
})
|
||||
})
|
@ -94,13 +94,15 @@ export default class UnlockPage extends Component {
|
||||
this.setState({ password: target.value, error: null })
|
||||
|
||||
// tell mascot to look at page action
|
||||
const element = target
|
||||
const boundingRect = element.getBoundingClientRect()
|
||||
const coordinates = getCaretCoordinates(element, element.selectionEnd)
|
||||
this.animationEventEmitter.emit('point', {
|
||||
x: boundingRect.left + coordinates.left - element.scrollLeft,
|
||||
y: boundingRect.top + coordinates.top - element.scrollTop,
|
||||
})
|
||||
if (target.getBoundingClientRect) {
|
||||
const element = target
|
||||
const boundingRect = element.getBoundingClientRect()
|
||||
const coordinates = getCaretCoordinates(element, element.selectionEnd)
|
||||
this.animationEventEmitter.emit('point', {
|
||||
x: boundingRect.left + coordinates.left - element.scrollLeft,
|
||||
y: boundingRect.top + coordinates.top - element.scrollTop,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
renderSubmitButton () {
|
||||
|
159
ui/app/selectors/tests/confirm-transaction.test.js
Normal file
159
ui/app/selectors/tests/confirm-transaction.test.js
Normal file
@ -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)
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
|
28
ui/app/selectors/tests/tokens.test.js
Normal file
28
ui/app/selectors/tests/tokens.test.js
Normal file
@ -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)
|
||||
})
|
||||
})
|
356
ui/app/selectors/tests/transactions.test.js
Normal file
356
ui/app/selectors/tests/transactions.test.js
Normal file
@ -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
Block a user