Skip to content

Commit

Permalink
wallet: fix repair 0 bid and add unit test (#277)
Browse files Browse the repository at this point in the history
  • Loading branch information
chikeichan authored Nov 26, 2020
1 parent 2706351 commit 7a25873
Show file tree
Hide file tree
Showing 12 changed files with 1,711 additions and 50 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,4 @@ dll
.idea
*.iml
npm-debug.log.*
test-dist/
13 changes: 7 additions & 6 deletions app/pages/Auction/BidActionPanel/BidNow.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import SuccessModal from '../../../components/SuccessModal';
import Checkbox from '../../../components/Checkbox';
import * as nameActions from '../../../ducks/names';
import { showError, showSuccess } from '../../../ducks/notifications';
import {displayBalance, parseFloatValue, toBaseUnits} from '../../../utils/balances';
import {displayBalance, toBaseUnits} from '../../../utils/balances';
import * as logger from '../../../utils/logClient';
import { clientStub as aClientStub } from '../../../background/analytics/client';
import walletClient from '../../../utils/walletClient';
Expand Down Expand Up @@ -106,11 +106,12 @@ class BidNow extends Component {
};

processValue = (val, field) => {
const value = parseFloatValue(val);

if (value) {
this.setState({[field]: value});
}
const value = val.match(/[0-9]*\.?[0-9]{0,6}/g)[0];
if (Number.isNaN(parseFloat(value)))
return;
if (value * consensus.COIN > consensus.MAX_MONEY)
return;
this.setState({[field]: value});
};

render() {
Expand Down
2 changes: 1 addition & 1 deletion app/pages/Auction/BidActionPanel/Reveal.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ function getTotalBids(domain) {
for (const {bid} of domain.bids) {
if (bid.own) {
// This is our bid, but we don't know its value
if (!bid.value)
if (typeof bid.value === 'undefined')
return -1;

total += bid.value;
Expand Down
32 changes: 17 additions & 15 deletions app/pages/Auction/RepairBid.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,8 @@ import {consensus} from 'hsd/lib/protocol';
import walletClient from '../../utils/walletClient';
import * as names from '../../ducks/names';
import { showError } from '../../ducks/notifications';
import {parseFloatValue} from "../../utils/balances";

@connect(
() => ({}),
dispatch => ({
getNameInfo: tld => dispatch(names.getNameInfo(tld)),
showError: (message) => dispatch(showError(message)),
}),
)
export default class RepairBid extends Component {
export class RepairBid extends Component {
static propTypes = {
bid: PropTypes.object.isRequired,
getNameInfo: PropTypes.func.isRequired,
Expand All @@ -28,7 +20,7 @@ export default class RepairBid extends Component {
value: "",
isCorrect: false,
};
}
};

renderRepairableBid() {
return (
Expand Down Expand Up @@ -57,12 +49,14 @@ export default class RepairBid extends Component {
}

processValue = async (val) => {
const value = parseFloatValue(val);
const value = val.match(/[0-9]*\.?[0-9]{0,6}/g)[0];
this.setState({value: value});
const parsed = parseFloat(value);

if (value) {
this.setState({value: value});
return this.verifyBid(value);
}
if (val === "" || Number.isNaN(parsed) || parsed * consensus.COIN > consensus.MAX_MONEY)
return;

return this.verifyBid(parsed);
};

async verifyBid(value) {
Expand Down Expand Up @@ -96,3 +90,11 @@ export default class RepairBid extends Component {
: this.renderRepairableBid();
}
}

export default connect(
() => ({}),
dispatch => ({
getNameInfo: tld => dispatch(names.getNameInfo(tld)),
showError: (message) => dispatch(showError(message)),
}),
)(RepairBid);
53 changes: 53 additions & 0 deletions app/pages/Auction/tests/RepairBid.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
const test = require('tape');
const sinon = require('sinon');
import {mount} from 'enzyme';
import {RepairBid} from "../RepairBid";
import {createMockStore} from "../../../utils/test-helpers";

test('<RepairBid>', async t => {
const getNameInfoStub = sinon.stub();
const showErrorStub = sinon.stub();
const store = createMockStore();
let calls = 0;
const wrapper = mount(
<RepairBid
bid={{
name: 'test',
from: 'ts1q8tlzrx9lq9an302cju5q6msjnr06564sd9fnj9'
}}
getNameInfo={getNameInfoStub}
showError={showErrorStub}
store={store}
/>,
);

const verifyBidSpy = sinon.stub(RepairBid.prototype, 'verifyBid');

const div = wrapper.find('div').at(0);
div.props().onClick();

wrapper.update();

testOneRepair('1234');
testOneRepair('0');

t.end();

function testOneRepair(text) {
const input = wrapper.find('input').at(0);
input.props().onChange({
target: {
value: `${text}`,
},
});

wrapper.update();

t.equal(
verifyBidSpy.getCall(calls++).args[0],
Number(text),
`it should submit verifyBid for ${text}`,
);
}
});
14 changes: 8 additions & 6 deletions app/pages/MyDomain/FinalizeWithPaymentModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { MiniModal } from '../../components/Modal/MiniModal';
import { clientStub as wClientStub } from '../../background/wallet/client';
import { finalizeWithPayment } from '../../ducks/names';
import { connect } from 'react-redux';
import {consensus} from 'hsd/lib/protocol';
import { waitForPassphrase } from '../../ducks/walletActions';
import {parseFloatValue} from "../../utils/balances";

const wallet = wClientStub(() => require('electron').ipcRenderer);

Expand Down Expand Up @@ -76,11 +76,13 @@ export class FinalizeWithPaymentModal extends Component {
}

processValue = (val) => {
const value = parseFloatValue(val);
if (value) {
this.setState({price: value});
}
};
const value = val.match(/[0-9]*\.?[0-9]{0,6}/g)[0];
if (Number.isNaN(parseFloat(value)))
return;
if (value * consensus.COIN > consensus.MAX_MONEY)
return;
this.setState({price: value});
}

renderForm() {
const isValid = !!this.state.price && (
Expand Down
10 changes: 0 additions & 10 deletions app/utils/balances.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,3 @@ export function toBaseUnits(bal) {
export function toDisplayUnits(bal) {
return new BigNumber(bal).div(UNIT_DIVISOR).toFixed(DECIMALS);
}

export function parseFloatValue(val) {
const value = val.match(/[0-9]*\.?[0-9]{0,6}/g)[0];
const parsed = parseFloat(value);
if (Number.isNaN(parsed))
return;
if (value * consensus.COIN > consensus.MAX_MONEY)
return;
return parsed;
}
9 changes: 9 additions & 0 deletions app/utils/test-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import sinon from 'sinon';

export const createMockStore = (initialState = {}) => {
return {
getState: () => initialState,
subscribe: sinon.stub(),
dispatch: sinon.stub(),
}
};
160 changes: 160 additions & 0 deletions configs/webpack.config.test.babel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import webpack from "webpack";

const path = require('path');

module.exports = {
devtool: 'inline-source-map',

mode: 'development',
target: 'electron-renderer',
entry: [
'./unit.js',
],
output: {
path: path.resolve(__dirname, '../test-dist'),
filename: 'test.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
},
{
test: /\.global\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /^((?!\.global).)*\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true,
sourceMap: true,
importLoaders: 1,
localIdentName: '[name]__[local]__[hash:base64:5]'
}
}
]
},
// SASS support - compile all .global.scss files and pipe it to style.css
{
test: /\.scss$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader'
}
]
},
// WOFF Font
{
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
},
// WOFF2 Font
{
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
},
// TTF Font
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream'
}
}
},
// EOT Font
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader'
},
// SVG Font
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'image/svg+xml'
}
}
},
// Common Image Formats
{
test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/,
use: 'url-loader'
}
]
},

plugins: [
/**
* Create global constants which can be configured at compile time.
*
* Useful for allowing different behaviour between development builds and
* release builds
*
* NODE_ENV should be production so that modules do not perform certain
* development checks
*
* By default, use 'development' as NODE_ENV. This can be overriden with
* 'staging', for example, by changing the ENV variables in the npm scripts
*/
new webpack.EnvironmentPlugin({
NODE_ENV: 'development'
}),
new webpack.LoaderOptionsPlugin({
debug: true
})
],

node: {
__dirname: false,
__filename: false
},
};
Loading

0 comments on commit 7a25873

Please sign in to comment.