230 lines
8.7 KiB
JavaScript
230 lines
8.7 KiB
JavaScript
import {
|
|
takeEvery,
|
|
put,
|
|
call,
|
|
delay,
|
|
select,
|
|
all,
|
|
} from 'redux-saga/effects';
|
|
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
|
|
|
|
import * as profileActions from './actions';
|
|
import { handleSaveProfileSelector, userAccountSelector } from './selectors';
|
|
|
|
jest.mock('./services', () => ({
|
|
getProfile: jest.fn(),
|
|
patchProfile: jest.fn(),
|
|
postProfilePhoto: jest.fn(),
|
|
deleteProfilePhoto: jest.fn(),
|
|
getPreferences: jest.fn(),
|
|
getAccount: jest.fn(),
|
|
getCourseCertificates: jest.fn(),
|
|
getCountryList: jest.fn(),
|
|
}));
|
|
|
|
jest.mock('@edx/frontend-platform/auth', () => ({
|
|
getAuthenticatedUser: jest.fn(),
|
|
}));
|
|
|
|
/* eslint-disable import/first */
|
|
import profileSaga, {
|
|
handleFetchProfile,
|
|
handleSaveProfile,
|
|
handleSaveProfilePhoto,
|
|
handleDeleteProfilePhoto,
|
|
} from './sagas';
|
|
import * as ProfileApiService from './services';
|
|
/* eslint-enable import/first */
|
|
|
|
describe('RootSaga', () => {
|
|
describe('profileSaga', () => {
|
|
it('should pass actions to the correct sagas', () => {
|
|
const gen = profileSaga();
|
|
|
|
expect(gen.next().value)
|
|
.toEqual(takeEvery(profileActions.FETCH_PROFILE.BASE, handleFetchProfile));
|
|
expect(gen.next().value)
|
|
.toEqual(takeEvery(profileActions.SAVE_PROFILE.BASE, handleSaveProfile));
|
|
expect(gen.next().value)
|
|
.toEqual(takeEvery(profileActions.SAVE_PROFILE_PHOTO.BASE, handleSaveProfilePhoto));
|
|
expect(gen.next().value)
|
|
.toEqual(takeEvery(profileActions.DELETE_PROFILE_PHOTO.BASE, handleDeleteProfilePhoto));
|
|
|
|
expect(gen.next().value).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('handleFetchProfile', () => {
|
|
it('should fetch certificates and preferences for the current user profile', () => {
|
|
const userAccount = {
|
|
username: 'gonzo',
|
|
other: 'data',
|
|
};
|
|
getAuthenticatedUser.mockReturnValue(userAccount);
|
|
const selectorData = {
|
|
userAccount,
|
|
};
|
|
|
|
const action = profileActions.fetchProfile('gonzo');
|
|
const gen = handleFetchProfile(action);
|
|
|
|
const result = [userAccount, [1, 2, 3], [], { preferences: 'stuff' }];
|
|
|
|
expect(gen.next().value).toEqual(select(userAccountSelector));
|
|
expect(gen.next(selectorData).value).toEqual(put(profileActions.fetchProfileBegin()));
|
|
expect(gen.next().value).toEqual(all([
|
|
call(ProfileApiService.getAccount, 'gonzo'),
|
|
call(ProfileApiService.getCourseCertificates, 'gonzo'),
|
|
call(ProfileApiService.getCountryList),
|
|
call(ProfileApiService.getPreferences, 'gonzo'),
|
|
]));
|
|
expect(gen.next(result).value)
|
|
.toEqual(put(profileActions.fetchProfileSuccess(userAccount, result[3], result[1], true, [])));
|
|
expect(gen.next().value).toEqual(put(profileActions.fetchProfileReset()));
|
|
expect(gen.next().value).toBeUndefined();
|
|
});
|
|
|
|
it('should fetch certificates and profile for some other user profile', () => {
|
|
const userAccount = {
|
|
username: 'gonzo',
|
|
other: 'data',
|
|
};
|
|
const countriesCodesList = [{ code: 'AX' }, { code: 'AL' }];
|
|
getAuthenticatedUser.mockReturnValue(userAccount);
|
|
const selectorData = {
|
|
userAccount,
|
|
};
|
|
|
|
const action = profileActions.fetchProfile('booyah');
|
|
const gen = handleFetchProfile(action);
|
|
|
|
const result = [{}, [1, 2, 3], countriesCodesList];
|
|
|
|
expect(gen.next().value).toEqual(select(userAccountSelector));
|
|
expect(gen.next(selectorData).value).toEqual(put(profileActions.fetchProfileBegin()));
|
|
expect(gen.next().value).toEqual(all([
|
|
call(ProfileApiService.getAccount, 'booyah'),
|
|
call(ProfileApiService.getCourseCertificates, 'booyah'),
|
|
call(ProfileApiService.getCountryList),
|
|
]));
|
|
expect(gen.next(result).value)
|
|
.toEqual(put(profileActions.fetchProfileSuccess(result[0], {}, result[1], false, countriesCodesList)));
|
|
expect(gen.next().value).toEqual(put(profileActions.fetchProfileReset()));
|
|
expect(gen.next().value).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('handleSaveProfile', () => {
|
|
const selectorData = {
|
|
username: 'my username',
|
|
drafts: {
|
|
name: 'Full Name',
|
|
},
|
|
preferences: {},
|
|
};
|
|
|
|
it('should successfully process a saveProfile request if there are no exceptions', () => {
|
|
const action = profileActions.saveProfile('ze form id', 'my username');
|
|
const gen = handleSaveProfile(action);
|
|
const profile = {
|
|
name: 'Full Name',
|
|
levelOfEducation: 'b',
|
|
};
|
|
expect(gen.next().value).toEqual(select(handleSaveProfileSelector));
|
|
expect(gen.next(selectorData).value).toEqual(put(profileActions.saveProfileBegin()));
|
|
expect(gen.next().value).toEqual(call(ProfileApiService.patchProfile, 'my username', {
|
|
name: 'Full Name',
|
|
}));
|
|
expect(gen.next(profile).value).toEqual(put(profileActions.saveProfileSuccess(profile, {})));
|
|
expect(gen.next().value).toEqual(delay(1000));
|
|
expect(gen.next().value).toEqual(put(profileActions.closeForm('ze form id')));
|
|
expect(gen.next().value).toEqual(delay(300));
|
|
expect(gen.next().value).toEqual(put(profileActions.saveProfileReset()));
|
|
expect(gen.next().value).toEqual(put(profileActions.resetDrafts()));
|
|
expect(gen.next().value).toBeUndefined();
|
|
});
|
|
|
|
it('should successfully publish a failure action on exception', () => {
|
|
const error = new Error('uhoh');
|
|
error.processedData = {
|
|
fieldErrors: {
|
|
uhoh: 'not good',
|
|
},
|
|
};
|
|
const action = profileActions.saveProfile(
|
|
'ze form id',
|
|
'my username',
|
|
);
|
|
const gen = handleSaveProfile(action);
|
|
|
|
expect(gen.next().value).toEqual(select(handleSaveProfileSelector));
|
|
expect(gen.next(selectorData).value).toEqual(put(profileActions.saveProfileBegin()));
|
|
const result = gen.throw(error);
|
|
expect(result.value).toEqual(put(profileActions.saveProfileFailure({ uhoh: 'not good' })));
|
|
expect(gen.next().value).toBeUndefined();
|
|
});
|
|
|
|
it('should reset profile if error has no processedData', () => {
|
|
const action = profileActions.saveProfile('formid', 'user1');
|
|
const gen = handleSaveProfile(action);
|
|
|
|
expect(gen.next().value).toEqual(select(handleSaveProfileSelector));
|
|
expect(gen.next(selectorData).value).toEqual(put(profileActions.saveProfileBegin()));
|
|
|
|
const err = new Error('oops');
|
|
const result = gen.throw(err);
|
|
expect(result.value).toEqual(put(profileActions.saveProfileReset()));
|
|
});
|
|
});
|
|
|
|
describe('handleSaveProfilePhoto', () => {
|
|
it('should save profile photo successfully', () => {
|
|
const action = profileActions.saveProfilePhoto('user1', { some: 'formdata' });
|
|
const gen = handleSaveProfilePhoto(action);
|
|
const fakePhoto = { url: 'photo.jpg' };
|
|
|
|
expect(gen.next().value).toEqual(put(profileActions.saveProfilePhotoBegin()));
|
|
expect(gen.next().value).toEqual(call(ProfileApiService.postProfilePhoto, 'user1', { some: 'formdata' }));
|
|
expect(gen.next(fakePhoto).value).toEqual(put(profileActions.saveProfilePhotoSuccess(fakePhoto)));
|
|
expect(gen.next().value).toEqual(put(profileActions.saveProfilePhotoReset()));
|
|
expect(gen.next().value).toBeUndefined();
|
|
});
|
|
|
|
it('should reset photo state on error', () => {
|
|
const action = profileActions.saveProfilePhoto('user1', {});
|
|
const gen = handleSaveProfilePhoto(action);
|
|
|
|
expect(gen.next().value).toEqual(put(profileActions.saveProfilePhotoBegin()));
|
|
|
|
const err = new Error('fail');
|
|
|
|
expect(gen.throw(err).value).toEqual(put(profileActions.saveProfilePhotoReset()));
|
|
expect(gen.next().done).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('handleDeleteProfilePhoto', () => {
|
|
it('should delete profile photo successfully', () => {
|
|
const action = profileActions.deleteProfilePhoto('user1');
|
|
const gen = handleDeleteProfilePhoto(action);
|
|
const fakeResult = { ok: true };
|
|
|
|
expect(gen.next().value).toEqual(put(profileActions.deleteProfilePhotoBegin()));
|
|
expect(gen.next().value).toEqual(call(ProfileApiService.deleteProfilePhoto, 'user1'));
|
|
expect(gen.next(fakeResult).value).toEqual(put(profileActions.deleteProfilePhotoSuccess(fakeResult)));
|
|
expect(gen.next().value).toEqual(put(profileActions.deleteProfilePhotoReset()));
|
|
expect(gen.next().value).toBeUndefined();
|
|
});
|
|
it('should reset photo state on error', () => {
|
|
const action = profileActions.saveProfilePhoto('user1', {});
|
|
const gen = handleSaveProfilePhoto(action);
|
|
|
|
expect(gen.next().value).toEqual(put(profileActions.saveProfilePhotoBegin()));
|
|
const err = new Error('fail');
|
|
expect(gen.throw(err).value).toEqual(put(profileActions.saveProfilePhotoReset()));
|
|
|
|
expect(gen.next().done).toBe(true);
|
|
});
|
|
});
|
|
});
|