mirror of
https://github.com/kremalicious/blowfish.git
synced 2024-12-28 23:57:52 +01:00
Merge pull request #44 from kremalicious/feature/tests
Add test setup and tests
This commit is contained in:
commit
6797dd37f0
12
.babelrc
12
.babelrc
@ -1,4 +1,14 @@
|
|||||||
{
|
{
|
||||||
"presets": ["@babel/env", "@babel/react"],
|
"presets": [
|
||||||
|
[
|
||||||
|
"@babel/env",
|
||||||
|
{
|
||||||
|
"targets": {
|
||||||
|
"node": "current"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"@babel/react"
|
||||||
|
],
|
||||||
"plugins": ["@babel/plugin-proposal-class-properties"]
|
"plugins": ["@babel/plugin-proposal-class-properties"]
|
||||||
}
|
}
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ yarn.lock
|
|||||||
package-lock.json
|
package-lock.json
|
||||||
build
|
build
|
||||||
dist
|
dist
|
||||||
|
coverage
|
||||||
|
19
.travis.yml
19
.travis.yml
@ -1,4 +1,4 @@
|
|||||||
osx_image: xcode10.2
|
osx_image: xcode11
|
||||||
os: osx
|
os: osx
|
||||||
language: node_js
|
language: node_js
|
||||||
node_js: node
|
node_js: node
|
||||||
@ -15,8 +15,15 @@ cache:
|
|||||||
- $HOME/.cache/electron-builder
|
- $HOME/.cache/electron-builder
|
||||||
- $HOME/.npm/_prebuilds
|
- $HOME/.npm/_prebuilds
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-darwin-amd64 > ./cc-test-reporter
|
||||||
|
- chmod +x ./cc-test-reporter
|
||||||
|
- ./cc-test-reporter before-build
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- npm test
|
- npm test || travis_terminate 1
|
||||||
|
- ./cc-test-reporter format-coverage -t lcov -o coverage/codeclimate.json src/renderer/coverage/lcov.info
|
||||||
|
- if [[ "$TRAVIS_TEST_RESULT" == 0 ]]; then ./cc-test-reporter upload-coverage; fi
|
||||||
- npm run dist
|
- npm run dist
|
||||||
|
|
||||||
branches:
|
branches:
|
||||||
@ -27,9 +34,9 @@ notifications:
|
|||||||
email: false
|
email: false
|
||||||
slack:
|
slack:
|
||||||
template:
|
template:
|
||||||
- "`%{repository_slug}#%{branch}`"
|
- '`%{repository_slug}#%{branch}`'
|
||||||
- "*%{result}* build (<%{build_url}|#%{build_number}>) for <%{compare_url}|%{commit}>"
|
- '*%{result}* build (<%{build_url}|#%{build_number}>) for <%{compare_url}|%{commit}>'
|
||||||
- "Execution time: *%{duration}*"
|
- 'Execution time: *%{duration}*'
|
||||||
- "Message: %{message}"
|
- 'Message: %{message}'
|
||||||
rooms:
|
rooms:
|
||||||
- secure: r6kVJw3zS4raTXgeBEYZYO/5YawnLoi1vO4zG3obhcNFRLm9FxlzuXfulFhjQA4viPQUW07m5UGud4bPTrDIAE35GUcLRlyisH/odahgsrmqLrBvz9CB+/V5WrEsCGpE9G3I/y5JGSRavjs+5qfVqJZaAI9Ox7bCcw+Msa5r/p7/yJw5di4EzgNLFWQswyio0zeOdjtCYgqpngWtLGpn0ksSwqNyqp/kntoHSz4nDdO/6GWS1q5K9mOfGMXr/wwiYuQrgDPpygRWETy9F8qh9yH2cseJmCZaXvSTSU1L9yV01qrBP5zDTTM2jPUGMQKY4JBoxFtU29G1BLWGAgMW9ymKe9V+f8FgbirZ+O1Vp87QAZPJXx5kO+pgqBtGewoYfp0k9HJ5xQAhr83l82w8BAEHVS3G/Y7cKKK9QNH9Z6gpdx6Y3s9YkpGqkv79MRvZo0tJV+XTOldCCfUFVxXXuZofuswWGUgt2h9qNoFY+AZc0G1TV/XVDHbDm32JNiGkuk+uO83HT9VI7G5PRWNcD8kP7ZS6XThiU2qOGr4OPGggmpFpJ7Yqc3LNFOjhFunKSzGOrZrc0GLZAbAR7qHkWNpiqQQ/RSpfnXfbPlAIJY6w5Vuzh9KhIIPkbWdP89Bc2Kw+W+ACFjStO7s298/8dty44EvJ2TS9CCjOhYtgaxk=
|
- secure: r6kVJw3zS4raTXgeBEYZYO/5YawnLoi1vO4zG3obhcNFRLm9FxlzuXfulFhjQA4viPQUW07m5UGud4bPTrDIAE35GUcLRlyisH/odahgsrmqLrBvz9CB+/V5WrEsCGpE9G3I/y5JGSRavjs+5qfVqJZaAI9Ox7bCcw+Msa5r/p7/yJw5di4EzgNLFWQswyio0zeOdjtCYgqpngWtLGpn0ksSwqNyqp/kntoHSz4nDdO/6GWS1q5K9mOfGMXr/wwiYuQrgDPpygRWETy9F8qh9yH2cseJmCZaXvSTSU1L9yV01qrBP5zDTTM2jPUGMQKY4JBoxFtU29G1BLWGAgMW9ymKe9V+f8FgbirZ+O1Vp87QAZPJXx5kO+pgqBtGewoYfp0k9HJ5xQAhr83l82w8BAEHVS3G/Y7cKKK9QNH9Z6gpdx6Y3s9YkpGqkv79MRvZo0tJV+XTOldCCfUFVxXXuZofuswWGUgt2h9qNoFY+AZc0G1TV/XVDHbDm32JNiGkuk+uO83HT9VI7G5PRWNcD8kP7ZS6XThiU2qOGr4OPGggmpFpJ7Yqc3LNFOjhFunKSzGOrZrc0GLZAbAR7qHkWNpiqQQ/RSpfnXfbPlAIJY6w5Vuzh9KhIIPkbWdP89Bc2Kw+W+ACFjStO7s298/8dty44EvJ2TS9CCjOhYtgaxk=
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://travis-ci.com/kremalicious/blowfish"><img src="https://travis-ci.com/kremalicious/blowfish.svg?branch=master" /></a>
|
<a href="https://travis-ci.com/kremalicious/blowfish"><img src="https://travis-ci.com/kremalicious/blowfish.svg?branch=master" /></a>
|
||||||
<a href="https://codeclimate.com/github/kremalicious/blowfish/maintainability"><img src="https://api.codeclimate.com/v1/badges/beeab7902ee5307fc0a1/maintainability" /></a>
|
<a href="https://codeclimate.com/github/kremalicious/blowfish/maintainability"><img src="https://api.codeclimate.com/v1/badges/beeab7902ee5307fc0a1/maintainability" /></a>
|
||||||
|
<a href="https://codeclimate.com/github/kremalicious/blowfish/test_coverage"><img src="https://api.codeclimate.com/v1/badges/beeab7902ee5307fc0a1/test_coverage" /></a>
|
||||||
<a href="https://greenkeeper.io/"><img src="https://badges.greenkeeper.io/kremalicious/blowfish.svg" /></a>
|
<a href="https://greenkeeper.io/"><img src="https://badges.greenkeeper.io/kremalicious/blowfish.svg" /></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
60
package.json
60
package.json
@ -5,7 +5,9 @@
|
|||||||
"description": "🐡 Simple Electron-based desktop app to retrieve and display your total Ocean Token balances.",
|
"description": "🐡 Simple Electron-based desktop app to retrieve and display your total Ocean Token balances.",
|
||||||
"main": "./src/main/index.js",
|
"main": "./src/main/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "eslint --ignore-path .gitignore ./src/**/*.{js,jsx} && stylelint --ignore-path .gitignore ./src/**/*.{css,scss}",
|
"test": "npm run lint && jest --coverage",
|
||||||
|
"test:watch": "jest --coverage --watch",
|
||||||
|
"lint": "eslint --ignore-path .gitignore ./src/**/*.{js,jsx} && stylelint --ignore-path .gitignore ./src/**/*.{css,scss}",
|
||||||
"start": "webpack-dev-server --hot --host 0.0.0.0 --config=./webpack.dev.config.js",
|
"start": "webpack-dev-server --hot --host 0.0.0.0 --config=./webpack.dev.config.js",
|
||||||
"build": "cross-env NODE_ENV=production webpack --config webpack.common.config.js",
|
"build": "cross-env NODE_ENV=production webpack --config webpack.common.config.js",
|
||||||
"package": "electron-builder build -mwl -p never && open ./dist",
|
"package": "electron-builder build -mwl -p never && open ./dist",
|
||||||
@ -24,47 +26,54 @@
|
|||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@coingecko/cryptoformat": "^0.3.2",
|
"@coingecko/cryptoformat": "^0.3.3",
|
||||||
"ethereum-address": "0.0.4",
|
"ethereum-address": "0.0.4",
|
||||||
"ethereum-blockies": "github:MyEtherWallet/blockies",
|
"ethereum-blockies": "github:MyEtherWallet/blockies",
|
||||||
"ms": "^2.1.2"
|
"ms": "^2.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.6.0",
|
"@babel/core": "^7.6.2",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.5.5",
|
"@babel/plugin-proposal-class-properties": "^7.5.5",
|
||||||
"@babel/preset-env": "^7.6.0",
|
"@babel/preset-env": "^7.6.2",
|
||||||
"@babel/preset-react": "^7.0.0",
|
"@babel/preset-react": "^7.0.0",
|
||||||
|
"@jest-runner/electron": "^2.0.2",
|
||||||
"@reach/router": "^1.2.1",
|
"@reach/router": "^1.2.1",
|
||||||
"@svgr/webpack": "^4.3.2",
|
"@react-mock/state": "^0.1.8",
|
||||||
|
"@svgr/webpack": "^4.3.3",
|
||||||
|
"@testing-library/jest-dom": "^4.1.0",
|
||||||
|
"@testing-library/react": "^9.3.0",
|
||||||
"auto-changelog": "^1.16.1",
|
"auto-changelog": "^1.16.1",
|
||||||
"babel-eslint": "^10.0.3",
|
"babel-eslint": "^10.0.3",
|
||||||
|
"babel-jest": "^24.9.0",
|
||||||
"babel-loader": "^8.0.6",
|
"babel-loader": "^8.0.6",
|
||||||
"copy-webpack-plugin": "^5.0.4",
|
"copy-webpack-plugin": "^5.0.4",
|
||||||
"cross-env": "^6.0.0",
|
"cross-env": "^6.0.3",
|
||||||
"css-loader": "^3.2.0",
|
"css-loader": "^3.2.0",
|
||||||
"electron": "^6.0.7",
|
"electron": "^6.0.11",
|
||||||
"electron-builder": "^21.2.0",
|
"electron-builder": "^21.2.0",
|
||||||
"electron-devtools-installer": "^2.2.4",
|
"electron-devtools-installer": "^2.2.4",
|
||||||
"electron-store": "^5.0.0",
|
"electron-store": "^5.0.0",
|
||||||
"eslint": "^6.3.0",
|
"eslint": "^6.5.1",
|
||||||
"eslint-config-prettier": "^6.2.0",
|
"eslint-config-prettier": "^6.4.0",
|
||||||
"eslint-plugin-react": "^7.14.3",
|
"eslint-plugin-react": "^7.16.0",
|
||||||
"file-loader": "^4.2.0",
|
"file-loader": "^4.2.0",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
|
"identity-obj-proxy": "^3.0.0",
|
||||||
|
"jest": "^24.9.0",
|
||||||
"mini-css-extract-plugin": "^0.8.0",
|
"mini-css-extract-plugin": "^0.8.0",
|
||||||
"prettier": "^1.18.2",
|
"prettier": "^1.18.2",
|
||||||
"prettier-stylelint": "^0.4.2",
|
"prettier-stylelint": "^0.4.2",
|
||||||
"react": "^16.9.0",
|
"react": "^16.10.2",
|
||||||
"react-dom": "^16.9.0",
|
"react-dom": "^16.10.2",
|
||||||
"react-pose": "^4.0.8",
|
"react-pose": "^4.0.8",
|
||||||
"release-it": "^12.3.6",
|
"release-it": "^12.4.2",
|
||||||
"style-loader": "^1.0.0",
|
"style-loader": "^1.0.0",
|
||||||
"stylelint": "^11.0.0",
|
"stylelint": "^11.0.0",
|
||||||
"stylelint-config-css-modules": "^1.4.0",
|
"stylelint-config-css-modules": "^1.5.0",
|
||||||
"stylelint-config-standard": "^19.0.0",
|
"stylelint-config-standard": "^19.0.0",
|
||||||
"webpack": "^4.39.3",
|
"webpack": "^4.41.0",
|
||||||
"webpack-cli": "^3.3.8",
|
"webpack-cli": "^3.3.9",
|
||||||
"webpack-dev-server": "^3.8.0"
|
"webpack-dev-server": "^3.8.2"
|
||||||
},
|
},
|
||||||
"browserslist": "electron >= 6.0",
|
"browserslist": "electron >= 6.0",
|
||||||
"build": {
|
"build": {
|
||||||
@ -115,5 +124,22 @@
|
|||||||
"npm": {
|
"npm": {
|
||||||
"publish": false
|
"publish": false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"jest": {
|
||||||
|
"rootDir": "src/renderer",
|
||||||
|
"transform": {
|
||||||
|
"^.+\\.jsx?$": "babel-jest"
|
||||||
|
},
|
||||||
|
"moduleNameMapper": {
|
||||||
|
".+\\.(css|styl|less|sass|scss)$": "identity-obj-proxy",
|
||||||
|
".+\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/jest/__mocks__/file-mock.js",
|
||||||
|
"\\.svg": "<rootDir>/jest/__mocks__/svgr-mock.js"
|
||||||
|
},
|
||||||
|
"testURL": "http://localhost",
|
||||||
|
"setupFilesAfterEnv": [
|
||||||
|
"<rootDir>/jest/setup-test-env.js"
|
||||||
|
],
|
||||||
|
"runner": "@jest-runner/electron",
|
||||||
|
"testEnvironment": "@jest-runner/electron/environment"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { PureComponent } from 'react'
|
import React, { useEffect } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import {
|
import {
|
||||||
Router,
|
Router,
|
||||||
@ -44,24 +44,22 @@ PosedRouter.propTypes = {
|
|||||||
children: PropTypes.any.isRequired
|
children: PropTypes.any.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class App extends PureComponent {
|
export default function App() {
|
||||||
componentDidMount() {
|
useEffect(() => {
|
||||||
ipcRenderer.on('goTo', (evt, route) => {
|
ipcRenderer.on('goTo', (evt, route) => {
|
||||||
navigate(route)
|
navigate(route)
|
||||||
})
|
})
|
||||||
}
|
}, [])
|
||||||
|
|
||||||
render() {
|
return (
|
||||||
return (
|
<>
|
||||||
<>
|
{process.platform === 'darwin' && <Titlebar />}
|
||||||
{process.platform === 'darwin' && <Titlebar />}
|
<div className={styles.app}>
|
||||||
<div className={styles.app}>
|
<PosedRouter>
|
||||||
<PosedRouter>
|
<Home path="/" default />
|
||||||
<Home path="/" default />
|
<Preferences path="/preferences" />
|
||||||
<Preferences path="/preferences" />
|
</PosedRouter>
|
||||||
</PosedRouter>
|
</div>
|
||||||
</div>
|
</>
|
||||||
</>
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
15
src/renderer/App.test.jsx
Normal file
15
src/renderer/App.test.jsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { render } from '@testing-library/react'
|
||||||
|
import AppProvider from './store/AppProvider'
|
||||||
|
import App from './App'
|
||||||
|
|
||||||
|
describe('App', () => {
|
||||||
|
it('renders correctly', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<AppProvider>
|
||||||
|
<App />
|
||||||
|
</AppProvider>
|
||||||
|
)
|
||||||
|
expect(container.firstChild).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
@ -22,15 +22,3 @@ export const fadeIn = {
|
|||||||
transition: { duration: 100 }
|
transition: { duration: 100 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const characterAnimation = {
|
|
||||||
exit: { opacity: 0, y: 10 },
|
|
||||||
enter: {
|
|
||||||
opacity: 1,
|
|
||||||
y: 0,
|
|
||||||
transition: ({ charInWordIndex }) => ({
|
|
||||||
type: 'spring',
|
|
||||||
delay: charInWordIndex * 20
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
34
src/renderer/jest/__fixtures__/context.js
Normal file
34
src/renderer/jest/__fixtures__/context.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
const prices = new Map()
|
||||||
|
prices.set('ocean', 1)
|
||||||
|
prices.set('eur', 1)
|
||||||
|
prices.set('usd', 1)
|
||||||
|
prices.set('btc', 1)
|
||||||
|
prices.set('eth', 1)
|
||||||
|
|
||||||
|
const priceChanges = {
|
||||||
|
eur: -14.051056318029353,
|
||||||
|
usd: -14.051056318029268,
|
||||||
|
btc: -14.761248039421442,
|
||||||
|
eth: -17.538786176215627
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
accentColor: '#0a5fff',
|
||||||
|
accounts: [
|
||||||
|
{
|
||||||
|
address: '0xxxxxxxxxxxxxxxxxxx',
|
||||||
|
balance: {
|
||||||
|
ocean: 10000,
|
||||||
|
btc: 1.9,
|
||||||
|
eth: 10000,
|
||||||
|
eur: 10000,
|
||||||
|
usd: 10000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
currency: 'ocean',
|
||||||
|
isLoading: false,
|
||||||
|
needsConfig: false,
|
||||||
|
prices,
|
||||||
|
priceChanges
|
||||||
|
}
|
1
src/renderer/jest/__mocks__/file-mock.js
Normal file
1
src/renderer/jest/__mocks__/file-mock.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
module.exports = 'div'
|
1
src/renderer/jest/__mocks__/svgr-mock.js
Normal file
1
src/renderer/jest/__mocks__/svgr-mock.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
module.exports = 'svg-mock'
|
1
src/renderer/jest/setup-test-env.js
Normal file
1
src/renderer/jest/setup-test-env.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
import '@testing-library/jest-dom/extend-expect'
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useContext } from 'react'
|
import React, { useContext } from 'react'
|
||||||
import { Link } from '@reach/router'
|
import { Link } from '@reach/router'
|
||||||
import { AppContext } from '../store/createContext'
|
import { AppContext } from '../../store/createContext'
|
||||||
import IconRocket from '../images/rocket.svg'
|
import IconRocket from '../../images/rocket.svg'
|
||||||
import styles from './Welcome.module.css'
|
import styles from './Welcome.module.css'
|
||||||
|
|
||||||
const Welcome = () => {
|
const Welcome = () => {
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useContext } from 'react'
|
import React, { useContext } from 'react'
|
||||||
import { Link } from '@reach/router'
|
import { Link } from '@reach/router'
|
||||||
import { AppContext } from '../../store/createContext'
|
import { AppContext } from '../../store/createContext'
|
||||||
import Welcome from '../../components/Welcome'
|
import Welcome from './Welcome'
|
||||||
import Spinner from '../../components/Spinner'
|
import Spinner from '../../components/Spinner'
|
||||||
import Divider from '../../components/Divider'
|
import Divider from '../../components/Divider'
|
||||||
import Total from './Total'
|
import Total from './Total'
|
||||||
@ -10,7 +10,7 @@ import Accounts from './Accounts'
|
|||||||
import IconCog from '../../images/cog.svg'
|
import IconCog from '../../images/cog.svg'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
|
|
||||||
const Home = () => {
|
export default function Home() {
|
||||||
const { isLoading, needsConfig } = useContext(AppContext)
|
const { isLoading, needsConfig } = useContext(AppContext)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -37,5 +37,3 @@ const Home = () => {
|
|||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Home
|
|
||||||
|
28
src/renderer/screens/Home/index.test.jsx
Normal file
28
src/renderer/screens/Home/index.test.jsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { render, fireEvent } from '@testing-library/react'
|
||||||
|
import { AppContext } from '../../store/createContext'
|
||||||
|
import context from '../../jest/__fixtures__/context'
|
||||||
|
import Home from '.'
|
||||||
|
|
||||||
|
describe('Home', () => {
|
||||||
|
it('renders correctly', () => {
|
||||||
|
const { container, getByText } = render(
|
||||||
|
<AppContext.Provider value={context}>
|
||||||
|
<Home />
|
||||||
|
</AppContext.Provider>
|
||||||
|
)
|
||||||
|
expect(container.firstChild).toBeInTheDocument()
|
||||||
|
fireEvent.click(getByText(/Ξ/))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders Welcome without config', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<AppContext.Provider value={{ ...context, needsConfig: true }}>
|
||||||
|
<Home />
|
||||||
|
</AppContext.Provider>
|
||||||
|
)
|
||||||
|
expect(container.firstChild).toHaveTextContent(
|
||||||
|
'Add your first address to get started.'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
@ -2,25 +2,32 @@ import React from 'react'
|
|||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import styles from './New.module.css'
|
import styles from './New.module.css'
|
||||||
|
|
||||||
const New = ({ input, handleInputChange, handleSave, accentColor }) => (
|
export default function New({
|
||||||
<li>
|
input,
|
||||||
<input
|
handleInputChange,
|
||||||
type="text"
|
handleSave,
|
||||||
placeholder="0xxxxxxxx"
|
accentColor
|
||||||
value={input}
|
}) {
|
||||||
onChange={e => handleInputChange(e)}
|
return (
|
||||||
className={styles.input}
|
<li>
|
||||||
/>
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="0xxxxxxxx"
|
||||||
|
value={input}
|
||||||
|
onChange={e => handleInputChange(e)}
|
||||||
|
className={styles.input}
|
||||||
|
/>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
onClick={e => handleSave(e)}
|
onClick={e => handleSave(e)}
|
||||||
style={{ color: accentColor }}
|
style={{ color: accentColor }}
|
||||||
>
|
>
|
||||||
Add
|
Add
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
New.propTypes = {
|
New.propTypes = {
|
||||||
input: PropTypes.string.isRequired,
|
input: PropTypes.string.isRequired,
|
||||||
@ -28,5 +35,3 @@ New.propTypes = {
|
|||||||
handleSave: PropTypes.func.isRequired,
|
handleSave: PropTypes.func.isRequired,
|
||||||
accentColor: PropTypes.string.isRequired
|
accentColor: PropTypes.string.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
export default New
|
|
||||||
|
@ -5,36 +5,40 @@ import posed, { PoseGroup } from 'react-pose'
|
|||||||
import { fadeIn } from '../../../components/Animations'
|
import { fadeIn } from '../../../components/Animations'
|
||||||
import styles from './Saved.module.css'
|
import styles from './Saved.module.css'
|
||||||
|
|
||||||
const Item = posed.li(fadeIn)
|
export default function Saved({ accounts, handleDelete }) {
|
||||||
|
const Item = posed.li(fadeIn)
|
||||||
|
|
||||||
const Saved = ({ accounts, handleDelete }) => (
|
return (
|
||||||
<PoseGroup>
|
<PoseGroup>
|
||||||
{accounts.map(account => {
|
{accounts.map(account => {
|
||||||
const identicon = account && toDataUrl(account)
|
const identicon = toDataUrl(account)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Item key={account}>
|
<Item key={account}>
|
||||||
<div>
|
<div>
|
||||||
<img className={styles.identicon} src={identicon} alt="Blockies" />
|
<img
|
||||||
{account}
|
className={styles.identicon}
|
||||||
</div>
|
src={identicon}
|
||||||
|
alt="Blockies"
|
||||||
|
/>
|
||||||
|
{account}
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className={styles.delete}
|
className={styles.delete}
|
||||||
onClick={e => handleDelete(e, account)}
|
onClick={e => handleDelete(e, account)}
|
||||||
title="Remove account"
|
title="Remove account"
|
||||||
>
|
>
|
||||||
×
|
×
|
||||||
</button>
|
</button>
|
||||||
</Item>
|
</Item>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</PoseGroup>
|
</PoseGroup>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Saved.propTypes = {
|
Saved.propTypes = {
|
||||||
accounts: PropTypes.array.isRequired,
|
accounts: PropTypes.array.isRequired,
|
||||||
handleDelete: PropTypes.func.isRequired
|
handleDelete: PropTypes.func.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Saved
|
|
||||||
|
50
src/renderer/screens/Preferences/Accounts/index.test.jsx
Normal file
50
src/renderer/screens/Preferences/Accounts/index.test.jsx
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { render, fireEvent } from '@testing-library/react'
|
||||||
|
import { AppContext } from '../../../store/createContext'
|
||||||
|
import { StateMock } from '@react-mock/state'
|
||||||
|
import Accounts from '.'
|
||||||
|
|
||||||
|
describe('Accounts', () => {
|
||||||
|
const ui = (
|
||||||
|
<AppContext.Provider value={{ accentColor: '#0a5fff' }}>
|
||||||
|
<StateMock state={{ accounts: ['xxx'], input: '', error: '' }}>
|
||||||
|
<Accounts />
|
||||||
|
</StateMock>
|
||||||
|
</AppContext.Provider>
|
||||||
|
)
|
||||||
|
|
||||||
|
it('renders correctly', () => {
|
||||||
|
const { container } = render(ui)
|
||||||
|
expect(container.firstChild).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Address can be removed', () => {
|
||||||
|
const { getByTitle } = render(ui)
|
||||||
|
fireEvent.click(getByTitle('Remove account'))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('New address can be added', () => {
|
||||||
|
const { getByPlaceholderText, getByText } = render(ui)
|
||||||
|
|
||||||
|
// error: empty
|
||||||
|
fireEvent.click(getByText('Add'))
|
||||||
|
|
||||||
|
// success
|
||||||
|
fireEvent.change(getByPlaceholderText('0xxxxxxxx'), {
|
||||||
|
target: { value: '0x139361162Fb034fa021d347848F0B1c593D1f53C' }
|
||||||
|
})
|
||||||
|
fireEvent.click(getByText('Add'))
|
||||||
|
|
||||||
|
// error: duplicate
|
||||||
|
fireEvent.change(getByPlaceholderText('0xxxxxxxx'), {
|
||||||
|
target: { value: '0x139361162Fb034fa021d347848F0B1c593D1f53C' }
|
||||||
|
})
|
||||||
|
fireEvent.click(getByText('Add'))
|
||||||
|
|
||||||
|
// error: not an ETH address
|
||||||
|
fireEvent.change(getByPlaceholderText('0xxxxxxxx'), {
|
||||||
|
target: { value: '0x000' }
|
||||||
|
})
|
||||||
|
fireEvent.click(getByText('Add'))
|
||||||
|
})
|
||||||
|
})
|
15
src/renderer/screens/Preferences/index.test.jsx
Normal file
15
src/renderer/screens/Preferences/index.test.jsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { render } from '@testing-library/react'
|
||||||
|
import { AppContext } from '../../store/createContext'
|
||||||
|
import Preferences from '.'
|
||||||
|
|
||||||
|
describe('Preferences', () => {
|
||||||
|
it('renders correctly', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<AppContext.Provider value={{ accentColor: '#0a5fff' }}>
|
||||||
|
<Preferences />
|
||||||
|
</AppContext.Provider>
|
||||||
|
)
|
||||||
|
expect(container.firstChild).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user