refactor services and reducers to parse JSON before data hits dispatch
This commit is contained in:
parent
55b1a9bce0
commit
ef165b0cff
16 changed files with 153 additions and 49 deletions
|
@ -39,6 +39,7 @@ function App() {
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const socketConnect = () => {
|
const socketConnect = () => {
|
||||||
|
socket.removeAllListeners();
|
||||||
socket.emit('connect');
|
socket.emit('connect');
|
||||||
socket.on('connected', data => setSocketData('socket connected'));
|
socket.on('connected', data => setSocketData('socket connected'));
|
||||||
socket.on('connect_error', err => setError([...error, err]));
|
socket.on('connect_error', err => setError([...error, err]));
|
||||||
|
|
|
@ -36,9 +36,8 @@ const Login = (props) => {
|
||||||
username,
|
username,
|
||||||
password
|
password
|
||||||
})
|
})
|
||||||
const parsedResponse = JSON.parse(loginResponse);
|
if (loginResponse.errors) {
|
||||||
if (parsedResponse.errors) {
|
const authError = loginResponse.errors
|
||||||
const authError = parsedResponse.errors
|
|
||||||
return props.dispatch({
|
return props.dispatch({
|
||||||
...errorDispatchAction,
|
...errorDispatchAction,
|
||||||
body: { authError }
|
body: { authError }
|
||||||
|
@ -48,7 +47,7 @@ const Login = (props) => {
|
||||||
return props.dispatch({
|
return props.dispatch({
|
||||||
type: 'AUTH',
|
type: 'AUTH',
|
||||||
message: 'LOGIN',
|
message: 'LOGIN',
|
||||||
body: parsedResponse
|
body: loginResponse
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
import Login from './Login';
|
import Login from './Login';
|
||||||
import { initState } from '../../reducers/init/stateReducer.init';
|
import { initState } from '../../../reducers/init/stateReducer.init';
|
||||||
|
|
||||||
test('renders Login without crashing', () => {
|
test('renders Login without crashing', () => {
|
||||||
const state = initState();
|
const state = initState();
|
||||||
|
|
|
@ -53,10 +53,9 @@ const Signup = (props) => {
|
||||||
password,
|
password,
|
||||||
confirmPassword
|
confirmPassword
|
||||||
})
|
})
|
||||||
const parsedResponse = JSON.parse(signupResponse)
|
|
||||||
|
|
||||||
if (parsedResponse.errors) {
|
if (signupResponse.errors) {
|
||||||
const authError = parsedResponse.errors[0].auth
|
const authError = signupResponse.errors[0].auth
|
||||||
return props.dispatch({
|
return props.dispatch({
|
||||||
...errorDispatchAction,
|
...errorDispatchAction,
|
||||||
body: { authError }
|
body: { authError }
|
||||||
|
@ -66,7 +65,7 @@ const Signup = (props) => {
|
||||||
return props.dispatch({
|
return props.dispatch({
|
||||||
type: 'AUTH',
|
type: 'AUTH',
|
||||||
message: 'SIGNUP',
|
message: 'SIGNUP',
|
||||||
body: parsedResponse
|
body: signupResponse
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
import Signup from './Signup';
|
import Signup from './Signup';
|
||||||
import { initState } from '../../reducers/init/stateReducer.init';
|
import { initState } from '../../../reducers/init/stateReducer.init';
|
||||||
|
|
||||||
test('renders Signup without crashing', () => {
|
test('renders Signup without crashing', () => {
|
||||||
const { getByTestId } = render(<Signup state={initState()}/>);
|
const { getByTestId } = render(<Signup state={initState()}/>);
|
||||||
|
|
|
@ -3,12 +3,30 @@ import { useParams } from 'react-router-dom';
|
||||||
import './Room.scss';
|
import './Room.scss';
|
||||||
import socketIOClient from 'socket.io-client';
|
import socketIOClient from 'socket.io-client';
|
||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
|
import roomsServices from '../../services/api/roomsServices';
|
||||||
|
|
||||||
const Room = (props) => {
|
const Room = (props) => {
|
||||||
const roomId = useParams().id;
|
const roomId = parseInt(useParams().id) || 0;
|
||||||
const [ socketData, setSocketData ] = useState();
|
const [ socketData, setSocketData ] = useState();
|
||||||
const [ messages, setMessages ] = useState();
|
const [ messages, setMessages ] = useState();
|
||||||
|
|
||||||
|
const fetchRoomAPI = async () => {
|
||||||
|
const response = await roomsServices.getRoomService(roomId);
|
||||||
|
if (response) {
|
||||||
|
console.log(response);
|
||||||
|
// const action = {
|
||||||
|
// type: 'ROOMS',
|
||||||
|
// message: 'JOIN_ROOM',
|
||||||
|
// body: response
|
||||||
|
// }
|
||||||
|
// return dispatch(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchRoomAPI();
|
||||||
|
}, [])
|
||||||
|
|
||||||
// ! [start] roomSocket
|
// ! [start] roomSocket
|
||||||
const roomSocket = socketIOClient(`${config.socketAddress}/${roomId}`)
|
const roomSocket = socketIOClient(`${config.socketAddress}/${roomId}`)
|
||||||
|
|
||||||
|
@ -23,6 +41,7 @@ const Room = (props) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
roomSocketConnect();
|
roomSocketConnect();
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// ! [end]
|
// ! [end]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -5,15 +5,10 @@ export const indexReducer = (state: state, action: action):state => {
|
||||||
switch(action.message) {
|
switch(action.message) {
|
||||||
|
|
||||||
case 'SET_USER':
|
case 'SET_USER':
|
||||||
const user = indexDataParse(action.body);
|
const user = action.body;
|
||||||
return {...state, user};
|
return {...state, user};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function indexDataParse(indexData) {
|
|
||||||
const user = JSON.parse(indexData);
|
|
||||||
return user
|
|
||||||
}
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
// @flow
|
||||||
|
import type { state, action } from '../stateReducer';
|
||||||
|
import { stateReducer } from '../stateReducer';
|
||||||
|
|
||||||
|
export const messagesReducer = (state: state, action: action):state => {
|
||||||
|
switch(action.message) {
|
||||||
|
|
||||||
|
case 'SET_MESSAGES':
|
||||||
|
const rooms = parseData(action.body);
|
||||||
|
return {...state, rooms};
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
import {stateReducer} from '../stateReducer';
|
||||||
|
import { initState } from '../init/stateReducer.init';
|
||||||
|
|
||||||
|
const messagesData = [];
|
||||||
|
|
||||||
|
it('default returns state unaltered', () => {
|
||||||
|
const state = initState();
|
||||||
|
const action = {type: 'MESSAGES', message: '', body: JSON.stringify(messagesData)};
|
||||||
|
expect(stateReducer(state, action)).toEqual(state);
|
||||||
|
})
|
|
@ -1,19 +1,43 @@
|
||||||
// @flow
|
// @flow
|
||||||
import type { state, action } from '../stateReducer';
|
import type { state, action } from '../stateReducer';
|
||||||
|
import { stateReducer } from '../stateReducer';
|
||||||
|
|
||||||
export const roomsReducer = (state: state, action: action):state => {
|
export const roomsReducer = (state: state, action: action):state => {
|
||||||
switch(action.message) {
|
switch(action.message) {
|
||||||
|
|
||||||
case 'SET_ROOMS':
|
case 'SET_ROOMS':
|
||||||
const rooms = roomsParse(action.body);
|
const rooms = action.body;
|
||||||
return {...state, rooms};
|
return {...state, rooms};
|
||||||
|
|
||||||
|
case 'JOIN_ROOM': {
|
||||||
|
// SET MESSAGES
|
||||||
|
const stateWithMessages = action.body.messages.length ? setMessages(state, action.body) : state;
|
||||||
|
|
||||||
|
// SET CURRENT ROOM
|
||||||
|
|
||||||
|
// if (!data.roomGames.length) {
|
||||||
|
// const errorAction = {
|
||||||
|
// type: 'ERR',
|
||||||
|
// message: 'JOIN_ROOM',
|
||||||
|
// body: { joinRoomError: 'Game room has no games' }
|
||||||
|
// }
|
||||||
|
// return stateReducer(stateWithMessages, errorAction);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// SET GAMES
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function roomsParse(roomsData) {
|
function setMessages(state, data) {
|
||||||
const rooms = JSON.parse(roomsData);
|
const messageAction = {
|
||||||
return rooms.rooms
|
type: 'MESSAGE',
|
||||||
|
message: 'SET_MESSAGES',
|
||||||
|
body: data.messages
|
||||||
|
}
|
||||||
|
stateReducer(state, messageAction)
|
||||||
}
|
}
|
|
@ -10,9 +10,45 @@ const roomsData = [
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
it('default returns state with rooms added', () => {
|
const joinRoomData = {
|
||||||
|
"roomGames": [
|
||||||
|
{
|
||||||
|
"id":1, "name":"main",
|
||||||
|
"description":"A general place to play Go",
|
||||||
|
"language":"EN", "komi":6.5, "handicap":0, "board_size":19,
|
||||||
|
"player_black":"anon", "player_white":"anon",
|
||||||
|
"player_black_rank":"K3", "player_white_rank":"K2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"content": "Hey! Welcome to the general room!", "username": "userOne", "admin":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
it('default returns state unaltered', () => {
|
||||||
const state = initState();
|
const state = initState();
|
||||||
const action = {type: 'ROOMS', message: 'SET_ROOMS', body: JSON.stringify(roomsData)};
|
const action = {type: 'ROOMS', message: '', body: JSON.stringify(roomsData)};
|
||||||
|
expect(stateReducer(state, action)).toEqual(state);
|
||||||
|
})
|
||||||
|
|
||||||
|
it('set rooms returns state with rooms added', () => {
|
||||||
|
const state = initState();
|
||||||
|
const action = {type: 'ROOMS', message: 'SET_ROOMS', body: roomsData};
|
||||||
expect(stateReducer(state, action)).toEqual({...state, rooms: roomsData});
|
expect(stateReducer(state, action)).toEqual({...state, rooms: roomsData});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('join room returns state with current room, games and messages all populated', () => {
|
||||||
|
const state = initState();
|
||||||
|
const action = {type: 'ROOMS', message: 'JOIN_ROOM', body: joinRoomData};
|
||||||
|
const normalizedRoomGames = joinRoomData.roomGames.map(game => {delete game.id; delete game.name; delete game.description; return game});
|
||||||
|
expect(stateReducer(state, action)).toEqual({
|
||||||
|
...state,
|
||||||
|
currentRoom: roomsData[0],
|
||||||
|
messages: joinRoomData.messages,
|
||||||
|
roomGames: [
|
||||||
|
joinRoomData.roomGames
|
||||||
|
]
|
||||||
|
})
|
||||||
|
});
|
|
@ -13,7 +13,7 @@ export type state = {
|
||||||
export type action = {
|
export type action = {
|
||||||
type: string,
|
type: string,
|
||||||
message: ?string,
|
message: ?string,
|
||||||
body: {}
|
body: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const stateReducer = (state: state, action: action): state => {
|
export const stateReducer = (state: state, action: action): state => {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import {stateReducer} from './stateReducer';
|
||||||
|
|
||||||
it('default returns state unaltered', () => {
|
it('default returns state unaltered', () => {
|
||||||
const state = {data: 'example'};
|
const state = {data: 'example'};
|
||||||
const action = {type: ''};
|
const action = {type: '', message: '', body:{}};
|
||||||
expect(stateReducer(state, action)).toBe(state);
|
expect(stateReducer(state, action)).toBe(state);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,9 @@ const indexService = async () => {
|
||||||
const response = await fetch(apiAddress,
|
const response = await fetch(apiAddress,
|
||||||
{method: 'GET', credentials: 'include', headers: headers}
|
{method: 'GET', credentials: 'include', headers: headers}
|
||||||
)
|
)
|
||||||
.then(res => {
|
.then(res => res.text())
|
||||||
return res.text();
|
.then(text => JSON.parse(text))
|
||||||
}).catch(err => {
|
.catch(err => {
|
||||||
return err;
|
return err;
|
||||||
});
|
});
|
||||||
return response;
|
return response;
|
||||||
|
|
|
@ -12,18 +12,25 @@ const indexService = async () => {
|
||||||
const response = await fetch(roomsAddress,
|
const response = await fetch(roomsAddress,
|
||||||
{method: 'GET', credentials: 'include', headers: headers}
|
{method: 'GET', credentials: 'include', headers: headers}
|
||||||
)
|
)
|
||||||
.then(res => {
|
.then(res => res.text())
|
||||||
return res.text();
|
.then(text => JSON.parse(text))
|
||||||
})
|
.catch(err => err);
|
||||||
// .then(text => {
|
|
||||||
// return JSON.parse(text)
|
return response;
|
||||||
// })
|
}
|
||||||
.catch(err => {
|
|
||||||
return err;
|
const getRoomService = async (roomIndex) => {
|
||||||
});
|
const response = await fetch(`${roomsAddress}/${roomIndex}`,
|
||||||
|
{method: 'GET', credentials: 'include', headers: headers}
|
||||||
|
)
|
||||||
|
.then(res => res.text())
|
||||||
|
.then(text => JSON.parse(text))
|
||||||
|
.catch(err => err);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
indexService
|
indexService,
|
||||||
|
getRoomService
|
||||||
}
|
}
|
|
@ -16,11 +16,10 @@ const loginService = async(formData) => {
|
||||||
body: JSON.stringify(formData),
|
body: JSON.stringify(formData),
|
||||||
headers: headers
|
headers: headers
|
||||||
})
|
})
|
||||||
.then(res => {
|
.then(res => res.text())
|
||||||
return res.text();
|
.then(text => JSON.parse(text))
|
||||||
}).catch(err => {
|
.catch(err => err);
|
||||||
return err;
|
|
||||||
});
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,11 +30,10 @@ const signupService = async (formData) => {
|
||||||
body: JSON.stringify(formData),
|
body: JSON.stringify(formData),
|
||||||
headers: headers
|
headers: headers
|
||||||
})
|
})
|
||||||
.then(res => {
|
.then(res => res.text())
|
||||||
return res.text();
|
.then(text => JSON.parse(text))
|
||||||
}).catch(err => {
|
.catch(err => err);
|
||||||
return err;
|
|
||||||
});
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue