Remove redux-promise-middleware (#1022)
* Use shapeshift for all swaps. * Replace existing redux-promise-middleware based CCRequest action with saga based action. * Remove module from package.json, store middleware, webpack_config. * fix snapshot * Add return typing * Add test for saga
This commit is contained in:
parent
6d041ba581
commit
e7f88a6a0a
|
@ -1,12 +1,12 @@
|
||||||
import * as interfaces from './actionTypes';
|
import * as interfaces from './actionTypes';
|
||||||
import { TypeKeys } from './constants';
|
import { TypeKeys } from './constants';
|
||||||
import { fetchRates, CCResponse } from './actionPayloads';
|
import { CCResponse } from 'api/rates';
|
||||||
|
|
||||||
export type TFetchCCRates = typeof fetchCCRates;
|
export type TFetchCCRatesRequested = typeof fetchCCRatesRequested;
|
||||||
export function fetchCCRates(symbols: string[] = []): interfaces.FetchCCRates {
|
export function fetchCCRatesRequested(symbols: string[] = []): interfaces.FetchCCRatesRequested {
|
||||||
return {
|
return {
|
||||||
type: TypeKeys.RATES_FETCH_CC,
|
type: TypeKeys.RATES_FETCH_CC_REQUESTED,
|
||||||
payload: fetchRates(symbols)
|
payload: symbols
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { TypeKeys } from './constants';
|
import { TypeKeys } from './constants';
|
||||||
import { CCResponse } from './actionPayloads';
|
import { CCResponse } from 'api/rates';
|
||||||
|
|
||||||
export interface FetchCCRates {
|
export interface FetchCCRatesRequested {
|
||||||
type: TypeKeys.RATES_FETCH_CC;
|
type: TypeKeys.RATES_FETCH_CC_REQUESTED;
|
||||||
payload: Promise<CCResponse>;
|
payload: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** Set rates ***/
|
/*** Set rates ***/
|
||||||
|
@ -17,4 +17,4 @@ export interface FetchCCRatesFailed {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** Union Type ***/
|
/*** Union Type ***/
|
||||||
export type RatesAction = FetchCCRates | FetchCCRatesSucceeded | FetchCCRatesFailed;
|
export type RatesAction = FetchCCRatesRequested | FetchCCRatesSucceeded | FetchCCRatesFailed;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
export enum TypeKeys {
|
export enum TypeKeys {
|
||||||
RATES_FETCH_CC = 'RATES_FETCH_CC',
|
RATES_FETCH_CC_REQUESTED = 'RATES_FETCH_CC_REQUESTED',
|
||||||
RATES_FETCH_CC_FAILED = 'RATES_FETCH_CC_FAILED',
|
RATES_FETCH_CC_FAILED = 'RATES_FETCH_CC_FAILED',
|
||||||
RATES_FETCH_CC_SUCCEEDED = 'RATES_FETCH_CC_SUCCEEDED'
|
RATES_FETCH_CC_SUCCEEDED = 'RATES_FETCH_CC_SUCCEEDED'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
export * from './actionCreators';
|
export * from './actionCreators';
|
||||||
export * from './actionTypes';
|
export * from './actionTypes';
|
||||||
export * from './actionPayloads';
|
|
||||||
|
|
|
@ -2,7 +2,8 @@ import React from 'react';
|
||||||
import translate from 'translations';
|
import translate from 'translations';
|
||||||
import { UnitDisplay, Spinner } from 'components/ui';
|
import { UnitDisplay, Spinner } from 'components/ui';
|
||||||
import Select from 'react-select';
|
import Select from 'react-select';
|
||||||
import { TFetchCCRates, fetchCCRates, rateSymbols } from 'actions/rates';
|
import { TFetchCCRatesRequested, fetchCCRatesRequested } from 'actions/rates';
|
||||||
|
import { rateSymbols } from 'api/rates';
|
||||||
import { chain, flatMap } from 'lodash';
|
import { chain, flatMap } from 'lodash';
|
||||||
import { TokenBalance, getShownTokenBalances } from 'selectors/wallet';
|
import { TokenBalance, getShownTokenBalances } from 'selectors/wallet';
|
||||||
import { Balance } from 'libs/wallet';
|
import { Balance } from 'libs/wallet';
|
||||||
|
@ -43,7 +44,7 @@ interface StateProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DispatchProps {
|
interface DispatchProps {
|
||||||
fetchCCRates: TFetchCCRates;
|
fetchCCRates: TFetchCCRatesRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = StateProps & DispatchProps;
|
type Props = StateProps & DispatchProps;
|
||||||
|
@ -266,4 +267,4 @@ function mapStateToProps(state: AppState): StateProps {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps, { fetchCCRates })(EquivalentValues);
|
export default connect(mapStateToProps, { fetchCCRates: fetchCCRatesRequested })(EquivalentValues);
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {
|
||||||
reset,
|
reset,
|
||||||
TReset
|
TReset
|
||||||
} from 'actions/transaction';
|
} from 'actions/transaction';
|
||||||
import { fetchCCRates, TFetchCCRates } from 'actions/rates';
|
import { fetchCCRatesRequested, TFetchCCRatesRequested } from 'actions/rates';
|
||||||
import { getNetworkConfig, getOffline } from 'selectors/config';
|
import { getNetworkConfig, getOffline } from 'selectors/config';
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { Units } from 'libs/units';
|
import { Units } from 'libs/units';
|
||||||
|
@ -32,7 +32,7 @@ interface StateProps {
|
||||||
interface DispatchProps {
|
interface DispatchProps {
|
||||||
inputGasPrice: TInputGasPrice;
|
inputGasPrice: TInputGasPrice;
|
||||||
inputGasPriceIntent: TInputGasPriceIntent;
|
inputGasPriceIntent: TInputGasPriceIntent;
|
||||||
fetchCCRates: TFetchCCRates;
|
fetchCCRates: TFetchCCRatesRequested;
|
||||||
getNonceRequested: TGetNonceRequested;
|
getNonceRequested: TGetNonceRequested;
|
||||||
reset: TReset;
|
reset: TReset;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ function mapStateToProps(state: AppState): StateProps {
|
||||||
export default connect(mapStateToProps, {
|
export default connect(mapStateToProps, {
|
||||||
inputGasPrice,
|
inputGasPrice,
|
||||||
inputGasPriceIntent,
|
inputGasPriceIntent,
|
||||||
fetchCCRates,
|
fetchCCRates: fetchCCRatesRequested,
|
||||||
getNonceRequested,
|
getNonceRequested,
|
||||||
reset
|
reset
|
||||||
})(TXMetaDataPanel);
|
})(TXMetaDataPanel);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { FetchCCRatesSucceeded, RatesAction, CCResponse } from 'actions/rates';
|
import { FetchCCRatesSucceeded, RatesAction } from 'actions/rates';
|
||||||
|
import { CCResponse } from 'api/rates';
|
||||||
import { TypeKeys } from 'actions/rates/constants';
|
import { TypeKeys } from 'actions/rates/constants';
|
||||||
|
|
||||||
// SYMBOL -> PRICE TO BUY 1 ETH
|
// SYMBOL -> PRICE TO BUY 1 ETH
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import configSaga from './config';
|
import configSaga from './config';
|
||||||
import deterministicWallets from './deterministicWallets';
|
import deterministicWallets from './deterministicWallets';
|
||||||
import notifications from './notifications';
|
import notifications from './notifications';
|
||||||
|
import rates from './rates';
|
||||||
import {
|
import {
|
||||||
swapTimerSaga,
|
swapTimerSaga,
|
||||||
pollBityOrderStatusSaga,
|
pollBityOrderStatusSaga,
|
||||||
|
@ -31,5 +32,6 @@ export default {
|
||||||
wallet,
|
wallet,
|
||||||
transaction,
|
transaction,
|
||||||
deterministicWallets,
|
deterministicWallets,
|
||||||
swapProviderSaga
|
swapProviderSaga,
|
||||||
|
rates
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { fetchCCRatesSucceeded, fetchCCRatesFailed, FetchCCRatesRequested } from 'actions/rates';
|
||||||
|
import { SagaIterator } from 'redux-saga';
|
||||||
|
import { call, put, takeLatest } from 'redux-saga/effects';
|
||||||
|
import { fetchRates, CCResponse } from 'api/rates';
|
||||||
|
import { TypeKeys } from 'actions/rates/constants';
|
||||||
|
|
||||||
|
export function* fetchRatesSaga(action: FetchCCRatesRequested): SagaIterator {
|
||||||
|
try {
|
||||||
|
const rates: CCResponse = yield call(fetchRates, action.payload);
|
||||||
|
yield put(fetchCCRatesSucceeded(rates));
|
||||||
|
} catch (e) {
|
||||||
|
yield put(fetchCCRatesFailed());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function* ratesSaga(): SagaIterator {
|
||||||
|
yield takeLatest(TypeKeys.RATES_FETCH_CC_REQUESTED, fetchRatesSaga);
|
||||||
|
}
|
|
@ -12,7 +12,6 @@ import { createLogger } from 'redux-logger';
|
||||||
import createSagaMiddleware from 'redux-saga';
|
import createSagaMiddleware from 'redux-saga';
|
||||||
import { loadStatePropertyOrEmptyObject, saveState } from 'utils/localStorage';
|
import { loadStatePropertyOrEmptyObject, saveState } from 'utils/localStorage';
|
||||||
import RootReducer, { AppState } from './reducers';
|
import RootReducer, { AppState } from './reducers';
|
||||||
import promiseMiddleware from 'redux-promise-middleware';
|
|
||||||
import { getNodeConfigFromId } from 'utils/node';
|
import { getNodeConfigFromId } from 'utils/node';
|
||||||
import { getNetworkConfigFromId } from 'utils/network';
|
import { getNetworkConfigFromId } from 'utils/network';
|
||||||
import { dedupeCustomTokens } from 'utils/tokens';
|
import { dedupeCustomTokens } from 'utils/tokens';
|
||||||
|
@ -23,27 +22,15 @@ const configureStore = () => {
|
||||||
collapsed: true
|
collapsed: true
|
||||||
});
|
});
|
||||||
const sagaMiddleware = createSagaMiddleware();
|
const sagaMiddleware = createSagaMiddleware();
|
||||||
const reduxPromiseMiddleWare = promiseMiddleware({
|
|
||||||
promiseTypeSuffixes: ['REQUESTED', 'SUCCEEDED', 'FAILED']
|
|
||||||
});
|
|
||||||
let middleware;
|
let middleware;
|
||||||
let store;
|
let store;
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
middleware = composeWithDevTools(
|
middleware = composeWithDevTools(
|
||||||
applyMiddleware(
|
applyMiddleware(sagaMiddleware, logger, routerMiddleware(history as any))
|
||||||
sagaMiddleware,
|
|
||||||
logger,
|
|
||||||
reduxPromiseMiddleWare,
|
|
||||||
routerMiddleware(history as any)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
middleware = applyMiddleware(
|
middleware = applyMiddleware(sagaMiddleware, routerMiddleware(history as any));
|
||||||
sagaMiddleware,
|
|
||||||
reduxPromiseMiddleWare,
|
|
||||||
routerMiddleware(history as any)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const localSwapState = loadStatePropertyOrEmptyObject<SwapState>('swap');
|
const localSwapState = loadStatePropertyOrEmptyObject<SwapState>('swap');
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
"react-transition-group": "2.2.1",
|
"react-transition-group": "2.2.1",
|
||||||
"redux": "3.7.2",
|
"redux": "3.7.2",
|
||||||
"redux-logger": "3.0.6",
|
"redux-logger": "3.0.6",
|
||||||
"redux-promise-middleware": "4.4.2",
|
|
||||||
"redux-saga": "0.16.0",
|
"redux-saga": "0.16.0",
|
||||||
"scryptsy": "2.0.0",
|
"scryptsy": "2.0.0",
|
||||||
"uuid": "3.2.1",
|
"uuid": "3.2.1",
|
||||||
|
@ -68,7 +67,6 @@
|
||||||
"@types/react-router-redux": "5.0.11",
|
"@types/react-router-redux": "5.0.11",
|
||||||
"@types/react-select": "1.2.0",
|
"@types/react-select": "1.2.0",
|
||||||
"@types/redux-logger": "3.0.5",
|
"@types/redux-logger": "3.0.5",
|
||||||
"@types/redux-promise-middleware": "0.0.9",
|
|
||||||
"@types/uuid": "3.4.3",
|
"@types/uuid": "3.4.3",
|
||||||
"@types/webpack-env": "1.13.4",
|
"@types/webpack-env": "1.13.4",
|
||||||
"@types/zxcvbn": "4.4.0",
|
"@types/zxcvbn": "4.4.0",
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { rates, INITIAL_STATE } from 'reducers/rates';
|
import { rates, INITIAL_STATE } from 'reducers/rates';
|
||||||
import * as ratesActions from 'actions/rates';
|
import * as ratesActions from 'actions/rates';
|
||||||
|
import { CCResponse } from 'api/rates';
|
||||||
|
|
||||||
describe('rates reducer', () => {
|
describe('rates reducer', () => {
|
||||||
it('should handle RATES_FETCH_CC_SUCCEEDED', () => {
|
it('should handle RATES_FETCH_CC_SUCCEEDED', () => {
|
||||||
const fakeCCResp: ratesActions.CCResponse = {
|
const fakeCCResp: CCResponse = {
|
||||||
ETH: {
|
ETH: {
|
||||||
USD: 0,
|
USD: 0,
|
||||||
BTC: 1,
|
BTC: 1,
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { fetchRatesSaga } from 'sagas/rates';
|
||||||
|
import { call, put } from 'redux-saga/effects';
|
||||||
|
import { fetchCCRatesSucceeded, fetchCCRatesFailed, fetchCCRatesRequested } from 'actions/rates';
|
||||||
|
import { fetchRates } from 'api/rates';
|
||||||
|
describe('fetch rates saga success', () => {
|
||||||
|
const saga = fetchRatesSaga(fetchCCRatesRequested());
|
||||||
|
it('should fetch the rates', () => {
|
||||||
|
expect(saga.next().value).toEqual(call(fetchRates, []));
|
||||||
|
});
|
||||||
|
it('should dispatch a success action', () => {
|
||||||
|
expect(saga.next({}).value).toEqual(put(fetchCCRatesSucceeded({})));
|
||||||
|
});
|
||||||
|
it('should be done', () => {
|
||||||
|
expect(saga.next().done).toEqual(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('fetch rates saga failure', () => {
|
||||||
|
const saga = fetchRatesSaga(fetchCCRatesRequested());
|
||||||
|
it('it should throw and dispatch a failure action', () => {
|
||||||
|
saga.next();
|
||||||
|
expect(saga.throw!().value).toEqual(put(fetchCCRatesFailed()));
|
||||||
|
});
|
||||||
|
it('should be done', () => {
|
||||||
|
expect(saga.next().done).toEqual(true);
|
||||||
|
});
|
||||||
|
});
|
|
@ -66,7 +66,6 @@ module.exports = {
|
||||||
'react-transition-group',
|
'react-transition-group',
|
||||||
'redux',
|
'redux',
|
||||||
'redux-logger',
|
'redux-logger',
|
||||||
'redux-promise-middleware',
|
|
||||||
'redux-saga',
|
'redux-saga',
|
||||||
'scryptsy',
|
'scryptsy',
|
||||||
'uuid',
|
'uuid',
|
||||||
|
|
Loading…
Reference in New Issue