From 8d1251186bf779c6830cb7cf91f8568858f5f086 Mon Sep 17 00:00:00 2001 From: Boris Yankov Date: Thu, 14 Mar 2019 17:58:14 +0200 Subject: [PATCH] UsersReducers Fixes ##3397 Part of ...??? --- src/users/__tests__/usersReducers-test.js | 135 +++++++++++++++++++++- src/users/usersReducers.js | 54 ++++++++- 2 files changed, 184 insertions(+), 5 deletions(-) diff --git a/src/users/__tests__/usersReducers-test.js b/src/users/__tests__/usersReducers-test.js index a7de9ae4273..6a66b59b7b8 100644 --- a/src/users/__tests__/usersReducers-test.js +++ b/src/users/__tests__/usersReducers-test.js @@ -1,6 +1,11 @@ import deepFreeze from 'deep-freeze'; -import { REALM_INIT, EVENT_USER_ADD, ACCOUNT_SWITCH } from '../../actionConstants'; +import { + REALM_INIT, + EVENT_USER_ADD, + ACCOUNT_SWITCH, + EVENT_USER_UPDATE, +} from '../../actionConstants'; import usersReducers from '../usersReducers'; describe('usersReducers', () => { @@ -96,6 +101,134 @@ describe('usersReducers', () => { }); }); + describe('EVENT_USER_UPDATE', () => { + test('updating non existing user does not mutate state', () => { + const initialState = deepFreeze([ + { + user_id: 1, + full_name: 'Some Guy', + }, + ]); + const action = deepFreeze({ + type: EVENT_USER_UPDATE, + person: { + user_id: 2, + full_name: 'New Name', + }, + }); + + const actualState = usersReducers(initialState, action); + + expect(actualState).toEqual(initialState); + }); + + test('updating name', () => { + const initialState = deepFreeze([ + { + user_id: 1, + full_name: 'Some Guy', + }, + ]); + const action = deepFreeze({ + type: EVENT_USER_UPDATE, + person: { + user_id: 1, + full_name: 'New Name', + }, + }); + const expectedState = [ + { + user_id: 1, + full_name: 'New Name', + }, + ]; + + const actualState = usersReducers(initialState, action); + + expect(actualState).toEqual(expectedState); + }); + + test('updating avatar', () => { + const initialState = deepFreeze([ + { + user_id: 1, + full_name: 'Some Guy', + avatar_url: 'https://example.com/avatar.png', + }, + ]); + const action = deepFreeze({ + type: EVENT_USER_UPDATE, + person: { + user_id: 1, + avatar_source: 'G', + avatar_url: 'https://example.com/new-avatar.png', + avatar_url_medium: 'https://example.com/new-avatar-medium.png', + }, + }); + const expectedState = [ + { + user_id: 1, + full_name: 'Some Guy', + avatar_url: 'https://example.com/new-avatar.png', + }, + ]; + + const actualState = usersReducers(initialState, action); + + expect(actualState).toEqual(expectedState); + }); + + test('updating custom profile field', () => { + const initialState = deepFreeze([ + { + user_id: 1, + full_name: 'Some Guy', + profile_data: { + 1: { + value: 'CA', + rendered_value: null, + }, + 2: { + value: 'Blue', + rendered_value: null, + }, + }, + }, + ]); + const action = deepFreeze({ + type: EVENT_USER_UPDATE, + person: { + user_id: 1, + custom_profile_field: { + id: 2, + value: 'Red', + rendered_value: null, + }, + }, + }); + const expectedState = [ + { + user_id: 1, + full_name: 'Some Guy', + profile_data: { + 1: { + value: 'CA', + rendered_value: null, + }, + 2: { + value: 'Red', + rendered_value: null, + }, + }, + }, + ]; + + const actualState = usersReducers(initialState, action); + + expect(actualState).toEqual(expectedState); + }); + }); + describe('ACCOUNT_SWITCH', () => { test('resets state to initial state', () => { const initialState = deepFreeze([ diff --git a/src/users/usersReducers.js b/src/users/usersReducers.js index 31f361468c2..f814a93ea9d 100644 --- a/src/users/usersReducers.js +++ b/src/users/usersReducers.js @@ -1,5 +1,7 @@ /* @flow strict-local */ -import type { UsersState, Action } from '../types'; +import isEqual from 'lodash.isequal'; + +import type { User, UsersState, UserUpdatePayload, Action } from '../types'; import { LOGOUT, LOGIN_SUCCESS, @@ -13,6 +15,37 @@ import { NULL_ARRAY } from '../nullObjects'; const initialState: UsersState = NULL_ARRAY; +const getUpdatedUser = (oldValue: User, updateData: UserUpdatePayload): User => { + if (updateData.full_name !== undefined) { + // update full name + return { + ...oldValue, + full_name: updateData.full_name, + }; + } else if (updateData.avatar_url !== undefined) { + // update avatar + return { + ...oldValue, + avatar_url: updateData.avatar_url, + }; + } else if (updateData.custom_profile_field) { + // update a profile field + return { + ...oldValue, + profile_data: { + ...oldValue.profile_data, + [updateData.custom_profile_field.id]: { + value: updateData.custom_profile_field.value, + rendered_value: updateData.custom_profile_field.rendered_value, + }, + }, + }; + } + + // unsupported/unrecognized update, do nothing + return oldValue; +}; + export default (state: UsersState = initialState, action: Action): UsersState => { switch (action.type) { case LOGOUT: @@ -29,9 +62,22 @@ export default (state: UsersState = initialState, action: Action): UsersState => case EVENT_USER_REMOVE: return state; // TODO - case EVENT_USER_UPDATE: - console.log('UPDATE!!!', action); - return state; // TODO + case EVENT_USER_UPDATE: { + const userIndex = state.findIndex(x => x.user_id === action.person.user_id); + const oldUser: User = state[userIndex]; + + if (userIndex === -1) { + return state; + } + + const updatedUser = getUpdatedUser(oldUser, action.person); + + if (isEqual(updatedUser, oldUser)) { + return state; + } + + return [...state.slice(0, userIndex), updatedUser, ...state.slice(userIndex + 1)]; + } default: return state;