Skip to content

Commit

Permalink
Merge pull request #1599 from LiskHQ/1428-add-hwWallet-unit-tests
Browse files Browse the repository at this point in the history
Add hw wallet unit tests - Closes #1428
  • Loading branch information
michaeltomasik committed Jan 24, 2019
2 parents ca0885f + 1a230a8 commit 27fd41c
Show file tree
Hide file tree
Showing 12 changed files with 490 additions and 144 deletions.
2 changes: 0 additions & 2 deletions jest.config.js
Expand Up @@ -11,7 +11,6 @@ module.exports = {
'src/components/dashboard/currencyGraph.test.js', // This should be unskipped in issue #1499
'src/components/errorBoundary/index.test.js',
'src/components/feedbackForm/*.test.js',
'src/components/hwWallet/*.test.js',
'src/components/login/*.test.js',
'src/components/newsFeed/index.test.js', // This component doesn't meet the setted tresholds for mocha but in jest
'src/components/passphraseCreation/index.test.js',
Expand Down Expand Up @@ -49,7 +48,6 @@ module.exports = {
'src/components/errorBoundary/index.js',
'src/components/feedbackForm/',
'src/components/formattedNumber/stories.js',
'src/components/hwWallet/',
'src/components/newsFeed/index.js', // This component doesn't meet the setted tresholds for mocha but in jest
'src/components/newsFeed/news.js',
'src/components/passphrase/create/create.js',
Expand Down
10 changes: 7 additions & 3 deletions src/components/hwWallet/accountCard.js
Expand Up @@ -17,7 +17,7 @@ const AccountCard = ({
onClick={() => {
onClickHandler(account, index);
}}>
<div className={styles.accountVisualWrapper}>
<div className={`${styles.accountVisualWrapper} accountVisualWrapper`}>
<AccountVisual
address={account.address}
size={100} sizeS={60}
Expand All @@ -27,14 +27,18 @@ const AccountCard = ({
{fromRawLsk(account.balance)}<p>LSK</p>
</div>
{isEditMode ?
<div className={styles.edit} onClick={(e) => {
<div
className={styles.edit}
onClick={/* istanbul ignore next */(e) => {
e.stopPropagation();
}}>
<ToolBoxInput
placeholder={'Title'}
onChange={value => changeInput(value, account.address)}
theme={styles}
onKeyDown={ (event) => { if (event.keyCode === keyCodes.enter) saveAccountNames(); }}
onKeyDown={/* istanbul ignore next */(event) => {
if (event.keyCode === keyCodes.enter) saveAccountNames();
}}
value={hardwareAccountName}></ToolBoxInput>
</div> :
null}
Expand Down
59 changes: 59 additions & 0 deletions src/components/hwWallet/accountCard.test.js
@@ -0,0 +1,59 @@
import React from 'react';
import { expect } from 'chai';
import { mount } from 'enzyme';
import { spy } from 'sinon';
import PropTypes from 'prop-types';

import i18n from '../../i18n';
import ToolBoxInput from '../toolbox/inputs/toolBoxInput';
import AccountCard from './accountCard';

describe('AccountCard', () => {
let wrapper;
let props;

beforeEach(() => {
props = {
account: {
address: '123L',
},
hardwareAccountName: 'test',
isEditMode: true,
changeInput: spy(),
onClickHandler: spy(),
index: 0,
};

wrapper = mount(<AccountCard {...props} />, {
context: { i18n },
childContextTypes: {
i18n: PropTypes.object.isRequired,
},
});
});

it('should find ToolBoxInput when isEditMode true', () => {
expect(wrapper.find(ToolBoxInput).exists()).to.equal(true);
});

it('should call changeInput when changing text in ToolBoxInput', () => {
wrapper.find(ToolBoxInput).props().onChange('test');
expect(props.changeInput).to.have.been.calledWith('test', '123L');
});

it('should call onClickHandler on click accountVisualWrapper', () => {
const newProps = {
...props,
isEditMode: false,
};

wrapper = mount(<AccountCard {...newProps} />, {
context: { i18n },
childContextTypes: {
i18n: PropTypes.object.isRequired,
},
});
wrapper.find('.accountVisualWrapper').simulate('click');
expect(props.onClickHandler).to.have.been.calledWith({ address: '123L' }, 0);
});
});
2 changes: 1 addition & 1 deletion src/components/hwWallet/addAccountCard.js
Expand Up @@ -4,7 +4,7 @@ import { FontIcon } from '../fontIcon';
import styles from './accountCard.css';

const AddAccountCard = ({ addAccount, t }) => (
<div className={`${styles.card} ${styles.addAccountCard}`} onClick={() => { addAccount(); }}>
<div className={`${styles.card} ${styles.addAccountCard} addAccountCard`} onClick={() => { addAccount(); }}>
<div><FontIcon className={styles.addIcon} value='add' /></div>
<div className={styles.addLabel}>{t('Add new')}</div>
</div>);
Expand Down
30 changes: 30 additions & 0 deletions src/components/hwWallet/addAccountCard.test.js
@@ -0,0 +1,30 @@
import React from 'react';
import { expect } from 'chai';
import { mount } from 'enzyme';
import { spy } from 'sinon';
import PropTypes from 'prop-types';

import i18n from '../../i18n';
import AddAccountCard from './addAccountCard';

describe('AddAccountCard', () => {
let wrapper;
let props;

it('should call addAccount on click addAccountCard', () => {
props = {
t: spy(),
addAccount: spy(),
};

wrapper = mount(<AddAccountCard {...props} />, {
context: { i18n },
childContextTypes: {
i18n: PropTypes.object.isRequired,
},
});

wrapper.find(AddAccountCard).simulate('click');
expect(props.addAccount).to.have.been.calledWith();
});
});
87 changes: 87 additions & 0 deletions src/components/hwWallet/hwWallet.js
@@ -0,0 +1,87 @@
import React from 'react';
import to from 'await-to-js';
import Box from '../box';

import UnlockWallet from './unlockWallet';
import LedgerLogin from './ledgerLoginHOC';
import getNetwork from '../../utils/getNetwork';
import { getAccountFromLedgerIndex } from '../../utils/ledger';
import Piwik from '../../utils/piwik';

import { loginType } from '../../constants/hwConstants';
import routes from '../../constants/routes';

import styles from './unlockWallet.css';

class HwWallet extends React.Component {
constructor(props) {
super(props);
this.state = {
isLedgerLogin: true,
};
}

async componentDidMount() {
this.ledgerLogin();
}

handleOnClick() {
Piwik.trackingEvent('HwWallet', 'button', 'Continue');
this.ledgerLogin();
}

cancelLedgerLogin() {
Piwik.trackingEvent('HwWallet', 'button', 'Cancel Ledger');
this.props.history.push(`${routes.loginV2.path}`);
}

async ledgerLogin() { // eslint-disable-line max-statements
this.props.loadingStarted('ledgerLogin');

const finishTimeout = setTimeout(() => {
this.setState({ isLedgerLogin: false });
this.props.loadingFinished('ledgerLogin');
}, 6000);
let error;
let ledgerAccount;
// eslint-disable-next-line prefer-const
[error, ledgerAccount] = await to(getAccountFromLedgerIndex()); // by default index 0
if (!error) {
const network = Object.assign({}, getNetwork(this.props.network));
/* istanbul ignore else */
if (ledgerAccount.publicKey) {
clearTimeout(finishTimeout);
this.props.loadingFinished('ledgerLogin');
this.setState({ isLedgerLogin: true, isLedgerFirstLogin: true });
}

// set active peer
this.props.liskAPIClientSet({
publicKey: ledgerAccount.publicKey,
loginType: loginType.ledger,
network,
});
}
}

render() {
if (this.state.isLedgerLogin) {
return (
<Box>
<LedgerLogin
loginType={loginType.normal}
network={getNetwork(this.props.network)}
cancelLedgerLogin={this.cancelLedgerLogin.bind(this)} />
</Box>);
}

return (
<Box className={styles.unlockWallet}>
<UnlockWallet
handleOnClick={this.handleOnClick.bind(this)}
cancelLedgerLogin={this.cancelLedgerLogin.bind(this)} />
</Box>);
}
}

export default HwWallet;
105 changes: 2 additions & 103 deletions src/components/hwWallet/index.js
@@ -1,112 +1,11 @@
import React from 'react';
import { connect } from 'react-redux';
import to from 'await-to-js';
import { withRouter } from 'react-router';

import Box from '../box';
import UnlockWallet from './unlockWallet';
import LedgerLogin from './ledgerLogin';
import networks from '../../constants/networks';
import getNetwork from '../../utils/getNetwork';
import { getAccountFromLedgerIndex } from '../../utils/ledger';
import { loadingStarted, loadingFinished } from '../../actions/loading';
import { liskAPIClientSet } from '../../actions/peers';
import Piwik from '../../utils/piwik';
import { loginType } from '../../constants/hwConstants';
import routes from '../../constants/routes';

import styles from './unlockWallet.css';

class HwWallet extends React.Component {
constructor(props) {
super(props);
this.state = {
isLedgerLogin: true,
};
}

async componentDidMount() {
this.ledgerLogin();
}

handleOnClick() {
Piwik.trackingEvent('HwWallet', 'button', 'Continue');
this.ledgerLogin();
}

cancelLedgerLogin() {
Piwik.trackingEvent('HwWallet', 'button', 'Cancel Ledger');
this.props.history.push(`${routes.loginV2.path}`);
}

async ledgerLogin() { // eslint-disable-line max-statements
this.props.loadingStarted('ledgerLogin');

const finishTimeout = setTimeout(() => {
this.setState({ isLedgerLogin: false });
this.props.loadingFinished('ledgerLogin');
}, 6000);
let error;
let ledgerAccount;
// eslint-disable-next-line prefer-const
[error, ledgerAccount] = await to(getAccountFromLedgerIndex()); // by default index 0

if (error) {
// const text = error && error.message ?
// `${error.message}.` : i18next.t('Error during login with Ledger.');
// this.props.errorToastDisplayed({ label: error.message });
} else {
const network = this.getNetwork();

if (ledgerAccount.publicKey) {
clearTimeout(finishTimeout);
this.props.loadingFinished('ledgerLogin');
this.setState({ isLedgerLogin: true, isLedgerFirstLogin: true });
}

// set active peer
this.props.liskAPIClientSet({
publicKey: ledgerAccount.publicKey,
loginType: loginType.ledger,
network,
// hwInfo: { // Use pubKey[0] first 10 char as device id
// deviceId: ledgerAccount.publicKey.substring(0, 10),
// derivationIndex: 0,
// },
});
}
}

getNetwork() {
const network = {
...getNetwork(this.props.network),
};
if (this.props.network === networks.customNode.code &&
this.props.peers.options && this.props.peers.options.address) {
network.address = this.props.peers.options.address;
}
return network;
}

render() {
if (this.state.isLedgerLogin) {
return (
<Box>
<LedgerLogin
loginType={loginType.normal}
network={this.getNetwork()}
cancelLedgerLogin={this.cancelLedgerLogin.bind(this)} />
</Box>);
}
import networks from '../../constants/networks';

return (
<Box className={styles.unlockWallet}>
<UnlockWallet
handleOnClick={this.handleOnClick.bind(this)}
cancelLedgerLogin={this.cancelLedgerLogin.bind(this)} />
</Box>);
}
}
import HwWallet from './hwWallet';

const mapStateToProps = state => ({
network: state.settings.network || networks.mainnet.code,
Expand Down

0 comments on commit 27fd41c

Please sign in to comment.