From 8ff7c822f3495123b2f08e0179f37bdd6d797216 Mon Sep 17 00:00:00 2001 From: Adam Butterworth Date: Fri, 12 Apr 2019 14:39:47 -0400 Subject: [PATCH] fix: get profile photo changes from calls back into redux store (#154) * fix: get profile photo changes from calls back into redux store * test: update profile actions test --- src/actions/ProfileActions.js | 6 ++++-- src/actions/ProfileActions.test.js | 12 ++++++++++-- src/reducers/ProfilePageReducer.js | 4 ++++ src/sagas/RootSaga.js | 17 ++++------------- src/services/ProfileApiService.js | 19 +++++++++++++++++-- 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/actions/ProfileActions.js b/src/actions/ProfileActions.js index b9a535e..d83035b 100644 --- a/src/actions/ProfileActions.js +++ b/src/actions/ProfileActions.js @@ -75,8 +75,9 @@ export const saveProfilePhotoBegin = () => ({ type: SAVE_PROFILE_PHOTO.BEGIN, }); -export const saveProfilePhotoSuccess = () => ({ +export const saveProfilePhotoSuccess = profileImage => ({ type: SAVE_PROFILE_PHOTO.SUCCESS, + payload: { profileImage }, }); export const saveProfilePhotoReset = () => ({ @@ -101,8 +102,9 @@ export const deleteProfilePhotoBegin = () => ({ type: DELETE_PROFILE_PHOTO.BEGIN, }); -export const deleteProfilePhotoSuccess = () => ({ +export const deleteProfilePhotoSuccess = profileImage => ({ type: DELETE_PROFILE_PHOTO.SUCCESS, + payload: { profileImage }, }); export const deleteProfilePhotoReset = () => ({ diff --git a/src/actions/ProfileActions.test.js b/src/actions/ProfileActions.test.js index 4fa8edf..2703989 100644 --- a/src/actions/ProfileActions.test.js +++ b/src/actions/ProfileActions.test.js @@ -114,10 +114,14 @@ describe('SAVE profile photo actions', () => { }); it('should create an action to signal user profile photo save success', () => { + const newPhotoData = { hasImage: true }; const expectedAction = { type: SAVE_PROFILE_PHOTO.SUCCESS, + payload: { + profileImage: newPhotoData, + }, }; - expect(saveProfilePhotoSuccess()).toEqual(expectedAction); + expect(saveProfilePhotoSuccess(newPhotoData)).toEqual(expectedAction); }); it('should create an action to signal user profile photo save success', () => { @@ -157,10 +161,14 @@ describe('DELETE profile photo actions', () => { }); it('should create an action to signal user profile photo deletion success', () => { + const defaultPhotoData = { hasImage: false }; const expectedAction = { type: DELETE_PROFILE_PHOTO.SUCCESS, + payload: { + profileImage: defaultPhotoData, + }, }; - expect(deleteProfilePhotoSuccess()).toEqual(expectedAction); + expect(deleteProfilePhotoSuccess(defaultPhotoData)).toEqual(expectedAction); }); it('should create an action to signal user profile photo deletion success', () => { diff --git a/src/reducers/ProfilePageReducer.js b/src/reducers/ProfilePageReducer.js index a586982..7891251 100644 --- a/src/reducers/ProfilePageReducer.js +++ b/src/reducers/ProfilePageReducer.js @@ -79,6 +79,8 @@ const profilePage = (state = initialState, action) => { case SAVE_PROFILE_PHOTO.SUCCESS: return { ...state, + // Merge in new profile image data + account: Object.assign({}, state.account, { profileImage: action.payload.profileImage }), savePhotoState: 'complete', errors: {}, }; @@ -104,6 +106,8 @@ const profilePage = (state = initialState, action) => { case DELETE_PROFILE_PHOTO.SUCCESS: return { ...state, + // Merge in new profile image data (should be empty or default image) + account: Object.assign({}, state.account, { profileImage: action.payload.profileImage }), savePhotoState: 'complete', errors: {}, }; diff --git a/src/sagas/RootSaga.js b/src/sagas/RootSaga.js index cc725d7..22ddf56 100644 --- a/src/sagas/RootSaga.js +++ b/src/sagas/RootSaga.js @@ -9,7 +9,6 @@ import { fetchProfileBegin, fetchProfileSuccess, fetchProfileReset, - fetchProfile, SAVE_PROFILE, saveProfileBegin, saveProfileSuccess, @@ -155,12 +154,8 @@ export function* handleSaveProfilePhoto(action) { try { yield put(saveProfilePhotoBegin()); - yield call(ProfileApiService.postProfilePhoto, username, formData); - - // Get the account data. Saving doesn't return anything on success. - yield handleFetchProfile(fetchProfile(username)); - - yield put(saveProfilePhotoSuccess()); + const photoResult = yield call(ProfileApiService.postProfilePhoto, username, formData); + yield put(saveProfilePhotoSuccess(photoResult)); yield put(saveProfilePhotoReset()); } catch (e) { if (e.processedData) { @@ -178,12 +173,8 @@ export function* handleDeleteProfilePhoto(action) { try { yield put(deleteProfilePhotoBegin()); - yield call(ProfileApiService.deleteProfilePhoto, username); - - // Get the account data. Saving doesn't return anything on success. - yield handleFetchProfile(fetchProfile(username)); - - yield put(deleteProfilePhotoSuccess()); + const photoResult = yield call(ProfileApiService.deleteProfilePhoto, username); + yield put(deleteProfilePhotoSuccess(photoResult)); yield put(deleteProfilePhotoReset()); } catch (e) { LoggingService.logAPIErrorResponse(e); diff --git a/src/services/ProfileApiService.js b/src/services/ProfileApiService.js index 9e21381..fc8a7dd 100644 --- a/src/services/ProfileApiService.js +++ b/src/services/ProfileApiService.js @@ -53,6 +53,7 @@ export async function patchProfile(username, params) { // POST PROFILE PHOTO export async function postProfilePhoto(username, formData) { + // eslint-disable-next-line no-unused-vars const { data } = await apiClient.post( `${configuration.ACCOUNTS_API_BASE_URL}/${username}/image`, formData, @@ -65,14 +66,28 @@ export async function postProfilePhoto(username, formData) { processAndThrowError(error, camelCaseObject); }); - return camelCaseObject(data); + // TODO: Someday in the future the POST photo endpoint + // will return the new values. At that time we should + // use the commented line below instead of the separate + // getAccount request that follows. + // return camelCaseObject(data); + const updatedData = await getAccount(username); + return updatedData.profileImage; } // DELETE PROFILE PHOTO export async function deleteProfilePhoto(username) { + // eslint-disable-next-line no-unused-vars const { data } = await apiClient.delete(`${configuration.ACCOUNTS_API_BASE_URL}/${username}/image`); - return camelCaseObject(data); + + // TODO: Someday in the future the POST photo endpoint + // will return the new values. At that time we should + // use the commented line below instead of the separate + // getAccount request that follows. + // return camelCaseObject(data); + const updatedData = await getAccount(username); + return updatedData.profileImage; } // GET PREFERENCES