2017-12-11 17:44:53 +00:00
|
|
|
import { normalize } from 'normalizr';
|
2018-06-18 01:53:00 +00:00
|
|
|
|
2018-01-09 02:59:32 +00:00
|
|
|
import { SHAPESHIFT_TOKEN_WHITELIST } from 'api/shapeshift';
|
2018-06-18 01:53:00 +00:00
|
|
|
import tokens from 'config/tokens/eth.json';
|
|
|
|
import * as types from './types';
|
|
|
|
import * as actions from './actions';
|
|
|
|
import * as reducer from './reducer';
|
2018-01-09 02:59:32 +00:00
|
|
|
|
|
|
|
describe('ensure whitelist', () => {
|
2018-03-07 23:36:05 +00:00
|
|
|
const findToken = (tkn: string) => tokens.find((t: any) => t.symbol === tkn);
|
2018-01-09 02:59:32 +00:00
|
|
|
SHAPESHIFT_TOKEN_WHITELIST.forEach(t => {
|
|
|
|
it(`Should find Token ${t}`, () => {
|
|
|
|
expect(findToken(t)).toBeTruthy();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2017-08-24 08:53:59 +00:00
|
|
|
|
|
|
|
describe('swap reducer', () => {
|
2018-01-02 18:04:50 +00:00
|
|
|
const shapeshiftApiResponse = {
|
|
|
|
['1SSTANT']: {
|
|
|
|
id: '1STANT',
|
|
|
|
options: [
|
|
|
|
{
|
|
|
|
id: '1ST',
|
|
|
|
status: 'available',
|
|
|
|
image: 'https://shapeshift.io/images/coins/firstblood.png',
|
|
|
|
name: 'FirstBlood'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 'ANT',
|
|
|
|
status: 'available',
|
|
|
|
image: 'https://shapeshift.io/images/coins/aragon.png',
|
|
|
|
name: 'Aragon'
|
|
|
|
}
|
|
|
|
],
|
|
|
|
rate: '0.24707537',
|
|
|
|
limit: 5908.29166225,
|
|
|
|
min: 7.86382979
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const bityApiResponse = {
|
2017-12-11 17:44:53 +00:00
|
|
|
BTCETH: {
|
|
|
|
id: 'BTCETH',
|
|
|
|
options: [{ id: 'BTC' }, { id: 'ETH' }],
|
|
|
|
rate: 23.27855114
|
|
|
|
},
|
|
|
|
ETHBTC: {
|
|
|
|
id: 'ETHBTC',
|
|
|
|
options: [{ id: 'ETH' }, { id: 'BTC' }],
|
|
|
|
rate: 0.042958
|
|
|
|
}
|
|
|
|
};
|
2018-01-02 18:04:50 +00:00
|
|
|
|
2018-06-18 01:53:00 +00:00
|
|
|
const normalizedBityRates: types.NormalizedBityRates = {
|
|
|
|
byId: normalize(bityApiResponse, [reducer.providerRate]).entities.providerRates,
|
|
|
|
allIds: reducer.allIds(
|
|
|
|
normalize(bityApiResponse, [reducer.providerRate]).entities.providerRates
|
|
|
|
)
|
2018-01-02 18:04:50 +00:00
|
|
|
};
|
2018-06-18 01:53:00 +00:00
|
|
|
const normalizedShapeshiftRates: types.NormalizedShapeshiftRates = {
|
|
|
|
byId: normalize(shapeshiftApiResponse, [reducer.providerRate]).entities.providerRates,
|
|
|
|
allIds: reducer.allIds(
|
|
|
|
normalize(shapeshiftApiResponse, [reducer.providerRate]).entities.providerRates
|
2018-01-02 18:04:50 +00:00
|
|
|
)
|
|
|
|
};
|
2018-06-18 01:53:00 +00:00
|
|
|
const normalizedBityOptions: types.NormalizedOptions = {
|
|
|
|
byId: normalize(bityApiResponse, [reducer.providerRate]).entities.options,
|
|
|
|
allIds: reducer.allIds(normalize(bityApiResponse, [reducer.providerRate]).entities.options)
|
2017-12-11 17:44:53 +00:00
|
|
|
};
|
2018-06-18 01:53:00 +00:00
|
|
|
const normalizedShapeshiftOptions: types.NormalizedOptions = {
|
|
|
|
byId: normalize(shapeshiftApiResponse, [reducer.providerRate]).entities.options,
|
|
|
|
allIds: reducer.allIds(
|
|
|
|
normalize(shapeshiftApiResponse, [reducer.providerRate]).entities.options
|
|
|
|
)
|
2017-12-11 17:44:53 +00:00
|
|
|
};
|
2018-01-02 18:04:50 +00:00
|
|
|
|
2017-08-24 08:53:59 +00:00
|
|
|
it('should handle SWAP_LOAD_BITY_RATES_SUCCEEDED', () => {
|
2018-06-18 01:53:00 +00:00
|
|
|
expect(
|
|
|
|
reducer.swapReducer(undefined, actions.loadBityRatesSucceededSwap(bityApiResponse))
|
|
|
|
).toEqual({
|
|
|
|
...reducer.INITIAL_STATE,
|
2017-08-24 08:53:59 +00:00
|
|
|
isFetchingRates: false,
|
2018-01-02 18:04:50 +00:00
|
|
|
bityRates: normalizedBityRates,
|
|
|
|
options: normalizedBityOptions
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle SWAP_LOAD_SHAPESHIFT_RATES_SUCCEEDED', () => {
|
|
|
|
expect(
|
2018-06-18 01:53:00 +00:00
|
|
|
reducer.swapReducer(
|
|
|
|
undefined,
|
|
|
|
actions.loadShapeshiftRatesSucceededSwap(shapeshiftApiResponse as any)
|
|
|
|
)
|
2018-01-02 18:04:50 +00:00
|
|
|
).toEqual({
|
2018-06-18 01:53:00 +00:00
|
|
|
...reducer.INITIAL_STATE,
|
2018-01-02 18:04:50 +00:00
|
|
|
isFetchingRates: false,
|
|
|
|
shapeshiftRates: normalizedShapeshiftRates,
|
|
|
|
options: normalizedShapeshiftOptions
|
2017-08-24 08:53:59 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle SWAP_STEP', () => {
|
|
|
|
const step = 2;
|
2018-06-18 01:53:00 +00:00
|
|
|
expect(reducer.swapReducer(undefined, actions.changeStepSwap(step))).toEqual({
|
|
|
|
...reducer.INITIAL_STATE,
|
2017-08-24 08:53:59 +00:00
|
|
|
step
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle SWAP_DESTINATION_ADDRESS', () => {
|
|
|
|
const destinationAddress = '341a0sdf83';
|
2018-06-18 01:53:00 +00:00
|
|
|
expect(
|
|
|
|
reducer.swapReducer(undefined, actions.destinationAddressSwap(destinationAddress))
|
|
|
|
).toEqual({
|
|
|
|
...reducer.INITIAL_STATE,
|
2017-08-24 08:53:59 +00:00
|
|
|
destinationAddress
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle SWAP_RESTART', () => {
|
|
|
|
expect(
|
2018-06-18 01:53:00 +00:00
|
|
|
reducer.swapReducer(
|
2017-08-24 08:53:59 +00:00
|
|
|
{
|
2018-06-18 01:53:00 +00:00
|
|
|
...reducer.INITIAL_STATE,
|
2018-01-02 18:04:50 +00:00
|
|
|
bityRates: normalizedBityRates,
|
|
|
|
shapeshiftRates: normalizedShapeshiftRates,
|
2018-03-01 17:53:29 +00:00
|
|
|
origin: { label: 'BTC', amount: 1 },
|
|
|
|
destination: { label: 'ETH', amount: 3 }
|
2017-08-24 08:53:59 +00:00
|
|
|
},
|
2018-06-18 01:53:00 +00:00
|
|
|
actions.restartSwap()
|
2017-08-24 08:53:59 +00:00
|
|
|
)
|
|
|
|
).toEqual({
|
2018-06-18 01:53:00 +00:00
|
|
|
...reducer.INITIAL_STATE,
|
2018-01-02 18:04:50 +00:00
|
|
|
bityRates: normalizedBityRates,
|
|
|
|
shapeshiftRates: normalizedShapeshiftRates
|
2017-08-24 08:53:59 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-01-02 18:04:50 +00:00
|
|
|
it('should handle SWAP_BITY_ORDER_CREATE_REQUESTED', () => {
|
2017-10-25 02:17:26 +00:00
|
|
|
expect(
|
2018-06-18 01:53:00 +00:00
|
|
|
reducer.swapReducer(undefined, {
|
|
|
|
type: types.SwapActions.BITY_ORDER_CREATE_REQUESTED
|
|
|
|
} as types.SwapAction)
|
2017-10-25 02:17:26 +00:00
|
|
|
).toEqual({
|
2018-06-18 01:53:00 +00:00
|
|
|
...reducer.INITIAL_STATE,
|
2017-08-24 08:53:59 +00:00
|
|
|
isPostingOrder: true
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-01-02 18:04:50 +00:00
|
|
|
it('should handle SWAP_SHAPESHIFT_ORDER_CREATE_REQUESTED', () => {
|
|
|
|
expect(
|
2018-06-18 01:53:00 +00:00
|
|
|
reducer.swapReducer(undefined, {
|
|
|
|
type: types.SwapActions.BITY_ORDER_CREATE_REQUESTED
|
|
|
|
} as types.SwapAction)
|
2018-01-02 18:04:50 +00:00
|
|
|
).toEqual({
|
2018-06-18 01:53:00 +00:00
|
|
|
...reducer.INITIAL_STATE,
|
2018-01-02 18:04:50 +00:00
|
|
|
isPostingOrder: true
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle SWAP_BITY_ORDER_CREATE_FAILED', () => {
|
|
|
|
expect(
|
2018-06-18 01:53:00 +00:00
|
|
|
reducer.swapReducer(undefined, {
|
|
|
|
type: types.SwapActions.BITY_ORDER_CREATE_FAILED
|
|
|
|
} as types.SwapAction)
|
2018-01-02 18:04:50 +00:00
|
|
|
).toEqual({
|
2018-06-18 01:53:00 +00:00
|
|
|
...reducer.INITIAL_STATE,
|
2018-01-02 18:04:50 +00:00
|
|
|
isPostingOrder: false
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle SWAP_SHAPESHIFT_ORDER_CREATE_FAILED', () => {
|
2017-10-25 02:17:26 +00:00
|
|
|
expect(
|
2018-06-18 01:53:00 +00:00
|
|
|
reducer.swapReducer(undefined, {
|
|
|
|
type: types.SwapActions.SHAPESHIFT_ORDER_CREATE_FAILED
|
|
|
|
} as types.SwapAction)
|
2017-10-25 02:17:26 +00:00
|
|
|
).toEqual({
|
2018-06-18 01:53:00 +00:00
|
|
|
...reducer.INITIAL_STATE,
|
2017-08-24 08:53:59 +00:00
|
|
|
isPostingOrder: false
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-11-17 21:12:27 +00:00
|
|
|
it('should handle SWAP_BITY_ORDER_CREATE_SUCCEEDED', () => {
|
2018-06-18 01:53:00 +00:00
|
|
|
const mockedBityOrder: types.BityOrderPostResponse = {
|
2017-11-17 21:12:27 +00:00
|
|
|
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'
|
|
|
|
};
|
|
|
|
|
2018-06-18 01:53:00 +00:00
|
|
|
expect(
|
|
|
|
reducer.swapReducer(undefined, actions.bityOrderCreateSucceededSwap(mockedBityOrder))
|
|
|
|
).toEqual({
|
|
|
|
...reducer.INITIAL_STATE,
|
2017-11-17 21:12:27 +00:00
|
|
|
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,
|
2018-01-02 18:04:50 +00:00
|
|
|
bityOrderStatus: mockedBityOrder.status,
|
2017-11-17 21:12:27 +00:00
|
|
|
orderId: mockedBityOrder.id
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-01-02 18:04:50 +00:00
|
|
|
it('should handle SWAP_SHAPESHIFT_ORDER_CREATE_SUCCEEDED', () => {
|
2018-06-18 01:53:00 +00:00
|
|
|
const mockedShapeshiftOrder: types.ShapeshiftOrderResponse = {
|
2018-01-02 18:04:50 +00:00
|
|
|
orderId: '64d73218-0ee9-4c6c-9bbd-6da9208595f5',
|
|
|
|
pair: 'eth_ant',
|
|
|
|
withdrawal: '0x6b3a639eb96d8e0241fe4e114d99e739f906944e',
|
|
|
|
withdrawalAmount: '200.13550988',
|
|
|
|
deposit: '0x039ed77933388642fdd618d27bfc4fa3582d10c4',
|
|
|
|
depositAmount: '0.98872802',
|
|
|
|
expiration: 1514633757288,
|
|
|
|
quotedRate: '203.47912271',
|
|
|
|
maxLimit: 7.04575258,
|
|
|
|
apiPubKey:
|
|
|
|
'0ca1ccd50b708a3f8c02327f0caeeece06d3ddc1b0ac749a987b453ee0f4a29bdb5da2e53bc35e57fb4bb7ae1f43c93bb098c3c4716375fc1001c55d8c94c160',
|
|
|
|
minerFee: '1.05'
|
|
|
|
};
|
|
|
|
|
2018-06-18 01:53:00 +00:00
|
|
|
const swapState = reducer.swapReducer(
|
2018-01-02 18:04:50 +00:00
|
|
|
undefined,
|
2018-06-18 01:53:00 +00:00
|
|
|
actions.shapeshiftOrderCreateSucceededSwap(mockedShapeshiftOrder)
|
2018-01-02 18:04:50 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
expect(swapState).toEqual({
|
2018-06-18 01:53:00 +00:00
|
|
|
...reducer.INITIAL_STATE,
|
2018-01-02 18:04:50 +00:00
|
|
|
shapeshiftOrder: {
|
|
|
|
...mockedShapeshiftOrder
|
|
|
|
},
|
|
|
|
isPostingOrder: false,
|
|
|
|
originAmount: parseFloat(mockedShapeshiftOrder.depositAmount),
|
|
|
|
destinationAmount: parseFloat(mockedShapeshiftOrder.withdrawalAmount),
|
|
|
|
secondsRemaining: swapState.secondsRemaining,
|
|
|
|
validFor: swapState.validFor,
|
|
|
|
orderTimestampCreatedISOString: swapState.orderTimestampCreatedISOString,
|
|
|
|
paymentAddress: mockedShapeshiftOrder.deposit,
|
|
|
|
shapeshiftOrderStatus: 'no_deposits',
|
|
|
|
orderId: mockedShapeshiftOrder.orderId
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-11-17 21:12:27 +00:00
|
|
|
it('should handle SWAP_BITY_ORDER_STATUS_SUCCEEDED', () => {
|
2018-06-18 01:53:00 +00:00
|
|
|
const mockedBityResponse: types.BityOrderResponse = {
|
2017-11-17 21:12:27 +00:00
|
|
|
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'
|
|
|
|
};
|
|
|
|
|
2018-06-18 01:53:00 +00:00
|
|
|
expect(
|
|
|
|
reducer.swapReducer(undefined, actions.bityOrderStatusSucceededSwap(mockedBityResponse))
|
|
|
|
).toEqual({
|
|
|
|
...reducer.INITIAL_STATE,
|
2017-11-17 21:12:27 +00:00
|
|
|
outputTx: mockedBityResponse.output.reference,
|
2018-01-02 18:04:50 +00:00
|
|
|
bityOrderStatus: mockedBityResponse.output.status
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle SWAP_SHAPESHIFT_ORDER_STATUS_SUCCEEDED', () => {
|
2018-06-18 01:53:00 +00:00
|
|
|
const mockedShapeshiftResponse: types.ShapeshiftStatusResponse = {
|
2018-01-02 18:04:50 +00:00
|
|
|
status: 'complete',
|
|
|
|
transaction: '0x039ed77933388642fdd618d27bfc4fa3582d10c4'
|
|
|
|
};
|
|
|
|
|
|
|
|
expect(
|
2018-06-18 01:53:00 +00:00
|
|
|
reducer.swapReducer(
|
|
|
|
undefined,
|
|
|
|
actions.shapeshiftOrderStatusSucceededSwap(mockedShapeshiftResponse)
|
|
|
|
)
|
2018-01-02 18:04:50 +00:00
|
|
|
).toEqual({
|
2018-06-18 01:53:00 +00:00
|
|
|
...reducer.INITIAL_STATE,
|
2018-01-02 18:04:50 +00:00
|
|
|
shapeshiftOrderStatus: mockedShapeshiftResponse.status,
|
|
|
|
outputTx: mockedShapeshiftResponse.transaction
|
2017-11-17 21:12:27 +00:00
|
|
|
});
|
|
|
|
});
|
2017-08-24 08:53:59 +00:00
|
|
|
|
|
|
|
it('should handle SWAP_ORDER_TIME', () => {
|
|
|
|
const secondsRemaining = 300;
|
2018-06-18 01:53:00 +00:00
|
|
|
expect(reducer.swapReducer(undefined, actions.orderTimeSwap(secondsRemaining))).toEqual({
|
|
|
|
...reducer.INITIAL_STATE,
|
2017-08-24 08:53:59 +00:00
|
|
|
secondsRemaining
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle SWAP_LOAD_BITY_RATES_REQUESTED', () => {
|
|
|
|
expect(
|
2018-06-18 01:53:00 +00:00
|
|
|
reducer.swapReducer(undefined, {
|
2017-10-25 02:17:26 +00:00
|
|
|
type: 'SWAP_LOAD_BITY_RATES_REQUESTED'
|
2018-06-18 01:53:00 +00:00
|
|
|
} as types.SwapAction)
|
2017-08-24 08:53:59 +00:00
|
|
|
).toEqual({
|
2018-06-18 01:53:00 +00:00
|
|
|
...reducer.INITIAL_STATE,
|
2017-08-24 08:53:59 +00:00
|
|
|
isFetchingRates: true
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-01-02 18:04:50 +00:00
|
|
|
it('should handle SWAP_LOAD_SHAPESHIFT_RATE_REQUESTED', () => {
|
|
|
|
expect(
|
2018-06-18 01:53:00 +00:00
|
|
|
reducer.swapReducer(undefined, {
|
|
|
|
type: types.SwapActions.LOAD_SHAPESHIFT_RATES_REQUESTED
|
|
|
|
} as types.SwapAction)
|
2018-01-02 18:04:50 +00:00
|
|
|
).toEqual({
|
2018-06-18 01:53:00 +00:00
|
|
|
...reducer.INITIAL_STATE,
|
2018-01-02 18:04:50 +00:00
|
|
|
isFetchingRates: true
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-08-24 08:53:59 +00:00
|
|
|
it('should handle SWAP_STOP_LOAD_BITY_RATES', () => {
|
2017-10-25 02:17:26 +00:00
|
|
|
expect(
|
2018-06-18 01:53:00 +00:00
|
|
|
reducer.swapReducer(undefined, {
|
2017-10-25 02:17:26 +00:00
|
|
|
type: 'SWAP_STOP_LOAD_BITY_RATES'
|
2018-06-18 01:53:00 +00:00
|
|
|
} as types.SwapAction)
|
2017-10-25 02:17:26 +00:00
|
|
|
).toEqual({
|
2018-06-18 01:53:00 +00:00
|
|
|
...reducer.INITIAL_STATE,
|
2017-08-24 08:53:59 +00:00
|
|
|
isFetchingRates: false
|
|
|
|
});
|
|
|
|
});
|
2018-01-02 18:04:50 +00:00
|
|
|
|
|
|
|
it('should handle SWAP_STOP_LOAD_SHAPESHIFT_RATES', () => {
|
|
|
|
expect(
|
2018-06-18 01:53:00 +00:00
|
|
|
reducer.swapReducer(undefined, {
|
|
|
|
type: types.SwapActions.STOP_LOAD_SHAPESHIFT_RATES
|
|
|
|
} as types.SwapAction)
|
2018-01-02 18:04:50 +00:00
|
|
|
).toEqual({
|
2018-06-18 01:53:00 +00:00
|
|
|
...reducer.INITIAL_STATE,
|
2018-01-02 18:04:50 +00:00
|
|
|
isFetchingRates: false
|
|
|
|
});
|
|
|
|
});
|
2017-08-24 08:53:59 +00:00
|
|
|
});
|