Break out utils functions and move preferences api calls to profileapiservice
This commit is contained in:
committed by
Adam Butterworth
parent
64c8a78c65
commit
a3b7999627
@@ -1,9 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import { getAuthenticatedAPIClient } from '@edx/frontend-auth';
|
||||
|
||||
import { configuration } from '../config';
|
||||
|
||||
const lmsBaseUrl = process.env.LMS_BASE_URL;
|
||||
|
||||
const apiClient = getAuthenticatedAPIClient({
|
||||
appBaseUrl: configuration.BASE_URL,
|
||||
@@ -16,78 +14,5 @@ const apiClient = getAuthenticatedAPIClient({
|
||||
csrfCookieName: configuration.CSRF_COOKIE_NAME,
|
||||
});
|
||||
|
||||
const clientServerKeyMap = {
|
||||
bio: 'bio',
|
||||
socialLinks: 'social_links',
|
||||
country: 'country',
|
||||
education: 'level_of_education',
|
||||
fullName: 'name',
|
||||
username: 'username',
|
||||
profileImage: 'profile_image',
|
||||
dateJoined: 'date_joined',
|
||||
languageProficiencies: 'language_proficiencies',
|
||||
accountPrivacy: 'account_privacy',
|
||||
};
|
||||
|
||||
const serverClientKeyMap = _.invert(clientServerKeyMap);
|
||||
|
||||
|
||||
export function getPreferences(username) {
|
||||
const url = `${lmsBaseUrl}/api/user/v1/preferences/${username}`;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
apiClient.get(url)
|
||||
.then(({ data }) => {
|
||||
// Unflatten server response
|
||||
// visibility.social_links: 'value' becomes { visibility: { socialLinks: 'value' }}
|
||||
const preferences = {};
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
_.set(
|
||||
preferences,
|
||||
key.split('.').map(pathKey => serverClientKeyMap[pathKey] || pathKey),
|
||||
value,
|
||||
);
|
||||
});
|
||||
resolve(preferences);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function savePreferences(username, preferences) {
|
||||
const url = `${lmsBaseUrl}/api/user/v1/preferences/${username}`;
|
||||
|
||||
// Flatten object for server
|
||||
// { visibility: { socialLinks: 'value' }} becomes visibility.social_links: 'value'
|
||||
const data = {};
|
||||
const flattenAndTransformKeys = (prevKeys, currentValue) => {
|
||||
if (typeof currentValue !== 'object') {
|
||||
const serverKey = prevKeys.map(key => serverClientKeyMap[key] || key).join('.');
|
||||
data[serverKey] = currentValue;
|
||||
return;
|
||||
}
|
||||
Object.keys(currentValue).forEach((key) => {
|
||||
flattenAndTransformKeys(prevKeys.concat(key), currentValue[key]);
|
||||
});
|
||||
};
|
||||
flattenAndTransformKeys([], preferences);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
apiClient.patch(
|
||||
url,
|
||||
data,
|
||||
{ headers: { 'Content-Type': 'application/merge-patch+json' } },
|
||||
)
|
||||
.then((response) => {
|
||||
resolve(response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export default apiClient;
|
||||
|
||||
@@ -39,7 +39,6 @@ import {
|
||||
} from '../actions/preferences';
|
||||
|
||||
import * as ProfileApiService from '../services/ProfileApiService';
|
||||
import { getPreferences, savePreferences } from '../data/apiClient';
|
||||
|
||||
|
||||
const PROP_TO_STATE_MAP = {
|
||||
@@ -139,7 +138,7 @@ export function* handleFetchPreferences(action) {
|
||||
const { username } = action.payload;
|
||||
try {
|
||||
yield put(fetchPreferencesBegin());
|
||||
const userPreferences = yield call(getPreferences, username);
|
||||
const userPreferences = yield call(ProfileApiService.getPreferences, username);
|
||||
yield put(fetchPreferencesSuccess(userPreferences));
|
||||
yield put(fetchPreferencesReset());
|
||||
} catch (e) {
|
||||
@@ -151,7 +150,7 @@ export function* handleSavePreferences(action) {
|
||||
const { username, preferences } = action.payload;
|
||||
try {
|
||||
yield put(savePreferencesBegin());
|
||||
yield call(savePreferences, username, preferences);
|
||||
yield call(ProfileApiService.savePreferences, username, preferences);
|
||||
yield put(savePreferencesSuccess(preferences));
|
||||
yield put(savePreferencesReset());
|
||||
} catch (e) {
|
||||
|
||||
@@ -1,11 +1,27 @@
|
||||
import camelcaseKeys from 'camelcase-keys';
|
||||
import snakecaseKeys from 'snakecase-keys';
|
||||
import _ from 'lodash';
|
||||
|
||||
import apiClient from '../data/apiClient';
|
||||
import { configuration } from '../config';
|
||||
import { unflattenAndTransformKeys, flattenAndTransformKeys } from './utils';
|
||||
|
||||
const accountsApiBaseUrl = `${configuration.LMS_BASE_URL}/api/user/v1/accounts`;
|
||||
const preferencesApiBaseUrl = `${configuration.LMS_BASE_URL}/api/user/v1/preferences`;
|
||||
const clientServerKeyMap = {
|
||||
bio: 'bio',
|
||||
socialLinks: 'social_links',
|
||||
country: 'country',
|
||||
education: 'level_of_education',
|
||||
fullName: 'name',
|
||||
username: 'username',
|
||||
profileImage: 'profile_image',
|
||||
dateJoined: 'date_joined',
|
||||
languageProficiencies: 'language_proficiencies',
|
||||
accountPrivacy: 'account_privacy',
|
||||
};
|
||||
const serverClientKeyMap = _.invert(clientServerKeyMap);
|
||||
|
||||
|
||||
export function getProfile(username) {
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -72,9 +88,35 @@ export function deleteProfilePhoto(username) {
|
||||
return apiClient.delete(`${accountsApiBaseUrl}/${username}/image`);
|
||||
}
|
||||
|
||||
export function getUserPreference(username, preferenceKey) {
|
||||
export function getPreferences(username) {
|
||||
const url = `${preferencesApiBaseUrl}/${username}`;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
apiClient.get(`${preferencesApiBaseUrl}/${username}/${preferenceKey}`)
|
||||
apiClient.get(url)
|
||||
.then(({ data }) => {
|
||||
// Unflatten server response
|
||||
// visibility.social_links: 'value' becomes { visibility: { socialLinks: 'value' }}
|
||||
resolve(unflattenAndTransformKeys(data, key => serverClientKeyMap[key] || key));
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function savePreferences(username, preferences) {
|
||||
const url = `${preferencesApiBaseUrl}/${username}`;
|
||||
|
||||
// Flatten object for server
|
||||
// { visibility: { socialLinks: 'value' }} becomes visibility.social_links: 'value'
|
||||
const data = flattenAndTransformKeys(preferences, key => clientServerKeyMap[key] || key);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
apiClient.patch(
|
||||
url,
|
||||
data,
|
||||
{ headers: { 'Content-Type': 'application/merge-patch+json' } },
|
||||
)
|
||||
.then((response) => {
|
||||
resolve(response.data);
|
||||
})
|
||||
@@ -83,4 +125,3 @@ export function getUserPreference(username, preferenceKey) {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
28
src/services/utils.js
Normal file
28
src/services/utils.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import _ from 'lodash';
|
||||
|
||||
export function unflattenAndTransformKeys(obj, transformer) {
|
||||
const newObj = {};
|
||||
|
||||
Object.entries(obj).forEach(([key, value]) => {
|
||||
_.set(newObj, key.split('.').map(transformer), value);
|
||||
});
|
||||
|
||||
return newObj;
|
||||
}
|
||||
|
||||
export function flattenAndTransformKeys(srcObj, transformer = key => key) {
|
||||
const flatten = (obj, prevKeys = []) => (Object.entries(obj).reduce((acc, [key, value]) => {
|
||||
const tKey = transformer(key);
|
||||
const keys = prevKeys.concat(tKey);
|
||||
|
||||
if (value && typeof value === 'object') {
|
||||
Object.assign(acc, flatten(value, keys));
|
||||
} else {
|
||||
acc[keys.join('.')] = value;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {}));
|
||||
|
||||
return flatten(srcObj);
|
||||
}
|
||||
47
src/services/utils.test.js
Normal file
47
src/services/utils.test.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import { flattenAndTransformKeys, unflattenAndTransformKeys } from './utils';
|
||||
|
||||
|
||||
describe('unflattenAndTransformKeys', () => {
|
||||
it('should unflatten objects and transform keys', () => {
|
||||
const sourceObject = {
|
||||
userlocation: 'US',
|
||||
'visibility.sociallinks': 'private',
|
||||
'visibility.education': 'private',
|
||||
'visibility.bio': 'private',
|
||||
};
|
||||
|
||||
const result = unflattenAndTransformKeys(sourceObject, key => key.toUpperCase());
|
||||
|
||||
expect(result).toEqual({
|
||||
USERLOCATION: 'US',
|
||||
VISIBILITY: {
|
||||
SOCIALLINKS: 'private',
|
||||
EDUCATION: 'private',
|
||||
BIO: 'private',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('flattenAndTransformKeys', () => {
|
||||
it('should flatten objects and transform keys', () => {
|
||||
const sourceObject = {
|
||||
USERLOCATION: 'US',
|
||||
VISIBILITY: {
|
||||
SOCIALLINKS: 'private',
|
||||
EDUCATION: 'private',
|
||||
BIO: 'private',
|
||||
},
|
||||
};
|
||||
|
||||
const result = flattenAndTransformKeys(sourceObject, key => key.toLowerCase());
|
||||
|
||||
expect(result).toEqual({
|
||||
userlocation: 'US',
|
||||
'visibility.sociallinks': 'private',
|
||||
'visibility.education': 'private',
|
||||
'visibility.bio': 'private',
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user