From 2982dda4d3462e01f8e453514c0b4b72e3b4448d Mon Sep 17 00:00:00 2001 From: George Lima Date: Mon, 28 Jan 2019 21:34:07 -0300 Subject: [PATCH] type(coverage): improve flow coverage --- app/components/button.js | 4 +-- app/components/input-label.js | 4 +-- app/components/sidebar.js | 20 ++++--------- app/components/text.js | 2 +- app/containers/dashboard.js | 43 ++++++++++++++------------- app/containers/send.js | 3 +- app/containers/transactions.js | 10 ++----- app/index.js | 5 +++- app/redux/modules/wallet.js | 2 +- app/types/redux.js | 2 +- app/views/settings.js | 21 ++++--------- config/daemon/fetch-windows-params.js | 21 +++---------- config/electron.js | 26 ++++++++-------- config/main.js | 2 ++ services/utils.js | 1 + services/zec-price.js | 3 +- utils/debug-shortcut.js | 16 ++++++---- 17 files changed, 82 insertions(+), 103 deletions(-) diff --git a/app/components/button.js b/app/components/button.js index d867613..8cce833 100644 --- a/app/components/button.js +++ b/app/components/button.js @@ -24,7 +24,7 @@ const DefaultButton = styled.button` transition: background-color 0.1s ${props => props.theme.colors.transitionEase}; `; -const Primary = styled(DefaultButton)` +const Primary = styled<{ theme: Object }>(DefaultButton)` background-color: ${props => props.theme.colors.primary}; color: ${props => props.theme.colors.secondary}; border: none; @@ -40,7 +40,7 @@ const Primary = styled(DefaultButton)` } `; -const Secondary = styled(DefaultButton)` +const Secondary = styled<{ theme: Object }>(DefaultButton)` background-color: transparent; color: ${props => props.theme.colors.secondary}; border: 2px solid ${props => props.theme.colors.buttonBorderColor}; diff --git a/app/components/input-label.js b/app/components/input-label.js index 4b61991..8625c2b 100644 --- a/app/components/input-label.js +++ b/app/components/input-label.js @@ -1,9 +1,9 @@ // @flow import styled from 'styled-components'; -import { TextComponent } from './text'; +import { TextComponent, type Props } from './text'; -export const InputLabelComponent = styled(TextComponent)` +export const InputLabelComponent = styled<{ ...Props, marginTop: string }>(TextComponent)` margin: ${props => props.marginTop || '20px'} 0 8.5px 0; font-weight: ${props => props.theme.fontWeight.bold}; `; diff --git a/app/components/sidebar.js b/app/components/sidebar.js index a1fe851..e12cdd9 100644 --- a/app/components/sidebar.js +++ b/app/components/sidebar.js @@ -1,5 +1,5 @@ // @flow - +/* eslint-disable max-len */ import React from 'react'; import styled from 'styled-components'; import { Link, type Location } from 'react-router-dom'; @@ -17,15 +17,11 @@ const Wrapper = styled.div` `; const StyledLink = styled(Link)` - color: ${props => (props.isActive - ? props.theme.colors.sidebarItemActive - : props.theme.colors.sidebarItem)}; + color: ${props => (props.isActive ? props.theme.colors.sidebarItemActive : props.theme.colors.sidebarItem)}; font-size: ${props => `${props.theme.fontSize.regular}em`}; text-decoration: none; font-weight: ${props => props.theme.fontWeight.bold}; - background-color: ${props => (props.isActive - ? `${props.theme.colors.sidebarHoveredItem}` - : 'transparent')}; + background-color: ${props => (props.isActive ? `${props.theme.colors.sidebarHoveredItem}` : 'transparent')}; letter-spacing: 0.25px; padding: 25px 20px; height: 35px; @@ -33,9 +29,7 @@ const StyledLink = styled(Link)` display: flex; align-items: center; outline: none; - border-right: ${props => (props.isActive - ? `3px solid ${props.theme.colors.sidebarItemActive}` - : 'none')}; + border-right: ${props => (props.isActive ? `3px solid ${props.theme.colors.sidebarItemActive}` : 'none')}; cursor: pointer; transition: all 0.03s ${props => props.theme.colors.transitionEase}; @@ -76,11 +70,7 @@ export const SidebarComponent = ({ options, location }: Props) => ( return ( - + {item.label} ); diff --git a/app/components/text.js b/app/components/text.js index 21ab22a..ec182ce 100644 --- a/app/components/text.js +++ b/app/components/text.js @@ -16,7 +16,7 @@ const Text = styled.p` text-align: ${props => props.align}; `; -type Props = { +export type Props = { ...ElementProps<'p'>, value: string, isBold?: boolean, diff --git a/app/containers/dashboard.js b/app/containers/dashboard.js index 2316756..43bc12b 100644 --- a/app/containers/dashboard.js +++ b/app/containers/dashboard.js @@ -37,25 +37,30 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ if (err) return dispatch(loadWalletSummaryError({ error: err.message })); - const [zAddressesErr, zAddresses] = await eres(rpc.z_listaddresses()); + const [zAddressesErr, zAddresses = []] = await eres(rpc.z_listaddresses()); - const [tAddressesErr, transparentAddresses] = await eres( - rpc.getaddressesbyaccount(''), - ); + if (zAddressesErr) { + return dispatch( + loadWalletSummaryError({ + error: zAddressesErr.message, + }), + ); + } - // eslint-disable-next-line - if (zAddressesErr || tAddressesErr) return dispatch( - loadWalletSummaryError({ - error: zAddressesErr?.message || tAddressesErr?.message, - }), - ); + const [tAddressesErr, tAddresses = []] = await eres(rpc.getaddressesbyaccount('')); + + if (tAddressesErr) { + return dispatch( + loadWalletSummaryError({ + error: tAddressesErr.message, + }), + ); + } const [transactionsErr, transactions] = await eres(rpc.listtransactions()); if (transactionsErr) { - return dispatch( - loadWalletSummaryError({ error: transactionsErr.message }), - ); + return dispatch(loadWalletSummaryError({ error: transactionsErr.message })); } const formattedTransactions = flow([ @@ -75,20 +80,18 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ ])(transactions); if (!zAddresses.length) { - const [getNewZAddressErr, newZAddress] = await eres( - rpc.z_getnewaddress(), - ); + const [getNewZAddressErr, newZAddress] = await eres(rpc.z_getnewaddress()); if (!getNewZAddressErr && newZAddress) { zAddresses.push(newZAddress); } } - if (!transparentAddresses.length) { + if (!tAddresses.length) { const [getNewAddressErr, newAddress] = await eres(rpc.getnewaddress('')); if (!getNewAddressErr && newAddress) { - transparentAddresses.push(newAddress); + tAddresses.push(newAddress); } } @@ -97,9 +100,9 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ transparent: walletSummary.transparent, total: walletSummary.total, shielded: walletSummary.private, - addresses: [...zAddresses, ...transparentAddresses], + addresses: [...zAddresses, ...tAddresses], transactions: formattedTransactions, - zecPrice: store.get('ZEC_DOLLAR_PRICE'), + zecPrice: Number(store.get('ZEC_DOLLAR_PRICE')), }), ); }, diff --git a/app/containers/send.js b/app/containers/send.js index 9fe767c..30b7bf5 100644 --- a/app/containers/send.js +++ b/app/containers/send.js @@ -48,6 +48,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ }: SendTransactionInput) => { dispatch(sendTransaction()); + // $FlowFixMe const [sendErr, operationId] = await eres( rpc.z_sendmany( from, @@ -136,7 +137,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ }, loadZECPrice: () => dispatch( loadZECPrice({ - value: store.get('ZEC_DOLLAR_PRICE'), + value: Number(store.get('ZEC_DOLLAR_PRICE')), }), ), }); diff --git a/app/containers/transactions.js b/app/containers/transactions.js index fc24fb8..d456664 100644 --- a/app/containers/transactions.js +++ b/app/containers/transactions.js @@ -31,14 +31,10 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ getTransactions: async () => { dispatch(loadTransactions()); - const [transactionsErr, transactions = []] = await eres( - rpc.listtransactions(), - ); + const [transactionsErr, transactions = []] = await eres(rpc.listtransactions()); if (transactionsErr) { - return dispatch( - loadTransactionsError({ error: transactionsErr.message }), - ); + return dispatch(loadTransactionsError({ error: transactionsErr.message })); } const formattedTransactions = flow([ @@ -60,7 +56,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ dispatch( loadTransactionsSuccess({ list: formattedTransactions, - zecPrice: store.get('ZEC_DOLLAR_PRICE'), + zecPrice: Number(store.get('ZEC_DOLLAR_PRICE')), }), ); }, diff --git a/app/index.js b/app/index.js index ec64a6d..a09b9cf 100644 --- a/app/index.js +++ b/app/index.js @@ -1,7 +1,10 @@ +// @flow + import React from 'react'; import ReactDOM from 'react-dom'; import App from './app'; const el = document.getElementById('root'); -ReactDOM.render(, el); + +if (el) ReactDOM.render(, el); diff --git a/app/redux/modules/wallet.js b/app/redux/modules/wallet.js index a7d3879..d0a9e94 100644 --- a/app/redux/modules/wallet.js +++ b/app/redux/modules/wallet.js @@ -8,7 +8,7 @@ export const LOAD_WALLET_SUMMARY_SUCCESS = 'LOAD_WALLET_SUMMARY_SUCCESS'; export const LOAD_WALLET_SUMMARY_ERROR = 'LOAD_WALLET_SUMMARY_ERROR'; // Actions Creators -export const loadWalletSummary = () => ({ +export const loadWalletSummary: () => Action = () => ({ type: LOAD_WALLET_SUMMARY, payload: {}, }); diff --git a/app/types/redux.js b/app/types/redux.js index 84151d4..47e2357 100644 --- a/app/types/redux.js +++ b/app/types/redux.js @@ -4,4 +4,4 @@ type State = {||}; export type Action = { type: $Subtype, payload: Object }; export type GetState = () => State; -export type Dispatch = (action: Action) => any; +export type Dispatch = (action: Action) => void; diff --git a/app/views/settings.js b/app/views/settings.js index 4cf93f4..ea663c8 100644 --- a/app/views/settings.js +++ b/app/views/settings.js @@ -170,6 +170,7 @@ export class SettingsView extends PureComponent { )}.dat`; electron.remote.dialog.showSaveDialog( + undefined, { defaultPath: backupFileName }, async (pathToSave) => { if (!pathToSave) return; @@ -182,19 +183,13 @@ export class SettingsView extends PureComponent { /* eslint-disable no-alert */ if (cannotAccess) { - alert( - "Couldn't backup the wallet.dat file. You need to back it up manually.", - ); + alert("Couldn't backup the wallet.dat file. You need to back it up manually."); } - const [error] = await eres( - promisify(fs.copyFile)(walletDatPath, pathToSave), - ); + const [error] = await eres(promisify(fs.copyFile)(walletDatPath, pathToSave)); if (error) { - alert( - "Couldn't backup the wallet.dat file. You need to back it up manually.", - ); + alert("Couldn't backup the wallet.dat file. You need to back it up manually."); } }, ); @@ -307,16 +302,12 @@ export class SettingsView extends PureComponent { this.setState({ importedPrivateKeys: value }) - } + onChange={value => this.setState({ importedPrivateKeys: value })} inputType='textarea' rows={10} /> {successImportPrivateKeys && ( - + )} {error && } diff --git a/config/daemon/fetch-windows-params.js b/config/daemon/fetch-windows-params.js index dfba7d9..21cade5 100644 --- a/config/daemon/fetch-windows-params.js +++ b/config/daemon/fetch-windows-params.js @@ -71,9 +71,7 @@ const downloadFile = ({ file, pathToSave }): Promise<*> => new Promise((resolve, log(`SHA256 validation for file ${file.name} succeeded!`); resolve(file.name); } else { - reject( - new Error(`SHA256 validation failed for file: ${file.name}`), - ); + reject(new Error(`SHA256 validation failed for file: ${file.name}`)); } }); }) @@ -84,9 +82,7 @@ const downloadFile = ({ file, pathToSave }): Promise<*> => new Promise((resolve, let missingDownloadParam = false; export default (): Promise<*> => new Promise((resolve, reject) => { - const firstRunProcess = cp.spawn( - path.join(getBinariesPath(), 'win', 'first-run.bat'), - ); + const firstRunProcess = cp.spawn(path.join(getBinariesPath(), 'win', 'first-run.bat')); firstRunProcess.stdout.on('data', data => log(data.toString())); firstRunProcess.stderr.on('data', data => reject(data.toString())); @@ -95,12 +91,7 @@ export default (): Promise<*> => new Promise((resolve, reject) => { await Promise.all( FILES.map(async (file) => { - const pathToSave = path.join( - app.getPath('userData'), - '..', - 'ZcashParams', - file.name, - ); + const pathToSave = path.join(app.getPath('userData'), '..', 'ZcashParams', file.name); const [cannotAccess] = await eres( util.promisify(fs.access)(pathToSave, fs.constants.F_OK), @@ -115,11 +106,7 @@ export default (): Promise<*> => new Promise((resolve, reject) => { if (isValid) { log(`${file.name} already is in ${pathToSave}...`); } else { - log( - `File: ${ - file.name - } failed in the SHASUM validation, downloading again...`, - ); + log(`File: ${file.name} failed in the SHASUM validation, downloading again...`); queue.add(() => { // eslint-disable-next-line max-len downloadFile({ file, pathToSave }).then(() => log(`Download ${file.name} finished!`)); diff --git a/config/electron.js b/config/electron.js index 899ca95..4b50b24 100644 --- a/config/electron.js +++ b/config/electron.js @@ -5,11 +5,9 @@ import dotenv from 'dotenv'; import path from 'path'; /* eslint-disable import/no-extraneous-dependencies */ -import { app, BrowserWindow } from 'electron'; +import { app, BrowserWindow, typeof BrowserWindow as BrowserWindowType } from 'electron'; import { autoUpdater } from 'electron-updater'; import isDev from 'electron-is-dev'; -/* eslint-enable import/no-extraneous-dependencies */ -import type { BrowserWindow as BrowserWindowType } from 'electron'; import eres from 'eres'; import { registerDebugShortcut } from '../utils/debug-shortcut'; import runDaemon from './daemon/zcashd-child-process'; @@ -26,10 +24,12 @@ let zcashDaemon; const showStatus = (text) => { if (text === 'Update downloaded') updateAvailable = true; - mainWindow.webContents.send('update', { - updateAvailable, - updateInfo: text, - }); + if (mainWindow) { + mainWindow.webContents.send('update', { + updateAvailable, + updateInfo: text, + }); + } }; const createWindow = () => { @@ -42,9 +42,9 @@ const createWindow = () => { autoUpdater.on('download-progress', progress => showStatus( /* eslint-disable-next-line max-len */ - `Download speed: ${progress.bytesPerSecond} - Downloaded ${ - progress.percent - }% (${progress.transferred}/${progress.total})`, + `Download speed: ${progress.bytesPerSecond} - Downloaded ${progress.percent}% (${ + progress.transferred + }/${progress.total})`, )); autoUpdater.on('update-downloaded', () => { updateAvailable = true; @@ -64,16 +64,14 @@ const createWindow = () => { }); getZecPrice().then((obj) => { - store.set('ZEC_DOLLAR_PRICE', obj.USD); + store.set('ZEC_DOLLAR_PRICE', String(obj.USD)); }); mainWindow.setVisibleOnAllWorkspaces(true); registerDebugShortcut(app, mainWindow); mainWindow.loadURL( - isDev - ? 'http://0.0.0.0:8080/' - : `file://${path.join(__dirname, '../build/index.html')}`, + isDev ? 'http://0.0.0.0:8080/' : `file://${path.join(__dirname, '../build/index.html')}`, ); exports.app = app; diff --git a/config/main.js b/config/main.js index 3219cba..efa1f66 100644 --- a/config/main.js +++ b/config/main.js @@ -1,3 +1,5 @@ +// @flow + const path = require('path'); const appRoot = path.join(__dirname, '..'); diff --git a/services/utils.js b/services/utils.js index cb7f523..216f999 100644 --- a/services/utils.js +++ b/services/utils.js @@ -679,6 +679,7 @@ export type APIMethods = { amount: number, vout: number, fee: number, + category: string, confirmations: number, blockhash: string, blockindex: number, diff --git a/services/zec-price.js b/services/zec-price.js index a5b7a03..71788fa 100644 --- a/services/zec-price.js +++ b/services/zec-price.js @@ -1,5 +1,6 @@ // @flow -// eslint-disable-next-line import/no-extraneous-dependencies +/* eslint-disable import/no-extraneous-dependencies */ +// $FlowFixMe import { net } from 'electron'; type Payload = { diff --git a/utils/debug-shortcut.js b/utils/debug-shortcut.js index 3a75a68..142aa1e 100644 --- a/utils/debug-shortcut.js +++ b/utils/debug-shortcut.js @@ -1,9 +1,15 @@ // @flow /* eslint-disable import/no-extraneous-dependencies */ -import { globalShortcut } from 'electron'; +import { globalShortcut, typeof BrowserWindow, typeof app as ElectronApp } from 'electron'; -export const registerDebugShortcut = (app: Object, mainWindow: Object) => globalShortcut.register('CommandOrControl+Option+B', () => { - app.dock.show(); - mainWindow.webContents.openDevTools(); -}); +export const registerDebugShortcut = (app: ElectronApp, mainWindow: BrowserWindow) => { + if (globalShortcut) { + globalShortcut.register('CommandOrControl+Option+B', () => { + // $FlowFixMe + app.dock.show(); + // $FlowFixMe + mainWindow.webContents.openDevTools(); + }); + } +};