This commit is contained in:
Christoph Wolfes
2018-07-25 14:35:37 +02:00
5 changed files with 99 additions and 82 deletions

View File

@@ -50,10 +50,8 @@ const mapDispatchToProps = dispatch => {
}; };
const mapStateToProps = (state, ownProps) => { const mapStateToProps = (state, ownProps) => {
if (state.users && state.users.users) { if (state.users && state.users.create) {
return { return state.users.create;
loading: state.users.users.loading
};
} }
return {}; return {};
}; };

View File

@@ -87,8 +87,8 @@ class SingleUser extends React.Component<Props> {
const mapStateToProps = (state, ownProps) => { const mapStateToProps = (state, ownProps) => {
const name = ownProps.match.params.name; const name = ownProps.match.params.name;
let userEntry; let userEntry;
if (state.users && state.users.usersByNames) { if (state.users && state.users.byNames) {
userEntry = state.users.usersByNames[name]; userEntry = state.users.byNames[name];
} }
return { return {

View File

@@ -58,10 +58,10 @@ const mapStateToProps = state => {
let error = null; let error = null;
let loading = false; let loading = false;
let canAddUsers = false; let canAddUsers = false;
if (state.users && state.users.users) { if (state.users && state.users.list) {
error = state.users.users.error; error = state.users.list.error;
canAddUsers = state.users.users.userCreatePermission; canAddUsers = state.users.list.userCreatePermission;
loading = state.users.users.loading; loading = state.users.list.loading;
} }
return { return {
userEntries, userEntries,

View File

@@ -188,21 +188,17 @@ export function modifyUser(user: User) {
}; };
} }
function modifyUserPending(user: User): Action { export function modifyUserPending(user: User): Action {
return { return {
type: MODIFY_USER_PENDING, type: MODIFY_USER_PENDING,
payload: { payload: user
user
}
}; };
} }
function modifyUserSuccess(user: User): Action { export function modifyUserSuccess(user: User): Action {
return { return {
type: MODIFY_USER_SUCCESS, type: MODIFY_USER_SUCCESS,
payload: { payload: user
user
}
}; };
} }
@@ -262,10 +258,10 @@ export function deleteUserFailure(user: User, error: Error): Action {
//helper functions //helper functions
export function getUsersFromState(state: any) { export function getUsersFromState(state: any) {
if (!state.users.users) { if (!state.users.list) {
return null; return null;
} }
const userNames = state.users.users.entries; const userNames = state.users.list.entries;
if (!userNames) { if (!userNames) {
return null; return null;
} }
@@ -312,11 +308,7 @@ function deleteUserInEntries(users: [], userName: any) {
return newUsers; return newUsers;
} }
const reduceUsersByNames = ( const reducerByName = (state: any, username: string, newUserState: any) => {
state: any,
username: string,
newUserState: any
) => {
const newUsersByNames = { const newUsersByNames = {
...state.byNames, ...state.byNames,
[username]: newUserState [username]: newUserState
@@ -334,22 +326,21 @@ export default function reducer(state: any = {}, action: any = {}) {
case FETCH_USERS_PENDING: case FETCH_USERS_PENDING:
return { return {
...state, ...state,
users: { list: {
loading: true loading: true
} }
}; };
case FETCH_USERS_SUCCESS: case FETCH_USERS_SUCCESS:
// return red(state, action.payload._embedded.users);
const users = action.payload._embedded.users; const users = action.payload._embedded.users;
const userNames = users.map(user => user.name); const userNames = users.map(user => user.name);
const byNames = extractUsersByNames(users, userNames, state.byNames); const byNames = extractUsersByNames(users, userNames, state.byNames);
return { return {
...state, ...state,
userCreatePermission: action.payload._links.create ? true : false,
list: { list: {
error: null, error: null,
entries: userNames, entries: userNames,
loading: false loading: false,
userCreatePermission: action.payload._links.create ? true : false
}, },
byNames byNames
}; };
@@ -364,50 +355,50 @@ export default function reducer(state: any = {}, action: any = {}) {
}; };
// Fetch single user cases // Fetch single user cases
case FETCH_USER_PENDING: case FETCH_USER_PENDING:
return reduceUsersByNames(state, action.payload.name, { return reducerByName(state, action.payload.name, {
loading: true, loading: true,
error: null error: null
}); });
case FETCH_USER_SUCCESS: case FETCH_USER_SUCCESS:
return reduceUsersByNames(state, action.payload.name, { return reducerByName(state, action.payload.name, {
loading: false, loading: false,
error: null, error: null,
entry: action.payload entry: action.payload
}); });
case FETCH_USER_FAILURE: case FETCH_USER_FAILURE:
return reduceUsersByNames(state, action.payload.username, { return reducerByName(state, action.payload.username, {
loading: false, loading: false,
error: action.payload.error error: action.payload.error
}); });
// Delete single user cases // Delete single user cases
case DELETE_USER: case DELETE_USER:
return reduceUsersByNames(state, action.payload.name, { return reducerByName(state, action.payload.name, {
loading: true, loading: true,
error: null, error: null,
entry: action.payload entry: action.payload
}); });
case DELETE_USER_SUCCESS: case DELETE_USER_SUCCESS:
const newUserByNames = deleteUserInUsersByNames(state.usersByNames, [ const newUserByNames = deleteUserInUsersByNames(state.byNames, [
action.payload.name action.payload.name
]); ]);
const newUserEntries = deleteUserInEntries(state.users.entries, [ const newUserEntries = deleteUserInEntries(state.list.entries, [
action.payload.name action.payload.name
]); ]);
return { return {
...state, ...state,
users: { list: {
...state.users, ...state.list,
entries: newUserEntries entries: newUserEntries
}, },
usersByNames: newUserByNames byNames: newUserByNames
}; };
case DELETE_USER_FAILURE: case DELETE_USER_FAILURE:
return reduceUsersByNames(state, action.payload.user.name, { return reducerByName(state, action.payload.user.name, {
loading: false, loading: false,
error: action.payload.error, error: action.payload.error,
entry: action.payload.user entry: action.payload.user
@@ -417,55 +408,39 @@ export default function reducer(state: any = {}, action: any = {}) {
case CREATE_USER_PENDING: case CREATE_USER_PENDING:
return { return {
...state, ...state,
list: { create: {
...state.list, loading: true
loading: true,
error: null
} }
}; };
case CREATE_USER_SUCCESS: case CREATE_USER_SUCCESS:
return { return {
...state, ...state,
list: { create: {
...state.users, loading: false
loading: false,
error: null
} }
}; };
case CREATE_USER_FAILURE: case CREATE_USER_FAILURE:
return { return {
...state, ...state,
list: { create: {
...state.users,
loading: false, loading: false,
error: action.payload error: action.payload
} }
}; };
// Update single user cases // Update single user cases
case MODIFY_USER_PENDING: case MODIFY_USER_PENDING:
return { return reducerByName(state, action.payload.name, {
...state, loading: true
usersByNames: { });
...state.usersByNames,
[action.user.name]: {
loading: true,
error: null,
entry: action.user
}
}
};
case MODIFY_USER_SUCCESS: case MODIFY_USER_SUCCESS:
return { return reducerByName(state, action.payload.name, {
...state, entry: action.payload
usersByNames: { });
...state.usersByNames, case MODIFY_USER_FAILURE:
[action.user.name]: { return reducerByName(state, action.payload.user.name, {
loading: false, error: action.payload.error
error: null, });
entry: action.user
}
}
};
default: default:
return state; return state;
} }

View File

@@ -31,6 +31,8 @@ import {
createUser, createUser,
createUserSuccess, createUserSuccess,
createUserFailure, createUserFailure,
modifyUserPending,
modifyUserSuccess,
modifyUserFailure, modifyUserFailure,
fetchUserSuccess, fetchUserSuccess,
deleteUserSuccess, deleteUserSuccess,
@@ -317,8 +319,8 @@ describe("users fetch()", () => {
describe("users reducer", () => { describe("users reducer", () => {
it("should update state correctly according to FETCH_USERS_PENDING action", () => { it("should update state correctly according to FETCH_USERS_PENDING action", () => {
const newState = reducer({}, fetchUsersPending()); const newState = reducer({}, fetchUsersPending());
expect(newState.users.loading).toBeTruthy(); expect(newState.list.loading).toBeTruthy();
expect(newState.users.error).toBeFalsy(); expect(newState.list.error).toBeFalsy();
}); });
it("should update state correctly according to FETCH_USERS_SUCCESS action", () => { it("should update state correctly according to FETCH_USERS_SUCCESS action", () => {
@@ -327,7 +329,8 @@ describe("users reducer", () => {
expect(newState.list).toEqual({ expect(newState.list).toEqual({
entries: ["zaphod", "ford"], entries: ["zaphod", "ford"],
error: null, error: null,
loading: false loading: false,
userCreatePermission: true
}); });
expect(newState.byNames).toEqual({ expect(newState.byNames).toEqual({
@@ -339,7 +342,7 @@ describe("users reducer", () => {
} }
}); });
expect(newState.userCreatePermission).toBeTruthy(); expect(newState.list.userCreatePermission).toBeTruthy();
}); });
test("should update state correctly according to DELETE_USER action", () => { test("should update state correctly according to DELETE_USER action", () => {
@@ -432,19 +435,19 @@ describe("users reducer", () => {
it("should set userCreatePermission to true if update link is present", () => { it("should set userCreatePermission to true if update link is present", () => {
const newState = reducer({}, fetchUsersSuccess(responseBody)); const newState = reducer({}, fetchUsersSuccess(responseBody));
expect(newState.userCreatePermission).toBeTruthy(); expect(newState.list.userCreatePermission).toBeTruthy();
}); });
it("should update state correctly according to CREATE_USER_PENDING action", () => { it("should update state correctly according to CREATE_USER_PENDING action", () => {
const newState = reducer({}, createUserPending(userZaphod)); const newState = reducer({}, createUserPending(userZaphod));
expect(newState.list.loading).toBeTruthy(); expect(newState.create.loading).toBeTruthy();
expect(newState.list.error).toBeNull(); expect(newState.create.error).toBeFalsy();
}); });
it("should update state correctly according to CREATE_USER_SUCCESS action", () => { it("should update state correctly according to CREATE_USER_SUCCESS action", () => {
const newState = reducer({ loading: true }, createUserSuccess()); const newState = reducer({ loading: true }, createUserSuccess());
expect(newState.list.loading).toBeFalsy(); expect(newState.create.loading).toBeFalsy();
expect(newState.list.error).toBeNull(); expect(newState.create.error).toBeFalsy();
}); });
it("should set the loading to false and the error if user could not be created", () => { it("should set the loading to false and the error if user could not be created", () => {
@@ -452,8 +455,8 @@ describe("users reducer", () => {
{ loading: true, error: null }, { loading: true, error: null },
createUserFailure(userFord, new Error("kaputt kaputt")) createUserFailure(userFord, new Error("kaputt kaputt"))
); );
expect(newState.list.loading).toBeFalsy(); expect(newState.create.loading).toBeFalsy();
expect(newState.list.error).toEqual(new Error("kaputt kaputt")); expect(newState.create.error).toEqual(new Error("kaputt kaputt"));
}); });
it("should update state according to FETCH_USER_PENDING action", () => { it("should update state according to FETCH_USER_PENDING action", () => {
@@ -500,4 +503,45 @@ describe("users reducer", () => {
expect(newState.byNames["ford"].entry).toBe(userFord); expect(newState.byNames["ford"].entry).toBe(userFord);
expect(newState.list.entries).toEqual(["zaphod"]); expect(newState.list.entries).toEqual(["zaphod"]);
}); });
it("should update state according to MODIFY_USER_PENDING action", () => {
const newState = reducer(
{
error: new Error("something"),
entry: {}
},
modifyUserPending(userFord)
);
expect(newState.byNames["ford"].loading).toBeTruthy();
expect(newState.byNames["ford"].error).toBeFalsy();
expect(newState.byNames["ford"].entry).toBeFalsy();
});
it("should update state according to MODIFY_USER_SUCCESS action", () => {
const newState = reducer(
{
loading: true,
error: new Error("something"),
entry: {}
},
modifyUserSuccess(userFord)
);
expect(newState.byNames["ford"].loading).toBeFalsy();
expect(newState.byNames["ford"].error).toBeFalsy();
expect(newState.byNames["ford"].entry).toBe(userFord);
});
it("should update state according to MODIFY_USER_SUCCESS action", () => {
const error = new Error("something went wrong");
const newState = reducer(
{
loading: true,
entry: {}
},
modifyUserFailure(userFord, error)
);
expect(newState.byNames["ford"].loading).toBeFalsy();
expect(newState.byNames["ford"].error).toBe(error);
expect(newState.byNames["ford"].entry).toBeFalsy();
});
}); });