feat: integrated notification preferences v2 API (#1280)

This commit is contained in:
Ahtisham Shahid
2025-07-04 17:00:09 +05:00
committed by GitHub
parent 929a34a0f6
commit d760be1a53
6 changed files with 85 additions and 1 deletions

1
.env
View File

@@ -37,3 +37,4 @@ SUPPORT_URL_TO_UNLINK_SOCIAL_MEDIA_ACCOUNT='https://help.edx.org/edxlearner/s/ar
COUNTRIES_WITH_DELETE_ACCOUNT_DISABLED='[]'
# Fallback in local style files
PARAGON_THEME_URLS={}
ENABLE_PREFERENCES_V2='false'

View File

@@ -38,3 +38,4 @@ SUPPORT_URL_TO_UNLINK_SOCIAL_MEDIA_ACCOUNT='https://help.edx.org/edxlearner/s/ar
COUNTRIES_WITH_DELETE_ACCOUNT_DISABLED='[]'
# Fallback in local style files
PARAGON_THEME_URLS={}
ENABLE_PREFERENCES_V2='false'

View File

@@ -34,3 +34,4 @@ LEARNER_FEEDBACK_URL=''
SUPPORT_URL_TO_UNLINK_SOCIAL_MEDIA_ACCOUNT='https://help.edx.org/edxlearner/s/article/How-do-I-link-or-unlink-my-edX-account-to-a-social-media-account'
COUNTRIES_WITH_DELETE_ACCOUNT_DISABLED='[]'
PARAGON_THEME_URLS={}
ENABLE_PREFERENCES_V2='false'

View File

@@ -74,6 +74,7 @@ initialize({
MARKETING_EMAILS_OPT_IN: (process.env.MARKETING_EMAILS_OPT_IN || false),
PASSWORD_RESET_SUPPORT_LINK: process.env.PASSWORD_RESET_SUPPORT_LINK,
LEARNER_FEEDBACK_URL: process.env.LEARNER_FEEDBACK_URL,
ENABLE_PREFERENCES_V2: process.env.ENABLE_PREFERENCES_V2 || false,
}, 'App loadConfig override handler');
},
},

View File

@@ -11,6 +11,10 @@ import { fireEvent, render, screen } from '@testing-library/react';
import { defaultState } from './data/reducers';
import NotificationPreferences from './NotificationPreferences';
import { LOADING_STATUS, SUCCESS_STATUS } from '../constants';
import {
getCourseNotificationPreferences,
postPreferenceToggle,
} from './data/service';
const courseId = 'selected-course-id';
@@ -191,3 +195,70 @@ describe('Notification Preferences', () => {
}
});
});
describe('Notification Preferences API v2 Logic', () => {
const LMS_BASE_URL = 'https://lms.example.com';
let mockHttpClient;
beforeEach(() => {
jest.clearAllMocks();
mockHttpClient = {
get: jest.fn().mockResolvedValue({ data: {} }),
put: jest.fn().mockResolvedValue({ data: {} }),
post: jest.fn().mockResolvedValue({ data: {} }),
patch: jest.fn().mockResolvedValue({ data: {} }),
};
auth.getAuthenticatedHttpClient.mockReturnValue(mockHttpClient);
setConfig({ LMS_BASE_URL });
});
describe('getCourseNotificationPreferences', () => {
it('should call the v2 configurations URL when ENABLE_PREFERENCES_V2 is true', async () => {
setConfig({ LMS_BASE_URL, ENABLE_PREFERENCES_V2: 'true' });
const expectedUrl = `${LMS_BASE_URL}/api/notifications/v2/configurations/`;
await getCourseNotificationPreferences('any-course-id');
expect(mockHttpClient.get).toHaveBeenCalledWith(expectedUrl);
expect(mockHttpClient.get).toHaveBeenCalledTimes(1);
});
it('should call the original (v1) configurations URL when ENABLE_PREFERENCES_V2 is not true', async () => {
setConfig({ LMS_BASE_URL, ENABLE_PREFERENCES_V2: 'false' });
const expectedUrl = `${LMS_BASE_URL}/api/notifications/configurations/${courseId}`;
await getCourseNotificationPreferences(courseId);
expect(mockHttpClient.get).toHaveBeenCalledWith(expectedUrl);
expect(mockHttpClient.get).toHaveBeenCalledTimes(1);
});
});
describe('postPreferenceToggle', () => {
it('should call the v2 configurations URL with PUT method when ENABLE_PREFERENCES_V2 is true', async () => {
setConfig({ LMS_BASE_URL, ENABLE_PREFERENCES_V2: 'true' });
const expectedUrl = `${LMS_BASE_URL}/api/notifications/v2/configurations/`;
const testArgs = ['app_name', 'notification_type', 'web', true, 'daily'];
await postPreferenceToggle(...testArgs);
expect(mockHttpClient.put).toHaveBeenCalledWith(expectedUrl, expect.any(Object));
expect(mockHttpClient.put).toHaveBeenCalledTimes(1);
expect(mockHttpClient.post).not.toHaveBeenCalled();
});
it('should call the original (v1) update-all URL with POST method when ENABLE_PREFERENCES_V2 is not true', async () => {
setConfig({ LMS_BASE_URL, ENABLE_PREFERENCES_V2: 'false' });
const expectedUrl = `${LMS_BASE_URL}/api/notifications/preferences/update-all/`;
const testArgs = ['app_name', 'notification_type', 'web', true, 'daily'];
await postPreferenceToggle(...testArgs);
expect(mockHttpClient.post).toHaveBeenCalledWith(expectedUrl, expect.any(Object));
expect(mockHttpClient.post).toHaveBeenCalledTimes(1);
expect(mockHttpClient.put).not.toHaveBeenCalled();
});
});
});

View File

@@ -3,7 +3,10 @@ import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import snakeCase from 'lodash.snakecase';
export const getCourseNotificationPreferences = async (courseId) => {
const url = `${getConfig().LMS_BASE_URL}/api/notifications/configurations/${courseId}`;
let url = `${getConfig().LMS_BASE_URL}/api/notifications/configurations/${courseId}`;
if (getConfig().ENABLE_PREFERENCES_V2 === 'true') {
url = `${getConfig().LMS_BASE_URL}/api/notifications/v2/configurations/`;
}
const { data } = await getAuthenticatedHttpClient().get(url);
return data;
};
@@ -47,6 +50,12 @@ export const postPreferenceToggle = async (
value,
emailCadence,
});
if (getConfig().ENABLE_PREFERENCES_V2 === 'true') {
const url = `${getConfig().LMS_BASE_URL}/api/notifications/v2/configurations/`;
const { data } = await getAuthenticatedHttpClient().put(url, patchData);
return data;
}
const url = `${getConfig().LMS_BASE_URL}/api/notifications/preferences/update-all/`;
const { data } = await getAuthenticatedHttpClient().post(url, patchData);
return data;