Redux Reducer Tests (#390)

* set return type in resetWallet action creator

* update config reducer test

* update generateWallet reducer test

* update swap reducer test

* update wallet reducer test

* create customTokens reducer test

* create deterministicWallets reducer test

* create ens reducer test

* create notifications reducer test

* add crypto compare success/fail actions

* add rates reducer test

* remove unnecessary comments

* remove more comments

* remove duplicate import

* update wallet reducer test to use BN

* update dWallet reducer test to use BN

* update wallet reducer tests

* update rates reducer tests
This commit is contained in:
skubakdj 2017-11-17 16:12:27 -05:00 committed by Daniel Ternyak
parent 159000caf8
commit c31490c8b4
11 changed files with 439 additions and 16 deletions

View File

@ -1,6 +1,6 @@
import * as interfaces from './actionTypes';
import { TypeKeys } from './constants';
import { fetchRates } from './actionPayloads';
import { fetchRates, CCResponse } from './actionPayloads';
export type TFetchCCRates = typeof fetchCCRates;
export function fetchCCRates(symbol: string): interfaces.FetchCCRates {
@ -9,3 +9,20 @@ export function fetchCCRates(symbol: string): interfaces.FetchCCRates {
payload: fetchRates(symbol)
};
}
export type TFetchCCRatesSucceeded = typeof fetchCCRatesSucceeded;
export function fetchCCRatesSucceeded(
payload: CCResponse
): interfaces.FetchCCRatesSucceeded {
return {
type: TypeKeys.RATES_FETCH_CC_SUCCEEDED,
payload
};
}
export type TFetchCCRatesFailed = typeof fetchCCRatesFailed;
export function fetchCCRatesFailed(): interfaces.FetchCCRatesFailed {
return {
type: TypeKeys.RATES_FETCH_CC_FAILED
};
}

View File

@ -120,7 +120,7 @@ export function broadCastTxFailed(
}
export type TResetWallet = typeof resetWallet;
export function resetWallet() {
export function resetWallet(): types.ResetWalletAction {
return {
type: TypeKeys.WALLET_RESET
};

View File

@ -28,4 +28,52 @@ describe('config reducer', () => {
gasPriceGwei: gasPrice
});
});
it('should handle CONFIG_TOGGLE_OFFLINE', () => {
const offlineState = {
...INITIAL_STATE,
offline: true
};
const onlineState = {
...INITIAL_STATE,
offline: false
};
expect(config(offlineState, configActions.toggleOfflineConfig())).toEqual({
...offlineState,
offline: false
});
expect(config(onlineState, configActions.toggleOfflineConfig())).toEqual({
...onlineState,
offline: true
});
});
it('should handle CONFIG_FORCE_OFFLINE', () => {
const forceOfflineTrue = {
...INITIAL_STATE,
forceOffline: true
};
const forceOfflineFalse = {
...INITIAL_STATE,
forceOffline: false
};
expect(
config(forceOfflineTrue, configActions.forceOfflineConfig())
).toEqual({
...forceOfflineTrue,
forceOffline: false
});
expect(
config(forceOfflineFalse, configActions.forceOfflineConfig())
).toEqual({
...forceOfflineFalse,
forceOffline: true
});
});
});

View File

@ -0,0 +1,37 @@
import { customTokens } from 'reducers/customTokens';
import { Token } from 'config/data';
import * as customTokensActions from 'actions/customTokens';
describe('customTokens reducer', () => {
const token1: Token = {
address: 'address',
symbol: 'OMG',
decimal: 16
};
const token2: Token = {
address: 'address',
symbol: 'ANT',
decimal: 16
};
it('should handle CUSTOM_TOKEN_ADD', () => {
expect(
customTokens(undefined, customTokensActions.addCustomToken(token1))
).toEqual([token1]);
});
it('should handle CUSTOM_TOKEN_REMOVE', () => {
const state1 = customTokens(
undefined,
customTokensActions.addCustomToken(token1)
);
const state2 = customTokens(
state1,
customTokensActions.addCustomToken(token2)
);
expect(
customTokens(state2, customTokensActions.removeCustomToken(token2.symbol))
).toEqual([token1]);
});
});

View File

@ -0,0 +1,81 @@
import {
deterministicWallets,
INITIAL_STATE
} from 'reducers/deterministicWallets';
import * as dWalletActions from 'actions/deterministicWallets';
import { TokenValue } from 'libs/units';
describe('deterministicWallets reducer', () => {
const tokenValues: dWalletActions.ITokenValues = {
OMG: {
value: TokenValue('0'),
decimal: 16
}
};
const wallet: dWalletActions.DeterministicWalletData = {
index: 0,
address: 'address',
value: TokenValue('0'),
tokenValues
};
it('should handle DW_SET_WALLETS', () => {
const wallets = [wallet];
expect(
deterministicWallets(
undefined,
dWalletActions.setDeterministicWallets(wallets)
)
).toEqual({
...INITIAL_STATE,
wallets
});
});
it('should handle DW_SET_DESIRED_TOKEN', () => {
const desiredToken = 'OMG';
expect(
deterministicWallets(
undefined,
dWalletActions.setDesiredToken(desiredToken)
)
).toEqual({
...INITIAL_STATE,
desiredToken
});
});
it('should handle DW_UPDATE_WALLET', () => {
const wallet1 = {
...wallet,
address: 'wallet1'
};
const wallet2 = {
...wallet,
address: 'wallet2'
};
const wallets = [wallet1, wallet2];
const state = deterministicWallets(
undefined,
dWalletActions.setDeterministicWallets(wallets)
);
const wallet2Update = {
...wallet,
index: 100,
address: 'wallet2',
value: TokenValue('100')
};
expect(
deterministicWallets(
state,
dWalletActions.updateDeterministicWallet(wallet2Update)
)
).toEqual({
...INITIAL_STATE,
wallets: [wallet1, wallet2Update]
});
});
});

15
spec/reducers/ens.spec.ts Normal file
View File

@ -0,0 +1,15 @@
import { ens, INITIAL_STATE } from 'reducers/ens';
import * as ensActions from 'actions/ens';
describe('customTokens reducer', () => {
it('should handle ENS_CACHE', () => {
const ensName = 'ensName';
const address = 'address';
expect(
ens(undefined, ensActions.cacheEnsAddress(ensName, address))
).toEqual({
...INITIAL_STATE,
[ensName]: address
});
});
});

View File

@ -1,7 +1,19 @@
import { generateWallet, INITIAL_STATE } from 'reducers/generateWallet';
import * as generateWalletActions from 'actions/generateWallet';
import Wallet from 'ethereumjs-wallet';
describe('generateWallet reducer', () => {
it('should handle GENERATE_WALLET_GENERATE_WALLET', () => {
const { wallet, password, activeStep } = generateWallet(
undefined,
generateWalletActions.generateNewWallet('password')
);
expect(wallet).toBeInstanceOf(Wallet);
expect(password).toEqual('password');
expect(activeStep).toEqual('download');
});
it('should handle GENERATE_WALLET_CONTINUE_TO_PAPER', () => {
expect(
generateWallet(undefined, generateWalletActions.continueToPaper())

View File

@ -0,0 +1,28 @@
import { notifications } from 'reducers/notifications';
import * as notificationsActions from 'actions/notifications';
describe('customTokens reducer', () => {
const notification1 = notificationsActions.showNotification('success', 'msg');
const notification2 = notificationsActions.showNotification('danger', 'msg');
it('should handle SHOW_NOTIFICATION', () => {
const state = notifications(undefined, notification1);
expect(notifications(state, notification2)).toEqual([
notification1.payload,
notification2.payload
]);
});
it('should handle CLOSE_NOTIFICATION', () => {
const state1 = notifications(undefined, notification1);
const state2 = notifications(state1, notification2);
expect(
notifications(
state2,
notificationsActions.closeNotification(notification2.payload)
)
).toEqual([notification1.payload]);
});
});

View File

@ -0,0 +1,33 @@
import { rates, INITIAL_STATE } from 'reducers/rates';
import * as ratesActions from 'actions/rates';
describe('rates reducer', () => {
it('should handle RATES_FETCH_CC_SUCCEEDED', () => {
const fakeCCResp: ratesActions.CCResponse = {
symbol: 'USD',
rates: {
BTC: 1,
EUR: 2,
GBP: 3,
CHF: 4,
REP: 5,
ETH: 6
}
};
expect(
rates(undefined, ratesActions.fetchCCRatesSucceeded(fakeCCResp))
).toEqual({
...INITIAL_STATE,
rates: {
...INITIAL_STATE.rates,
[fakeCCResp.symbol]: fakeCCResp.rates
}
});
});
it('should handle RATES_FETCH_CC_FAILED', () => {
expect(rates(undefined, ratesActions.fetchCCRatesFailed())).toHaveProperty(
'ratesError'
);
});
});

View File

@ -59,12 +59,12 @@ describe('swap reducer', () => {
it('should handle SWAP_ORIGIN_AMOUNT', () => {
const originAmount = 2;
expect(
swap(undefined, swapActions.originAmountSwap(originAmount))
).toEqual({
...INITIAL_STATE,
originAmount
});
expect(swap(undefined, swapActions.originAmountSwap(originAmount))).toEqual(
{
...INITIAL_STATE,
originAmount
}
);
});
it('should handle SWAP_DESTINATION_AMOUNT', () => {
@ -153,12 +153,71 @@ describe('swap reducer', () => {
});
});
// TODO
// it('should handle SWAP_BITY_ORDER_CREATE_SUCCEEDED', () => {
// });
//
// it('should handle SWAP_BITY_ORDER_STATUS_SUCCEEDED', () => {
// });
it('should handle SWAP_BITY_ORDER_CREATE_SUCCEEDED', () => {
const mockedBityOrder: swapActions.BityOrderPostResponse = {
payment_address: 'payment_address',
status: 'status',
input: {
amount: '1.111',
currency: 'input_currency',
reference: 'input_reference',
status: 'input_status'
},
output: {
amount: '1.111',
currency: 'output_currency',
reference: 'output_reference',
status: 'output_status'
},
timestamp_created: 'timestamp_created',
validFor: 0,
id: 'id'
};
expect(
swap(undefined, swapActions.bityOrderCreateSucceededSwap(mockedBityOrder))
).toEqual({
...INITIAL_STATE,
bityOrder: {
...mockedBityOrder
},
isPostingOrder: false,
originAmount: parseFloat(mockedBityOrder.input.amount),
destinationAmount: parseFloat(mockedBityOrder.output.amount),
secondsRemaining: mockedBityOrder.validFor,
validFor: mockedBityOrder.validFor,
orderTimestampCreatedISOString: mockedBityOrder.timestamp_created,
paymentAddress: mockedBityOrder.payment_address,
orderStatus: mockedBityOrder.status,
orderId: mockedBityOrder.id
});
});
it('should handle SWAP_BITY_ORDER_STATUS_SUCCEEDED', () => {
const mockedBityResponse: swapActions.BityOrderResponse = {
input: {
amount: '1.111',
currency: 'input_currency',
reference: 'input_reference',
status: 'input_status'
},
output: {
amount: '1.111',
currency: 'output_currency',
reference: 'output_reference',
status: 'FILL'
},
status: 'status'
};
expect(
swap(undefined, swapActions.orderStatusSucceededSwap(mockedBityResponse))
).toEqual({
...INITIAL_STATE,
outputTx: mockedBityResponse.output.reference,
orderStatus: mockedBityResponse.output.status
});
});
it('should handle SWAP_ORDER_TIME', () => {
const secondsRemaining = 300;

View File

@ -1,11 +1,11 @@
import { wallet, INITIAL_STATE } from 'reducers/wallet';
import { Wei, TokenValue } from 'libs/units';
import * as walletActions from 'actions/wallet';
import { TokenValue } from 'libs/units';
describe('wallet reducer', () => {
it('should handle WALLET_SET', () => {
const doSomething = new Promise<string>(resolve => {
setTimeout(() => resolve('Success'), 1000);
setTimeout(() => resolve('Success'), 10);
});
const walletInstance = {
@ -20,6 +20,45 @@ describe('wallet reducer', () => {
});
});
it('should handle WALLET_RESET', () => {
expect(wallet(undefined, walletActions.resetWallet())).toEqual(
INITIAL_STATE
);
});
it('should handle WALLET_SET_BALANCE_PENDING', () => {
expect(wallet(undefined, walletActions.setBalancePending())).toEqual({
...INITIAL_STATE,
balance: {
...INITIAL_STATE.balance,
isPending: true
}
});
});
it('should handle WALLET_SET_BALANCE_FULFILLED', () => {
const balance = Wei('100');
expect(
wallet(undefined, walletActions.setBalanceFullfilled(balance))
).toEqual({
...INITIAL_STATE,
balance: {
wei: balance,
isPending: false
}
});
});
it('should handle WALLET_SET_BALANCE_REJECTED', () => {
expect(wallet(undefined, walletActions.setBalanceRejected())).toEqual({
...INITIAL_STATE,
balance: {
...INITIAL_STATE.balance,
isPending: false
}
});
});
it('should handle WALLET_SET_TOKEN_BALANCES', () => {
const tokenBalances = { OMG: TokenValue('20') };
expect(
@ -29,4 +68,58 @@ describe('wallet reducer', () => {
tokens: tokenBalances
});
});
it('should handle WALLET_BROADCAST_TX_REQUESTED', () => {
const signedTx = '0xdeadbeef';
// test broadcast where first time seeing transaction
expect(wallet(undefined, walletActions.broadcastTx(signedTx))).toEqual({
...INITIAL_STATE,
transactions: [
{
signedTx,
isBroadcasting: true,
successfullyBroadcast: false
}
]
});
});
it('should handle WALLET_BROADCAST_TX_SUCCEEDED', () => {
const signedTx = '0xdead';
const txHash = '0xbeef';
const state = wallet(undefined, walletActions.broadcastTx(signedTx));
expect(
wallet(state, walletActions.broadcastTxSucceded(txHash, signedTx))
).toEqual({
...INITIAL_STATE,
transactions: [
{
signedTx,
isBroadcasting: false,
successfullyBroadcast: true
}
]
});
});
it('should handle WALLET_BROADCAST_TX_FAILED', () => {
const signedTx = '0xdeadbeef';
const errorMsg = 'Broadcasting failed.';
const state = wallet(undefined, walletActions.broadcastTx(signedTx));
expect(
wallet(state, walletActions.broadCastTxFailed(signedTx, errorMsg))
).toEqual({
...INITIAL_STATE,
transactions: [
{
signedTx,
isBroadcasting: false,
successfullyBroadcast: false
}
]
});
});
});