diff --git a/packages/desktop/electron/main.js b/packages/desktop/electron/main.js index e811fb133..3fcf9fa9d 100644 --- a/packages/desktop/electron/main.js +++ b/packages/desktop/electron/main.js @@ -106,7 +106,10 @@ app.on('ready', () => { log.info('... start services'); services.start(); + + // Run IPC listeners ipc({ settings }); + log.info('... services started'); log.info('... subscribe for prices'); diff --git a/packages/desktop/electron/prices.js b/packages/desktop/electron/prices.js index cec272aa7..5d9769f2f 100644 --- a/packages/desktop/electron/prices.js +++ b/packages/desktop/electron/prices.js @@ -1,3 +1,4 @@ +const { settings } = require('@emeraldwallet/store'); const log = require('./logger'); class Prices { @@ -29,7 +30,7 @@ class Prices { log.info(`Request for prices, to ${this.to}`); const self = this; this.listener.request(this.froms, this.to, (result) => { - self.webContents.send('prices/rate', result); + self.webContents.send('store', settings.actions.setRatesAction(result)); }); setTimeout(this.fetch.bind(this), 60000); } diff --git a/packages/desktop/src/components/welcome/welcome.js b/packages/desktop/src/components/welcome/welcome.js index eff5472a7..744149ede 100644 --- a/packages/desktop/src/components/welcome/welcome.js +++ b/packages/desktop/src/components/welcome/welcome.js @@ -5,6 +5,7 @@ import {Logo} from '@emeraldwallet/ui'; import Grid from '@material-ui/core/Grid'; import CircularProgress from '@material-ui/core/CircularProgress'; import {withStyles} from '@material-ui/styles'; +import { launcher } from '@emeraldwallet/store'; import InitialSetup from './initialSetup'; import { TERMS_VERSION } from '../../store/config'; @@ -76,9 +77,9 @@ const StyledWelcome = withStyles(getStyles)(Welcome); export default connect( (state, ownProps) => { + const msg = launcher.selectors.getMessage(state); return ({ - message: state.launcher.getIn(['message', 'text']), - level: state.launcher.getIn(['message', 'level']), + ...msg, needSetup: state.launcher.get('configured') && (state.launcher.get('terms') !== TERMS_VERSION), }); }, diff --git a/packages/desktop/src/store/launcher/launcherActions.js b/packages/desktop/src/store/launcher/launcherActions.js index bbf4540df..66d5089b2 100644 --- a/packages/desktop/src/store/launcher/launcherActions.js +++ b/packages/desktop/src/store/launcher/launcherActions.js @@ -33,55 +33,25 @@ export function agreeOnTerms(v) { }; } -export function saveSettings(extraSettings) { - extraSettings = extraSettings || {}; - return (dispatch, getState) => { - const geth = getState().launcher.get('geth').toJS(); - const chain = getState().launcher.get('chain').toJS(); - - const settings = { geth, chain, ...extraSettings }; - - log.info('Save settings', settings); - - ipcRenderer.send('settings', settings); - - dispatch({ - type: 'LAUNCHER/SETTINGS', - updated: false, - }); - }; -} - -// TODO: depricated -export function listenElectron() { - return (dispatch, getState) => { - log.debug('Running launcher listener'); - - ipcRenderer.on('launcher', (event, type, message) => { - log.debug('launcher listener: ', 'type', type, 'message', message); - - dispatch({ - type: `LAUNCHER/${type}`, - ...message, - }); - - if (type === 'CHAIN') { - if (getState().launcher.getIn(['chain', 'id']) !== message.chainId) { - // Launcher sent chain different from what user has chosen - // Alert ! - dispatch(screen.actions.showError( - new Error(`Launcher connected to invalid chain: [${message.chain}, ${message.chainId}]`) - )); - } else { - dispatch({ - type: 'NETWORK/SWITCH_CHAIN', - ...message, - }); - } - } - }); - }; -} +// TODO: Depricated +// export function saveSettings(extraSettings) { +// extraSettings = extraSettings || {}; +// return (dispatch, getState) => { +// const geth = getState().launcher.get('geth').toJS(); +// const chain = getState().launcher.get('chain').toJS(); +// +// const settings = { geth, chain, ...extraSettings }; +// +// log.info('Save settings', settings); +// +// ipcRenderer.send('settings', settings); +// +// dispatch({ +// type: 'LAUNCHER/SETTINGS', +// updated: false, +// }); +// }; +// } export function connecting(value) { return { diff --git a/packages/desktop/src/store/store.js b/packages/desktop/src/store/store.js index 66366c579..547ff08f8 100644 --- a/packages/desktop/src/store/store.js +++ b/packages/desktop/src/store/store.js @@ -17,7 +17,6 @@ import tokens from './vault/tokens'; import { readConfig, - listenElectron, connecting } from './launcher/launcherActions'; // import { showError } from './wallet/screen/screenActions'; @@ -42,7 +41,7 @@ global.api = api; function refreshAll() { const promises = [ // store.dispatch(accounts.actions.loadPendingTransactions()), // TODO: Fix it - store.dispatch(addresses.actions.loadAccountsList()), + // store.dispatch(addresses.actions.loadAccountsList()), ]; // Main loop that will refresh UI as needed @@ -53,8 +52,6 @@ function refreshAll() { export function startSync() { log.info('Start synchronization'); - store.dispatch(settings.actions.listenPrices()); - const promises = []; promises.push( @@ -127,6 +124,9 @@ function newWalletVersionCheck() { }); } +/** + * Listen to IPC channel 'store' and dispatch action to redux store + */ export function electronToStore() { return (dispatch) => { log.debug('Running launcher listener for Redux'); @@ -144,7 +144,6 @@ export const start = () => { } catch (e) { log.error(e); } - store.dispatch(listenElectron()); store.dispatch(electronToStore()); getInitialScreen(); newWalletVersionCheck(); diff --git a/packages/react-app/src/ledger/ImportAccount/Container.tsx b/packages/react-app/src/ledger/ImportAccount/Container.tsx index 9f6fe9a4a..78d831a39 100644 --- a/packages/react-app/src/ledger/ImportAccount/Container.tsx +++ b/packages/react-app/src/ledger/ImportAccount/Container.tsx @@ -56,7 +56,7 @@ export default connect( const acc = { id: address, blockchain }; return dispatch(addresses.actions.loadAccountsList(() => { // go to account details only when accounts updated - dispatch(screen.actions.gotoScreen('account', acc)); + dispatch(screen.actions.gotoScreen(screen.Pages.ACCOUNT, acc)); }) as any); }); }, diff --git a/packages/react-app/src/transaction/CreateTx/TokenField/TokenField.spec.tsx b/packages/react-app/src/transaction/CreateTx/TokenField/TokenField.spec.tsx index d10d30e4d..d9d55455a 100644 --- a/packages/react-app/src/transaction/CreateTx/TokenField/TokenField.spec.tsx +++ b/packages/react-app/src/transaction/CreateTx/TokenField/TokenField.spec.tsx @@ -6,7 +6,7 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import { TokenField } from './TokenField'; -const reduceClasses = (prev: any, curr: any) => ({ ...prev, [curr]: curr }); +const reduceClasses = (prev: any, curr: any) => ({ ...prev, [curr]: curr }); const classes = Object.keys({ container: {} }).reduce(reduceClasses, {}); describe('TokenField', () => { diff --git a/packages/react-app/src/transactions/List/List.tsx b/packages/react-app/src/transactions/List/List.tsx index 74a438523..ff8fd16b2 100644 --- a/packages/react-app/src/transactions/List/List.tsx +++ b/packages/react-app/src/transactions/List/List.tsx @@ -1,13 +1,14 @@ import { - Table, TableBody, TableCell, TableHead, TableRow } from '@material-ui/core'; + createStyles, + Table, TableBody, TableCell, TableHead, TableRow +} from '@material-ui/core'; import { withStyles, withTheme } from '@material-ui/styles'; -import { Styles } from '@material-ui/styles/withStyles'; import cx from 'classnames'; import { List } from 'immutable'; import * as React from 'react'; import Transaction from './Transaction'; -const styles = { +const styles = createStyles({ columnName: { textTransform: 'uppercase', fontSize: '11px !important', @@ -33,7 +34,7 @@ const styles = { paddingRight: '0px !important', width: '24px' } -} as Styles; +}); interface IProps { transactions: List; diff --git a/packages/react-app/src/transactions/List/Transaction.tsx b/packages/react-app/src/transactions/List/Transaction.tsx index c4bf9b9d1..d67d0155d 100644 --- a/packages/react-app/src/transactions/List/Transaction.tsx +++ b/packages/react-app/src/transactions/List/Transaction.tsx @@ -1,10 +1,10 @@ import { blockchainById, blockchainByName } from '@emeraldwallet/core'; -import { addresses, blockchains, screen, settings, txhistory, wallet } from '@emeraldwallet/store'; -import TxView from '@emeraldwallet/ui/lib/components/tx/TxHistory/TxList/TxItem'; +import { addresses, blockchains, screen, settings, wallet } from '@emeraldwallet/store'; import * as React from 'react'; import { connect } from 'react-redux'; import Balance from '../../common/Balance'; import i18n from '../../i18n'; +import TxView from './TxItemView'; function txValueRenderer (showFiat: boolean) { return function renderer (balance: any, ticker: string) { diff --git a/packages/ui/src/components/tx/TxHistory/TxList/TxItem/Status.tsx b/packages/react-app/src/transactions/List/TxItemView/Status.tsx similarity index 95% rename from packages/ui/src/components/tx/TxHistory/TxList/TxItem/Status.tsx rename to packages/react-app/src/transactions/List/TxItemView/Status.tsx index 35e0a1bf2..47a4040ac 100644 --- a/packages/ui/src/components/tx/TxHistory/TxList/TxItem/Status.tsx +++ b/packages/react-app/src/transactions/List/TxItemView/Status.tsx @@ -21,7 +21,7 @@ const styles = (theme: any) => ({ } }); -interface Props { +interface IStatusProps { currentBlockHeight: number; txBlockNumber: number | null; txTimestamp: any; @@ -33,7 +33,7 @@ interface Props { onClick?: any; } -const Status = (props: Props) => { +export const Status = (props: IStatusProps) => { const { classes, onClick } = props; const tsFormatter = props.timeStampFormatter || defaultTimestampFormatter; const { currentBlockHeight, txBlockNumber, requiredConfirmations, txDiscarded } = props; @@ -92,5 +92,4 @@ function defaultTimestampFormatter (timestamp: any): string { return timestamp; } -const StyledStatus = withStyles(styles)(Status); -export default StyledStatus; +export default withStyles(styles)(Status); diff --git a/packages/react-app/src/transactions/List/TxItemView/TxItem.spec.tsx b/packages/react-app/src/transactions/List/TxItemView/TxItem.spec.tsx new file mode 100644 index 000000000..d6578efec --- /dev/null +++ b/packages/react-app/src/transactions/List/TxItemView/TxItem.spec.tsx @@ -0,0 +1,39 @@ +import { Theme } from '@emeraldplatform/ui'; +import { ThemeProvider } from '@material-ui/styles'; +import { render } from '@testing-library/react'; +import BigNumber from 'bignumber.js'; +import * as React from 'react'; +import TxItem from './TxItem'; + +const tx = { + blockNumber: 1, + from: '0x1', + to: '0x2', + value: new BigNumber(100000) +}; +const from = {}; +const to = {}; + +describe('TxItem', () => { + it('should renders without crash', () => { + const comp = render( + + {}} + openTx={() => {}} + netParams={ + { + currentBlockHeight: 100, + requiredConfirmations: 12 + } + } + tx={tx} + fromAccount={from} + toAccount={to} + /> + + ); + expect(comp).toBeDefined(); + }); + +}); diff --git a/packages/ui/src/components/tx/TxHistory/TxList/TxItem/TxItem.tsx b/packages/react-app/src/transactions/List/TxItemView/TxItem.tsx similarity index 100% rename from packages/ui/src/components/tx/TxHistory/TxList/TxItem/TxItem.tsx rename to packages/react-app/src/transactions/List/TxItemView/TxItem.tsx diff --git a/packages/ui/src/components/tx/TxHistory/TxList/TxItem/index.ts b/packages/react-app/src/transactions/List/TxItemView/index.ts similarity index 100% rename from packages/ui/src/components/tx/TxHistory/TxList/TxItem/index.ts rename to packages/react-app/src/transactions/List/TxItemView/index.ts diff --git a/packages/store/src/addresses/actions.ts b/packages/store/src/accounts/actions.ts similarity index 100% rename from packages/store/src/addresses/actions.ts rename to packages/store/src/accounts/actions.ts diff --git a/packages/store/src/addresses/index.ts b/packages/store/src/accounts/index.ts similarity index 100% rename from packages/store/src/addresses/index.ts rename to packages/store/src/accounts/index.ts diff --git a/packages/store/src/addresses/reducer.spec.ts b/packages/store/src/accounts/reducer.spec.ts similarity index 100% rename from packages/store/src/addresses/reducer.spec.ts rename to packages/store/src/accounts/reducer.spec.ts diff --git a/packages/store/src/addresses/reducer.ts b/packages/store/src/accounts/reducer.ts similarity index 100% rename from packages/store/src/addresses/reducer.ts rename to packages/store/src/accounts/reducer.ts diff --git a/packages/store/src/addresses/selectors.spec.ts b/packages/store/src/accounts/selectors.spec.ts similarity index 100% rename from packages/store/src/addresses/selectors.spec.ts rename to packages/store/src/accounts/selectors.spec.ts diff --git a/packages/store/src/addresses/selectors.ts b/packages/store/src/accounts/selectors.ts similarity index 100% rename from packages/store/src/addresses/selectors.ts rename to packages/store/src/accounts/selectors.ts diff --git a/packages/store/src/addresses/types.ts b/packages/store/src/accounts/types.ts similarity index 100% rename from packages/store/src/addresses/types.ts rename to packages/store/src/accounts/types.ts diff --git a/packages/store/src/index.ts b/packages/store/src/index.ts index 785572818..8fb71baa3 100644 --- a/packages/store/src/index.ts +++ b/packages/store/src/index.ts @@ -1,5 +1,5 @@ import * as addressBook from './address-book'; -import * as addresses from './addresses'; +import * as addresses from './accounts'; import * as blockchains from './blockchains'; import * as connection from './conn'; import * as launcher from './launcher'; diff --git a/packages/store/src/ledger/actions.ts b/packages/store/src/ledger/actions.ts index f7920b01a..763f7d5dc 100644 --- a/packages/store/src/ledger/actions.ts +++ b/packages/store/src/ledger/actions.ts @@ -6,7 +6,7 @@ import { Dispatched, GetState } from '../types'; import { ActionTypes, AddressSelected, - Connected, + Connected, IGetAddressesAction, IUpdateAddressAction, SetBaseHD, SetHDOffset, SetListHDPath, Watch @@ -44,11 +44,13 @@ export function setHdOffsetAction (offset: number): SetHDOffset { }; } -export function getAddressesAction (offset: number = 0, count: number = 5) { +export function getAddressesAction (offset: number = 0, count: number = 5): IGetAddressesAction { return { type: ActionTypes.GET_ADDRESSES, - offset, - count + payload: { + offset, + count + } }; } diff --git a/packages/store/src/ledger/sagas.ts b/packages/store/src/ledger/sagas.ts index de46de27a..e1ecf7525 100644 --- a/packages/store/src/ledger/sagas.ts +++ b/packages/store/src/ledger/sagas.ts @@ -11,7 +11,7 @@ function* fetchAddrInfo (api: IApi, action: LoadAddrInfoAction) { } function* getAddressesSaga (api: IApi, action: IGetAddressesAction) { - const { offset, count } = action; + const { offset, count } = action.payload; yield put(setHdOffsetAction(offset)); yield put(selectAddressAction(undefined)); @@ -34,17 +34,9 @@ function* getAddressesSaga (api: IApi, action: IGetAddressesAction) { } } -function* watchLoadInfo (api: IApi) { - yield takeEvery(ActionTypes.LOAD_ADDR_INFO, fetchAddrInfo, api); -} - -function* watchGetAddresses (api: IApi) { - yield takeLatest(ActionTypes.GET_ADDRESSES, getAddressesSaga, api); -} - export function* root (api: IApi) { yield all([ - watchLoadInfo(api), - watchGetAddresses(api) + takeEvery(ActionTypes.LOAD_ADDR_INFO, fetchAddrInfo, api), + takeLatest(ActionTypes.GET_ADDRESSES, getAddressesSaga, api) ]); } diff --git a/packages/store/src/ledger/types.ts b/packages/store/src/ledger/types.ts index ac35e0e69..4fb6c72a0 100644 --- a/packages/store/src/ledger/types.ts +++ b/packages/store/src/ledger/types.ts @@ -70,8 +70,10 @@ export interface LoadAddrInfoAction { export interface IGetAddressesAction { type: ActionTypes.GET_ADDRESSES; - offset: number; - count: number; + payload: { + offset: number; + count: number; + }; } export type LedgerAction = diff --git a/packages/store/src/screen/index.ts b/packages/store/src/screen/index.ts index 069fe7633..317510838 100644 --- a/packages/store/src/screen/index.ts +++ b/packages/store/src/screen/index.ts @@ -1,5 +1,6 @@ import * as actions from './actions'; import { reducer } from './reducer'; import * as selectors from './selectors'; +import { Pages } from './types'; -export { actions, reducer, selectors }; +export { actions, reducer, selectors, Pages }; diff --git a/packages/store/src/screen/types.ts b/packages/store/src/screen/types.ts index 49026eb80..37131ea06 100644 --- a/packages/store/src/screen/types.ts +++ b/packages/store/src/screen/types.ts @@ -9,6 +9,10 @@ export enum ActionTypes { NOTIFICATION_CLOSE = 'SCREEN/NOTIFICATION_CLOSE' } +export enum Pages { + ACCOUNT = 'account' +} + export interface IScreenState { screen: any | null; item: any | null; diff --git a/packages/store/src/settings/actions.ts b/packages/store/src/settings/actions.ts index 84d62e4a3..46819f980 100644 --- a/packages/store/src/settings/actions.ts +++ b/packages/store/src/settings/actions.ts @@ -1,6 +1,6 @@ import { ipcRenderer } from 'electron'; import * as screen from '../screen'; -import { ActionTypes, ILoadSettingsAction } from './types'; +import { ActionTypes, ILoadSettingsAction, ISetExchRatesAction } from './types'; export interface ISettings { language: string; @@ -37,13 +37,11 @@ export function update (settings: ISettings) { }; } -export function listenPrices () { - return (dispatch: any, getState: any) => { - ipcRenderer.on('prices/rate', (event: any, rates: any) => { - dispatch({ - type: ActionTypes.EXCHANGE_RATES, - rates - }); - }); +export function setRatesAction (rates: any): ISetExchRatesAction { + return { + type: ActionTypes.EXCHANGE_RATES, + payload: { + rates + } }; } diff --git a/packages/store/src/settings/reducer.spec.ts b/packages/store/src/settings/reducer.spec.ts index 38d1c41a6..5017d6e08 100644 --- a/packages/store/src/settings/reducer.spec.ts +++ b/packages/store/src/settings/reducer.spec.ts @@ -1,3 +1,4 @@ +import { setRatesAction } from './actions'; import settingsReducers from './reducer'; import { ActionTypes } from './types'; @@ -10,13 +11,12 @@ describe('settingsReducers', () => { }); // do - state = settingsReducers(state, { - type: ActionTypes.EXCHANGE_RATES, - rates: { + state = settingsReducers(state, setRatesAction( + { ETC: 5, ETH: 10 } - }); + )); // assert expect(state.get('localeRate')).toEqual(5); diff --git a/packages/store/src/settings/reducer.ts b/packages/store/src/settings/reducer.ts index 3d506c20e..dd2a6e35e 100644 --- a/packages/store/src/settings/reducer.ts +++ b/packages/store/src/settings/reducer.ts @@ -36,9 +36,10 @@ function onSetLocaleCurrency (state: ISettingsState, action: SetLocaleCurrencyAc } function onExchangeRates (state: ISettingsState, action: ISetExchRatesAction) { + const { rates } = action.payload; return state - .set('rates', fromJS(action.rates)) - .set('localeRate', action.rates ? action.rates.ETC : null); + .set('rates', fromJS(rates)) + .set('localeRate', rates ? rates.ETC : null); } diff --git a/packages/store/src/settings/types.ts b/packages/store/src/settings/types.ts index 11c12f00e..b283c3255 100644 --- a/packages/store/src/settings/types.ts +++ b/packages/store/src/settings/types.ts @@ -35,7 +35,9 @@ export interface SetShowHiddenAccsAction { export interface ISetExchRatesAction { type: ActionTypes.EXCHANGE_RATES; - rates: any; + payload: { + rates: any; + }; } export type SettingsAction = diff --git a/packages/store/src/wallet/sagas.ts b/packages/store/src/wallet/sagas.ts index 0dfae1ab9..693f255fd 100644 --- a/packages/store/src/wallet/sagas.ts +++ b/packages/store/src/wallet/sagas.ts @@ -1,6 +1,6 @@ import { IApi } from '@emeraldwallet/core'; import { all, put, select, takeEvery } from 'redux-saga/effects'; -import * as addresses from '../addresses'; +import * as addresses from '../accounts'; import * as screen from '../screen'; import { ActionTypes, IOpenAccDetailsAction } from './types'; @@ -11,7 +11,7 @@ function* openAccountDetails (api: IApi, action: IOpenAccDetailsAction) { yield put(screen.actions.showNotification( `Account ${address} not found in the vault`, 'warning', 3000, '', () => {})); } else { - yield put(screen.actions.gotoScreen('account', acc)); + yield put(screen.actions.gotoScreen(screen.Pages.ACCOUNT, acc)); } } diff --git a/packages/ui/package.json b/packages/ui/package.json index 2f9853978..c74f9c842 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -25,6 +25,7 @@ "@material-ui/lab": "^4.0.0-alpha.19", "@material-ui/styles": "^4.2.0", "bignumber.js": "8.0.2", + "classnames": "2.2.6", "qrcode.react": "^0.9.3", "react": "16.11.0", "react-autosuggest": "^9.4.3", diff --git a/packages/ui/src/components/accounts/ImportPrivateKey/ImportPrivateKey.spec.tsx b/packages/ui/src/components/accounts/ImportPrivateKey/ImportPrivateKey.spec.tsx index 408c2a134..8a27bcb7f 100644 --- a/packages/ui/src/components/accounts/ImportPrivateKey/ImportPrivateKey.spec.tsx +++ b/packages/ui/src/components/accounts/ImportPrivateKey/ImportPrivateKey.spec.tsx @@ -1,13 +1,19 @@ -import { shallow } from 'enzyme'; +import '@testing-library/jest-dom/extend-expect'; +import { fireEvent, render } from '@testing-library/react'; import * as React from 'react'; import { ImportPrivateKey, styles } from './ImportPrivateKey'; -const reduceClasses = (prev, curr) => ({ ...prev, [curr]: curr }); +const reduceClasses = (prev, curr) => ({ ...prev, [curr]: curr }); const classes = Object.keys(styles).reduce(reduceClasses, {}); describe('ImportPrivateKey', () => { - it('renders without crash', () => { - const component = shallow(); - expect(component).toBeDefined(); + + it('shows error when passwords do not match', () => { + const comp = render(); + const confirm = comp.getByPlaceholderText('Confirm Password'); + expect(comp.queryByText('Password must match')).toBeNull(); + fireEvent.change(confirm, { target: { value: 'a' } }); + const error = comp.getByText('Password must match'); + expect(error).toHaveTextContent('Password must match'); }); }); diff --git a/packages/ui/src/components/accounts/ImportPrivateKey/ImportPrivateKey.tsx b/packages/ui/src/components/accounts/ImportPrivateKey/ImportPrivateKey.tsx index c98ae34d2..c434b1775 100644 --- a/packages/ui/src/components/accounts/ImportPrivateKey/ImportPrivateKey.tsx +++ b/packages/ui/src/components/accounts/ImportPrivateKey/ImportPrivateKey.tsx @@ -1,11 +1,12 @@ import { Input, Page, Warning, WarningHeader, WarningText } from '@emeraldplatform/ui'; import { Back } from '@emeraldplatform/ui-icons'; import { Blockchain, BlockchainCode } from '@emeraldwallet/core'; -import CircularProgress from '@material-ui/core/CircularProgress'; +import { CircularProgress } from '@material-ui/core'; import { withStyles } from '@material-ui/styles'; import * as React from 'react'; import Button from '../../common/Button'; import ChainSelector from '../../common/ChainSelector/ChainSelector'; +import FormRow from '../../common/FormRow'; import PasswordInput from '../../common/PasswordInput'; export const styles = { @@ -85,7 +86,7 @@ export class ImportPrivateKey extends React.Component { public handleConfirmPwdChange = (event: any) => { const confirmPassword = event.target.value; - if (this.state.password != confirmPassword) { + if (this.state.password !== confirmPassword) { this.setState({ confirmError: 'Password must match' }); } else { this.setState({ confirmError: null }); @@ -114,11 +115,20 @@ export class ImportPrivateKey extends React.Component { const { blockchain, privateKey, confirmPassword, password } = this.state; const invalid = ((password || '').length < PasswordInput.DEFAULT_MIN_LENGTH) || - ((privateKey || '').length == 0) || + ((privateKey || '').length === 0) || (password !== confirmPassword); return ( }> + + )} + />
@@ -184,7 +194,7 @@ export class ImportPrivateKey extends React.Component { disabled={submitting || invalid} icon={getLoadingIcon(submitting)} /> - +
diff --git a/packages/ui/src/components/common/NotificationBar/NotificationBar.spec.tsx b/packages/ui/src/components/common/NotificationBar/NotificationBar.spec.tsx index 72014889e..a265010ac 100644 --- a/packages/ui/src/components/common/NotificationBar/NotificationBar.spec.tsx +++ b/packages/ui/src/components/common/NotificationBar/NotificationBar.spec.tsx @@ -1,13 +1,18 @@ -import { shallow } from 'enzyme'; +import { render } from '@testing-library/react'; import * as React from 'react'; import { NotificationBar } from './NotificationBar'; -const reduceClasses = (prev: any, curr: any) => ({ ...prev, [curr]: curr }); +const reduceClasses = (prev: any, curr: any) => ({ ...prev, [curr]: curr }); const classes = Object.keys({ success: {}, info: {}, error: {}, common: {} }).reduce(reduceClasses, {}); describe('NotificationBar', () => { it('should be created without crash', () => { - const component = shallow(); + const component = render( + + ); expect(component).toBeDefined(); }); }); diff --git a/packages/ui/src/components/common/NotificationBar/NotificationBar.tsx b/packages/ui/src/components/common/NotificationBar/NotificationBar.tsx index f8bafd9d1..8cde62077 100644 --- a/packages/ui/src/components/common/NotificationBar/NotificationBar.tsx +++ b/packages/ui/src/components/common/NotificationBar/NotificationBar.tsx @@ -1,11 +1,9 @@ +import { Snackbar, SnackbarContent, withStyles } from '@material-ui/core'; import orange from '@material-ui/core/colors/orange'; -import Snackbar from '@material-ui/core/Snackbar'; -import SnackbarContent from '@material-ui/core/SnackbarContent'; -import { withStyles } from '@material-ui/core/styles'; import classNames from 'classnames'; import * as React from 'react'; -export interface Props { +export interface IBarProps { onActionClick?: any; onRequestClose?: any; notificationActionToDispatchOnActionClick?: any; @@ -17,7 +15,7 @@ export interface Props { open?: boolean; } -interface State { +interface IBarState { open: boolean; } @@ -32,14 +30,14 @@ const styles = (theme) => ({ } }); -export class NotificationBar extends React.Component { +export class NotificationBar extends React.Component { constructor (props) { super(props); this.state = { open: props.open || false }; this.onActionClick = this.onActionClick.bind(this); } - public UNSAFE_componentWillReceiveProps (nextProps) { // eslint-disable-line + public UNSAFE_componentWillReceiveProps (nextProps) { if (nextProps.notificationMessage) { this.setState({ open: true }); } else { @@ -53,21 +51,8 @@ export class NotificationBar extends React.Component { public render () { const { classes } = this.props; - // const colors = { - // success: muiTheme.palette.primary1Color, - // error: muiTheme.palette.accent1Color, - // info: muiTheme.palette.textColor, - // warning: orange[300], - // }; return ( ({ ...prev, [curr]: curr }); -const classes = Object.keys(styles2).reduce(reduceClasses, {}); - -const theme = { - palette: {} -}; - -const tx = { - blockNumber: 1, - from: '0x1', - to: '0x2', - value: new BigNumber(100000) -}; -const from = {}; -const to = {}; - -describe('TxItem', () => { - it('should renders without crash', () => { - const wrapper = mount( - {}} - openTx={() => {}} - netParams={ - { - currentBlockHeight: 100, - requiredConfirmations: 12 - } - } - classes={classes} - tx={tx} - fromAccount={from} - toAccount={to} - />); - expect(wrapper).toBeDefined(); - }); -}); diff --git a/packages/ui/stories/ImportPrivateKey/index.tsx b/packages/ui/stories/ImportPrivateKey/index.tsx index a3de5555c..850a0c677 100644 --- a/packages/ui/stories/ImportPrivateKey/index.tsx +++ b/packages/ui/stories/ImportPrivateKey/index.tsx @@ -1,7 +1,15 @@ +import { Blockchain, BlockchainCode, Blockchains } from '@emeraldwallet/core'; import { action } from '@storybook/addon-actions'; import { storiesOf } from '@storybook/react'; import * as React from 'react'; import ImportPrivateKey from '../../src/components/accounts/ImportPrivateKey'; +const chains: Blockchain[] = [ + Blockchains[BlockchainCode.ETC], + Blockchains[BlockchainCode.ETH] +]; + storiesOf('ImportPrivateKey', module) - .add('default', () => ()); + .add('default', () => ( + + )); diff --git a/yarn.lock b/yarn.lock index 1c0b21f72..99d049710 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5690,7 +5690,7 @@ classnames@2.2.5: resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d" integrity sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0= -classnames@^2.2.5, classnames@^2.2.6: +classnames@2.2.6, classnames@^2.2.5, classnames@^2.2.6: version "2.2.6" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==