Skip to content
This repository has been archived by the owner on Apr 15, 2019. It is now read-only.

Fix issues in forging - Closes #618 #630

Merged
merged 7 commits into from
Aug 28, 2017
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions src/components/forging/delegateStats.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@ const DelegateStats = props => (
<div className={`${grid['col-xs-12']} ${grid['col-sm-4']}`} key={cardItem.key}>
<Card className={style.grayCard}>
<CardText>
<div className={grid['col-xs-12']}>
<div className={`${grid.row} ${grid['between-xs']}`}>
<div className={style.circularProgressTitle}> {cardItem.label} </div>
<CircularProgressbar
percentage={cardItem.percentageTransform(props.delegate[cardItem.key])}
textForPercentage={cardItem.textForPercentage.bind(props.delegate[cardItem.key])}/>
<div className={grid['col-xs-12']}>
<div className={`${grid.row} ${grid['between-xs']}`}>
<div className={style.circularProgressTitle}> {cardItem.label} </div>
<CircularProgressbar
percentage={cardItem.percentageTransform(props.delegate[cardItem.key])}
textForPercentage={
cardItem.textForPercentage.bind(null, props.delegate[cardItem.key])}/>
</div>
</div>
</div>
</CardText>
</Card>
</div>
Expand Down
43 changes: 23 additions & 20 deletions src/components/forging/forgedBlocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,29 @@ const ForgedBlocks = props => (
<CardTitle>
Forged Blocks
</CardTitle>
<div className={style.forgedBlocksTableWrapper}>
<Table selectable={false}>
<TableHead>
<TableCell>Block height</TableCell>
<TableCell>Block Id</TableCell>
<TableCell>Timestamp</TableCell>
<TableCell>Total fee</TableCell>
<TableCell>Reward</TableCell>
</TableHead>
{props.forgedBlocks.map((block, idx) => (
<TableRow key={idx}>
<TableCell><FormattedNumber val={block.height} /></TableCell>
<TableCell>{block.id}</TableCell>
<TableCell><TooltipTime label={block.timestamp} /></TableCell>
<TableCell><LiskAmount val={block.totalFee} /></TableCell>
<TableCell><LiskAmount val={block.reward} /></TableCell>
</TableRow>
))}
</Table>
</div>
{ props.forgedBlocks.length ?
<div className={style.forgedBlocksTableWrapper}>
<Table selectable={false}>
<TableHead>
<TableCell>Block height</TableCell>
<TableCell>Block Id</TableCell>
<TableCell>Timestamp</TableCell>
<TableCell>Total fee</TableCell>
<TableCell>Reward</TableCell>
</TableHead>
{props.forgedBlocks.map((block, idx) => (
<TableRow key={idx}>
<TableCell><FormattedNumber val={block.height} /></TableCell>
<TableCell>{block.id}</TableCell>
<TableCell><TooltipTime label={block.timestamp} /></TableCell>
<TableCell><LiskAmount val={block.totalFee} roundTo={2} /></TableCell>
<TableCell><LiskAmount val={block.reward} roundTo={2} /></TableCell>
</TableRow>
))}
</Table>
</div> :
<p className='hasPaddingRow empty-message'>You have not forged any blocks yet.</p>
}
</Card>
);

Expand Down
1 change: 1 addition & 0 deletions src/components/forging/forgingStats.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class ForgingStats extends React.Component {
<span className='title'> {cardObj.label} </span>
<span>
<LiskAmount val={this.props.statistics[cardObj.key]}
roundTo={2}
/> LSK
</span>
</div>
Expand Down
8 changes: 4 additions & 4 deletions src/components/forging/forgingStats.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,18 @@ describe('ForgingStats', () => {
});

it('should render Card component for Last 24 hours', () => {
expect(wrapper.find('Card').at(0).text().trim()).to.equal('Last 24 hours 0.00321317 LSK');
expect(wrapper.find('Card').at(0).text().trim()).to.equal('Last 24 hours 0 LSK');
});

it('should render Card component for Last 7 days', () => {
expect(wrapper.find('Card').at(1).text().trim()).to.equal('Last 7 days 32.13179124 LSK');
expect(wrapper.find('Card').at(1).text().trim()).to.equal('Last 7 days 32.13 LSK');
});

it('should render Card component for Last 30 days', () => {
expect(wrapper.find('Card').at(2).text().trim()).to.equal('Last 30 days 3,213.17912423 LSK');
expect(wrapper.find('Card').at(2).text().trim()).to.equal('Last 30 days 3,213.18 LSK');
});

it('should render Card component for Last 365 days', () => {
expect(wrapper.find('Card').at(3).text().trim()).to.equal('Last 365 days 321,317.91242342 LSK');
expect(wrapper.find('Card').at(3).text().trim()).to.equal('Last 365 days 321,317.91 LSK');
});
});
2 changes: 1 addition & 1 deletion src/components/forging/forgingTitle.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ForgingTitle extends React.Component {
{this.props.account.delegate.username}
</h2>
<span>
<LiskAmount val={this.props.statistics.total} /> LSK Earned
<LiskAmount val={this.props.statistics.total} roundTo={2} /> LSK Earned
</span>
</div>
</CardText>
Expand Down
13 changes: 11 additions & 2 deletions src/components/liskAmount/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@ import React from 'react';
import { fromRawLsk } from '../../utils/lsk';
import FormattedNumber from '../formattedNumber';

const LiskValue = props => (<FormattedNumber val={parseFloat(fromRawLsk(props.val))} />);
const roundTo = (value, places) => {
if (!places) {
return value;
}
const x = Math.pow(10, places);
return Math.round(value * x) / x;
};

export default LiskValue;
const LiskAmount = props => (<FormattedNumber val={
roundTo(parseFloat(fromRawLsk(props.val)), props.roundTo)} />);

export default LiskAmount;

7 changes: 7 additions & 0 deletions src/components/liskAmount/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,11 @@ describe('LiskAmount', () => {
const wrapper = mount(<LiskAmount val={inputValue} />);
expect(wrapper.text()).to.be.equal(expectedValue);
});

it('should round to props.roundTo decimal places', () => {
const inputValue = '12932689.64321' * normalizeNumber;
const expectedValue = '12,932,689.64';
const wrapper = mount(<LiskAmount val={inputValue} roundTo={2} />);
expect(wrapper.text()).to.be.equal(expectedValue);
});
});
9 changes: 9 additions & 0 deletions src/store/middlewares/account.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { accountUpdated } from '../../actions/account';
import { transactionsUpdated } from '../../actions/transactions';
import { activePeerUpdate } from '../../actions/peers';
import actionTypes from '../../constants/actions';
import { fetchAndUpdateForgedBlocks } from '../../actions/forging';

const updateAccountData = next => (store) => { // eslint-disable-line
const { peers, account } = store.getState();
Expand All @@ -15,6 +16,14 @@ const updateAccountData = next => (store) => { // eslint-disable-line
confirmed: response.transactions,
count: parseInt(response.count, 10),
})));
if (account.isDelegate) {
store.dispatch(fetchAndUpdateForgedBlocks({
activePeer: peers.data,
limit: 10,
offset: 0,
generatorPublicKey: account.publicKey,
}));
}
}
next(accountUpdated(result));
});
Expand Down
51 changes: 47 additions & 4 deletions src/store/middlewares/account.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,29 @@ import { spy, stub } from 'sinon';
import middleware from './account';
import * as accountApi from '../../utils/api/account';
import actionTypes from '../../constants/actions';
// import { fetchAndUpdateForgedBlocks } from '../../actions/forging';

describe('Account middleware', () => {
let store;
let next;
let state;

beforeEach(() => {
store = stub();
store.getState = () => ({
store.dispatch = spy();
state = {
peers: {
data: {},
},
account: {},
});
account: {
balance: 0,
},
};
next = spy();
});

it('should passes the action to next middleware', () => {
store.getState = () => (state);
const expectedAction = {
type: 'TEST_ACTION',
};
Expand All @@ -29,7 +35,8 @@ describe('Account middleware', () => {
});

it(`should call account API methods on ${actionTypes.metronomeBeat} action`, () => {
const stubGetAccount = stub(accountApi, 'getAccount').resolves(true);
store.getState = () => (state);
const stubGetAccount = stub(accountApi, 'getAccount').resolves({ balance: 0 });
const stubGetAccountStatus = stub(accountApi, 'getAccountStatus').resolves(true);

middleware(store)(next)({ type: actionTypes.metronomeBeat });
Expand All @@ -40,5 +47,41 @@ describe('Account middleware', () => {
stubGetAccount.restore();
stubGetAccountStatus.restore();
});

it(`should call transactions API methods on ${actionTypes.metronomeBeat} action if account.balance changes`, () => {
store.getState = () => (state);
const stubGetAccount = stub(accountApi, 'getAccount').resolves({ balance: 10e8 });
const stubTransactions = stub(accountApi, 'transactions').resolves(true);

middleware(store)(next)({ type: actionTypes.metronomeBeat });

expect(stubGetAccount).to.have.been.calledWith();
// TODO why next expect doesn't work despite it being called according to test coverage?
// expect(stubTransactions).to.have.been.calledWith();

stubGetAccount.restore();
stubTransactions.restore();
});

it(`should call store.dispatch(fetchAndUpdateForgedBlocks(...)) on ${actionTypes.metronomeBeat} action if account.balance changes and account.isDelegate`, () => {
state.account.isDelegate = true;
store.getState = () => (state);
const stubGetAccount = stub(accountApi, 'getAccount').resolves({ balance: 10e8 });
const stubGetAccountStatus = stub(accountApi, 'getAccountStatus').resolves(true);

middleware(store)(next)({ type: actionTypes.metronomeBeat });

expect(stubGetAccount).to.have.been.calledWith();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is not related to title.
The issue is, Actions that we create using Redux thunk don't return object. They return a function which accepts dispatch as argument. but you're using just like other actions.

Other than how you've used it, the actual issue is as described above it best called inside component class.

// TODO why next expect doesn't work despite it being called according to test coverage?
// expect(store.dispatch).to.have.been.calledWith(fetchAndUpdateForgedBlocks({
// activePeer: state.peers.data,
// limit: 10,
// offset: 0,
// generatorPublicKey: state.account.publicKey,
// }));

stubGetAccount.restore();
stubGetAccountStatus.restore();
});
});