Unverified Commit 90e69eea authored by andreswebs's avatar andreswebs
Browse files

use native fetch and add tests for wallet actions

parent fed13e05
import React from 'react';
import ReactDOM from 'react-dom';
import { render } from '@testing-library/react';
import App from './App';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
test('App renders without crashing', () => {
render(<App />);
});
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
......
const machineConfig = {
initial: 'Init',
states: {
Init: {
onEntry: 'FETCH_DATA_REQUEST',
on: {
FETCH_DATA_REQUEST: 'Loading'
}
},
Loading: {
on: {
FETCH_DATA_SUCCESS: 'ShowData',
FETCH_DATA_FAILURE: 'Error'
}
},
ShowData: {
type: 'final'
},
Error: {
on: {
FETCH_DATA_RETRY: 'Init'
}
}
}
};
......@@ -43,7 +43,7 @@ function success(wallet) {
}
function getWallet() {
return function(dispatch) {
return function getWalletThunk(dispatch) {
dispatch(begin());
return fetchApi({ path: USER_WALLET_PATH })
.then(response => dispatch(success(response.data)))
......
import { WALLET } from './constants';
import { reset, begin, success, failure, getWallet } from './actions';
test('action: reset', () => {
const action = reset();
expect(action.type).toEqual(WALLET);
expect(action.payload.status).toEqual('initial');
});
test('action: begin', () => {
const action = begin();
expect(action.type).toEqual(WALLET);
expect(action.payload.status).toEqual('pending');
});
test('action: success', () => {
const wallet = {};
const action = success(wallet);
expect(action.type).toEqual(WALLET);
expect(action.payload.status).toEqual('success');
expect(action.payload.wallet).toEqual(wallet);
});
test('action: failure', () => {
const error = new Error();
const action = failure(error);
expect(action.type).toEqual(WALLET);
expect(action.payload.status).toEqual('error');
expect(action.error).toBe(true);
expect(action.payload.error).toEqual(error);
});
test('action (thunk): getWallet - success', async () => {
const mockDispatch = jest.fn();
function mockFetch(data) {
return jest.fn().mockImplementation(() =>
Promise.resolve({
ok: true,
json: () => data
})
);
}
const response = {
data: {}
};
global.fetch = mockFetch(response);
await getWallet()(mockDispatch);
const actionBegin = mockDispatch.mock.calls[0][0];
const actionSuccess = mockDispatch.mock.calls[1][0];
expect(mockDispatch.mock.calls.length).toBe(2);
expect(actionBegin.type).toEqual(WALLET);
expect(actionSuccess.type).toEqual(WALLET);
expect(actionSuccess.payload.wallet).toEqual(response.data);
});
test('action (thunk): getWallet - failure', async () => {
const mockDispatch = jest.fn();
const error = new Error();
global.fetch = () => Promise.reject(error);
await getWallet()(mockDispatch);
const actionBegin = mockDispatch.mock.calls[0][0];
const actionFailure = mockDispatch.mock.calls[1][0];
expect(actionBegin.type).toEqual(WALLET);
expect(actionFailure.type).toEqual(WALLET);
expect(actionFailure.error).toBe(true);
expect(actionFailure.payload.error).toEqual(error);
});
import axios from 'axios';
const BACKEND_URL = process.env.REACT_APP_BACKEND_URL;
export const tokenName = 'auth';
......@@ -24,28 +22,44 @@ export function requireAuth(nextState, replace) {
}
}
function handleFetchErrors(response) {
if (!response.ok) {
const error = new Error(response.statusText);
error.response = response;
return Promise.reject(error);
}
return response;
}
export function fetchApi(args) {
const { path, body, method } = args;
const url = `${BACKEND_URL}/${path}`;
const newargs = {
url,
data: body,
method: method || 'GET'
body: JSON.stringify(body),
method: method || 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
}
};
if (isLoggedIn()) {
newargs.headers = {
Authorization: `Bearer ${getAuthToken()}`
};
newargs.headers.Authorization = `Bearer ${getAuthToken()}`;
}
return axios(newargs)
.then(response => response.data)
.catch(error => {
return fetch(url, newargs)
.then(handleFetchErrors)
.then(response => response.json())
.catch(async error => {
if (!error.response) {
throw error;
}
if (error.response.status === 401 && isLoggedIn()) {
logOut();
window.history.go('/login');
}
const apiErrorResponse = await error.response.json();
return Promise.reject(Object.assign(new Error(), apiErrorResponse));
});
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment