Skip to content

Commit

Permalink
Refactor more functions from account middleware to account action and…
Browse files Browse the repository at this point in the history
… update tests
  • Loading branch information
Gina Contrino committed Jun 11, 2018
1 parent a498f45 commit 9b0f375
Show file tree
Hide file tree
Showing 8 changed files with 301 additions and 150 deletions.
47 changes: 45 additions & 2 deletions src/actions/account.js
Expand Up @@ -2,9 +2,10 @@ import i18next from 'i18next';
import actionTypes from '../constants/actions';
import { setSecondPassphrase, getAccount } from '../utils/api/account';
import { registerDelegate, getDelegate, getVotes, getVoters } from '../utils/api/delegate';
import { loadTransactionsFinish } from './transactions';
import { loadTransactionsFinish, transactionsUpdated } from './transactions';
import { delegateRegisteredFailure } from './delegate';
import { errorAlertDialogDisplayed } from './dialog';
import { activePeerUpdate } from './peers';
import Fees from '../constants/fees';
import transactionTypes from '../constants/transactionTypes';

Expand Down Expand Up @@ -159,7 +160,6 @@ export const loadAccount = ({
transactionsResponse,
isSameAccount,
}) =>

(dispatch) => {
getAccount(activePeer, address)
.then((response) => {
Expand All @@ -184,3 +184,46 @@ export const loadAccount = ({
dispatch(loadTransactionsFinish(accountDataUpdated));
});
};

export const updateTransactionsIfNeeded = ({ transactions, activePeer, account }, windowFocus) =>
(dispatch) => {
const hasRecentTransactions = txs => (
txs.confirmed.filter(tx => tx.confirmations < 1000).length !== 0 ||
txs.pending.length !== 0
);

if (windowFocus || !hasRecentTransactions(transactions)) {
const { filter } = transactions;
const address = transactions.account ? transactions.account.address : account.address;

dispatch(transactionsUpdated({
pendingTransactions: transactions.pending,
activePeer,
address,
limit: 25,
filter,
}));
}
};

export const accountDataUpdated = ({
peers, account, windowIsFocused, transactions,
}) =>
(dispatch) => {
getAccount(peers.data, account.address).then((result) => {
if (result.balance !== account.balance) {
dispatch(updateTransactionsIfNeeded(
{
transactions,
activePeer: peers.data,
account,
},
!windowIsFocused,
));
}
dispatch(accountUpdated(result));
dispatch(activePeerUpdate({ online: true }));
}).catch((res) => {
dispatch(activePeerUpdate({ online: false, code: res.error.code }));
});
};
179 changes: 172 additions & 7 deletions src/actions/account.test.js
@@ -1,5 +1,5 @@
import { expect } from 'chai';
import sinon from 'sinon';
import { spy, stub } from 'sinon';
import actionTypes from '../constants/actions';
import {
accountUpdated,
Expand All @@ -9,6 +9,9 @@ import {
removePassphrase,
passphraseUsed,
loadDelegate,
loadAccount,
accountDataUpdated,
updateTransactionsIfNeeded,
} from './account';
import { errorAlertDialogDisplayed } from './dialog';
import { delegateRegisteredFailure } from './delegate';
Expand All @@ -18,6 +21,8 @@ import Fees from '../constants/fees';
import transactionTypes from '../constants/transactionTypes';
import networks from '../constants/networks';
import accounts from '../../test/constants/accounts';
import * as peersActions from './peers';
import * as transactionsActions from './transactions';

describe('actions: account', () => {
describe('accountUpdated', () => {
Expand Down Expand Up @@ -58,8 +63,8 @@ describe('actions: account', () => {
let dispatch;

beforeEach(() => {
accountApiMock = sinon.stub(accountApi, 'setSecondPassphrase');
dispatch = sinon.spy();
accountApiMock = stub(accountApi, 'setSecondPassphrase');
dispatch = spy();
});

afterEach(() => {
Expand Down Expand Up @@ -119,8 +124,8 @@ describe('actions: account', () => {
let dispatch;

beforeEach(() => {
delegateApiMock = sinon.stub(delegateApi, 'registerDelegate');
dispatch = sinon.spy();
delegateApiMock = stub(delegateApi, 'registerDelegate');
dispatch = spy();
});

afterEach(() => {
Expand Down Expand Up @@ -175,8 +180,8 @@ describe('actions: account', () => {
const actionFunction = loadDelegate(data);

beforeEach(() => {
delegateApiMock = sinon.stub(delegateApi, 'getDelegate');
dispatch = sinon.spy();
delegateApiMock = stub(delegateApi, 'getDelegate');
dispatch = spy();
});

afterEach(() => {
Expand Down Expand Up @@ -212,4 +217,164 @@ describe('actions: account', () => {
expect(removePassphrase(data)).to.be.deep.equal(expectedAction);
});
});

describe('loadAccount', () => {
let getAccountStub;
let transactionsActionsStub;

const dispatch = spy();

beforeEach(() => {
getAccountStub = stub(accountApi, 'getAccount').returnsPromise();
transactionsActionsStub = spy(transactionsActions, 'loadTransactionsFinish');
});

afterEach(() => {
getAccountStub.restore();
transactionsActionsStub.restore();
});

it('should finish transactions load and load delegate if not own account', () => {
getAccountStub.resolves({
balance: 10e8,
publicKey: accounts.genesis.publicKey,
isDelegate: false,
});

const data = {
activePeer: {},
address: accounts.genesis.address,
transactionsResponse: { count: 0, transactions: [] },
isSameAccount: false,
};

loadAccount(data)(dispatch);
expect(transactionsActionsStub).to.have.been.calledWith({
confirmed: [],
count: 0,
balance: 10e8,
address: accounts.genesis.address,
});
});

it('should finish transactions load and should not load delegate if own account', () => {
getAccountStub.resolves({
balance: 10e8,
publicKey: accounts.genesis.publicKey,
isDelegate: true,
delegate: 'delegate information',
});

const data = {
activePeer: {},
address: accounts.genesis.address,
transactionsResponse: { count: 0, transactions: [] },
isSameAccount: true,
};

loadAccount(data)(dispatch);
expect(transactionsActionsStub).to.have.been.calledWith({
confirmed: [],
count: 0,
balance: 10e8,
address: accounts.genesis.address,
delegate: 'delegate information',
});
});
});

describe('accountDataUpdated', () => {
let peersActionsStub;
let getAccountStub;
let transactionsActionsStub;

const dispatch = spy();

beforeEach(() => {
peersActionsStub = spy(peersActions, 'activePeerUpdate');
getAccountStub = stub(accountApi, 'getAccount').returnsPromise();
transactionsActionsStub = spy(transactionsActions, 'transactionsUpdated');
});

afterEach(() => {
getAccountStub.restore();
peersActionsStub.restore();
transactionsActionsStub.restore();
});

it(`should call account API methods on ${actionTypes.newBlockCreated} action when online`, () => {
getAccountStub.resolves({ balance: 10e8 });

const data = {
windowIsFocused: false,
peers: { data: {} },
transactions: {
pending: [{
id: 12498250891724098,
}],
confirmed: [],
account: { address: 'test_address', balance: 0 },
},
account: { address: accounts.genesis.address, balance: 0 },
};

accountDataUpdated(data)(dispatch);
expect(dispatch).to.have.callCount(3);
expect(peersActionsStub).to.have.not.been.calledWith({ online: false, code: 'EUNAVAILABLE' });
});

it(`should call account API methods on ${actionTypes.newBlockCreated} action when offline`, () => {
getAccountStub.rejects({ error: { code: 'EUNAVAILABLE' } });

const data = {
windowIsFocused: true,
peers: { data: {} },
transactions: {
pending: [{ id: 12498250891724098 }],
confirmed: [],
account: { address: 'test_address', balance: 0 },
},
account: { address: accounts.genesis.address },
};

accountDataUpdated(data)(dispatch);
expect(peersActionsStub).to.have.been.calledWith({ online: false, code: 'EUNAVAILABLE' });
});
});

describe('updateTransactionsIfNeeded', () => {
let transactionsActionsStub;

const dispatch = spy();

beforeEach(() => {
transactionsActionsStub = spy(transactionsActions, 'transactionsUpdated');
});

afterEach(() => {
transactionsActionsStub.restore();
});

it('should update transactions when window is in focus', () => {
const data = {
activePeer: {},
transactions: { confirmed: [{ confirmations: 10 }], pending: [] },
account: { address: accounts.genesis.address },
};

updateTransactionsIfNeeded(data, true)(dispatch);
expect(transactionsActionsStub).to.have.been.calledWith();
});

it('should update transactions when there are no recent transactions', () => {
const data = {
activePeer: {},
transactions: { confirmed: [{ confirmations: 10000 }], pending: [] },
account: { address: accounts.genesis.address },
};

updateTransactionsIfNeeded(data, false)(dispatch);
expect(transactionsActionsStub).to.have.been.calledWith();
});
});
});
8 changes: 6 additions & 2 deletions src/actions/search.js
Expand Up @@ -63,7 +63,9 @@ export const searchTransactions = ({
}) =>
(dispatch) => {
if (showLoading) loadingStarted(actionTypes.searchTransactions);
getTransactions({ activePeer, address, limit, filter })
getTransactions({
activePeer, address, limit, filter,
})
.then((transactionsResponse) => {
dispatch({
data: {
Expand All @@ -82,7 +84,9 @@ export const searchMoreTransactions = ({
activePeer, address, limit, offset, filter,
}) =>
(dispatch) => {
getTransactions({ activePeer, address, limit, offset, filter })
getTransactions({
activePeer, address, limit, offset, filter,
})
.then((transactionsResponse) => {
dispatch({
data: {
Expand Down
20 changes: 15 additions & 5 deletions src/actions/transactions.js
Expand Up @@ -72,9 +72,13 @@ export const loadTransactions = ({ activePeer, publicKey, address }) =>
});
};

export const transactionsRequested = ({ activePeer, address, limit, offset, filter }) =>
export const transactionsRequested = ({
activePeer, address, limit, offset, filter,
}) =>
(dispatch) => {
getTransactions({ activePeer, address, limit, offset, filter })
getTransactions({
activePeer, address, limit, offset, filter,
})
.then((response) => {
dispatch({
data: {
Expand Down Expand Up @@ -144,9 +148,13 @@ export const loadTransaction = ({ activePeer, id }) =>
});
};

export const transactionsUpdated = ({ activePeer, address, limit, filter, pendingTransactions }) =>
export const transactionsUpdated = ({
activePeer, address, limit, filter, pendingTransactions,
}) =>
(dispatch) => {
getTransactions({ activePeer, address, limit, filter })
getTransactions({
activePeer, address, limit, filter,
})
.then((response) => {
dispatch({
data: {
Expand All @@ -165,7 +173,9 @@ export const transactionsUpdated = ({ activePeer, address, limit, filter, pendin
});
};

export const sent = ({ activePeer, account, recipientId, amount, passphrase, secondPassphrase }) =>
export const sent = ({
activePeer, account, recipientId, amount, passphrase, secondPassphrase,
}) =>
(dispatch) => {
send(activePeer, recipientId, toRawLsk(amount), passphrase, secondPassphrase)
.then((data) => {
Expand Down
2 changes: 1 addition & 1 deletion src/actions/transactions.test.js
Expand Up @@ -32,7 +32,7 @@ describe('actions: transactions', () => {
transactionsApiMock.restore();
});

it('should dispatch transactionsLoaded action if resolved', () => {
it('should dispatch transactionsUpdated action if resolved', () => {
transactionsApiMock.returnsPromise().resolves({ transactions: [], count: '0' });
const expectedAction = {
count: 0,
Expand Down

0 comments on commit 9b0f375

Please sign in to comment.