Skip to content

Commit

Permalink
refactor: fixed issues of review
Browse files Browse the repository at this point in the history
  • Loading branch information
SundasNoreen committed Jun 19, 2023
1 parent 6efa310 commit 4483a73
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 142 deletions.
22 changes: 12 additions & 10 deletions src/Notifications/data/api.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { camelCaseObject, getConfig, snakeCaseObject } from '@edx/frontend-platform';
import { getConfig, snakeCaseObject } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';

export const getNotificationsCountApiUrl = () => `${getConfig().LMS_BASE_URL}/api/notifications/count/`;
export const getNotificationsApiUrl = () => `${getConfig().LMS_BASE_URL}/api/notifications/`;
export const markNotificationsSeenApiUrl = (appName) => `${getConfig().LMS_BASE_URL}/api/notifications/mark-notifications-unseen/${appName}/`;
export const markAllNotificationsAsReadpiUrl = (appName, id) => `${getConfig().LMS_BASE_URL}/api/notifications/mark-notifications-read/${appName}/${id}`;
export const markAllNotificationsAsReadpiUrl = () => `${getConfig().LMS_BASE_URL}/api/notifications/read/`;

export async function getNotifications(appName, page, pageSize) {
const params = snakeCaseObject({ page, pageSize });
Expand All @@ -14,29 +14,31 @@ export async function getNotifications(appName, page, pageSize) {
const endIndex = startIndex + pageSize;

const notifications = data.slice(startIndex, endIndex);
return { notifications: camelCaseObject(notifications), numPages: 2, currentPage: page };
return { notifications, numPages: 2, currentPage: page };
}

export async function getNotificationCounts() {
const { data } = await getAuthenticatedHttpClient().get(getNotificationsCountApiUrl());

return camelCaseObject(data);
return data;
}

export async function markNotificationSeen(appName) {
const { data } = await getAuthenticatedHttpClient().put(`${markNotificationsSeenApiUrl(appName)}`);

return camelCaseObject(data);
return data;
}

export async function markAllNotificationRead(appName) {
const { data } = await getAuthenticatedHttpClient().put(`${markAllNotificationsAsReadpiUrl(appName)}`);
const params = snakeCaseObject({ appName });
const { data } = await getAuthenticatedHttpClient().put(markAllNotificationsAsReadpiUrl(), { params });

return camelCaseObject(data);
return data;
}

export async function markNotificationRead(appName, notificationId) {
const { data } = await getAuthenticatedHttpClient().put(`${markAllNotificationsAsReadpiUrl(appName, notificationId)}`);
export async function markNotificationRead(notificationId) {
const params = snakeCaseObject({ notificationId });
const { data } = await getAuthenticatedHttpClient().put(markAllNotificationsAsReadpiUrl(), { params });

return camelCaseObject({ data, id: notificationId });
return { data, id: notificationId };
}
143 changes: 63 additions & 80 deletions src/Notifications/data/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,19 @@ import { Factory } from 'rosie';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { initializeMockApp } from '@edx/frontend-platform/testing';

import { initializeStore } from '../../store';
import executeThunk from '../../test-utils';
import {
getNotificationsApiUrl, getNotificationsCountApiUrl, markAllNotificationsAsReadpiUrl, markNotificationsSeenApiUrl,
getNotificationCounts, getNotifications, markNotificationSeen, markAllNotificationRead, markNotificationRead,
} from './api';
import {
fetchAppsNotificationCount,
fetchNotificationList,
markAllNotificationsAsRead,
markNotificationsAsRead,
markNotificationsAsSeen,
} from './thunks';

import './__factories__';

const notificationCountsApiUrl = getNotificationsCountApiUrl();
const notificationsApiUrl = getNotificationsApiUrl();
const markedAllNotificationsAsSeenApiUrl = markNotificationsSeenApiUrl('discussions');
const markedAllNotificationsAsReadApiUrl = markAllNotificationsAsReadpiUrl('discussions');
const markedNotificationAsReadApiUrl = markAllNotificationsAsReadpiUrl('discussions', 1);
const markedAllNotificationsAsReadApiUrl = markAllNotificationsAsReadpiUrl();

let axiosMock = null;
let store;

describe('Notifications API', () => {
beforeEach(async () => {
Expand All @@ -41,14 +30,13 @@ describe('Notifications API', () => {
});
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
Factory.resetAll();
store = initializeStore();
});

afterEach(() => {
axiosMock.reset();
});

it('successfully get notification counts for different tabs.', async () => {
it('Successfully get notification counts for different tabs.', async () => {
axiosMock.onGet(notificationCountsApiUrl).reply(200, (Factory.build('notificationsCount')));

const { count, countByAppName } = await getNotificationCounts();
Expand All @@ -60,21 +48,20 @@ describe('Notifications API', () => {
expect(countByAppName.authoring).toEqual(5);
});

it('failed to get notification counts.', async () => {
axiosMock.onGet(notificationCountsApiUrl).reply(404);
await executeThunk(fetchAppsNotificationCount(), store.dispatch, store.getState);

expect(store.getState().notifications.notificationStatus).toEqual('failed');
});

it('denied to get notification counts.', async () => {
axiosMock.onGet(notificationCountsApiUrl).reply(403, {});
await executeThunk(fetchAppsNotificationCount(), store.dispatch);

expect(store.getState().notifications.notificationStatus).toEqual('denied');
it.each([
{ statusCode: 404, message: 'Failed to get notification counts.' },
{ statusCode: 403, message: 'Denied to get notification counts.' },
])('%s for notification counts API.', async ({ statusCode, message }) => {
axiosMock.onGet(notificationCountsApiUrl).reply(statusCode, { message });
try {
await getNotificationCounts();
} catch (error) {
expect(error.response.status).toEqual(statusCode);
expect(error.response.data.message).toEqual(message);
}
});

it('successfully get notifications.', async () => {
it('Successfully get notifications.', async () => {
axiosMock.onGet(notificationsApiUrl).reply(
200,
(Factory.buildList('notification', 2, null, { createdDate: new Date().toISOString() })),
Expand All @@ -85,83 +72,79 @@ describe('Notifications API', () => {
expect(notifications).toHaveLength(2);
});

it('failed to get notifications.', async () => {
axiosMock.onGet(notificationsApiUrl).reply(404);
await executeThunk(fetchNotificationList({ page: 1, pageSize: 10 }), store.dispatch, store.getState);

expect(store.getState().notifications.notificationStatus).toEqual('failed');
it.each([
{ statusCode: 404, message: 'Failed to get notifications.' },
{ statusCode: 403, message: 'Denied to get notifications.' },
])('%s for notification API.', async ({ statusCode, message }) => {
axiosMock.onGet(notificationsApiUrl).reply(statusCode, { message });
try {
await getNotifications({ page: 1, pageSize: 10 });
} catch (error) {
expect(error.response.status).toEqual(statusCode);
expect(error.response.data.message).toEqual(message);
}
});

it('denied to get notifications.', async () => {
axiosMock.onGet(notificationsApiUrl).reply(403, {});
await executeThunk(fetchNotificationList({ page: 1, pageSize: 10 }), store.dispatch);

expect(store.getState().notifications.notificationStatus).toEqual('denied');
});

it('successfully marked all notifications as seen for selected app.', async () => {
it('Successfully marked all notifications as seen for selected app.', async () => {
axiosMock.onPut(markedAllNotificationsAsSeenApiUrl).reply(200, { message: 'Notifications marked seen.' });

const { message } = await markNotificationSeen('discussions');

expect(message).toEqual('Notifications marked seen.');
});

it('failed to mark all notifications as seen for selected app.', async () => {
axiosMock.onPut(markedAllNotificationsAsSeenApiUrl).reply(404);
await executeThunk(markNotificationsAsSeen('discussions'), store.dispatch, store.getState);

expect(store.getState().notifications.notificationStatus).toEqual('failed');
it.each([
{ statusCode: 404, message: 'Failed to mark all notifications as seen for selected app.' },
{ statusCode: 403, message: 'Denied to mark all notifications as seen for selected app.' },
])('%s for notification mark as seen API.', async ({ statusCode, message }) => {
axiosMock.onPut(markedAllNotificationsAsSeenApiUrl).reply(statusCode, { message });
try {
await markNotificationSeen('discussions');
} catch (error) {
expect(error.response.status).toEqual(statusCode);
expect(error.response.data.message).toEqual(message);
}
});

it('denied to mark all notifications as seen for selected app.', async () => {
axiosMock.onPut(markedAllNotificationsAsSeenApiUrl).reply(403, {});
await executeThunk(markNotificationsAsSeen('discussions'), store.dispatch);

expect(store.getState().notifications.notificationStatus).toEqual('denied');
});

it('successfully marked all notifications as read for selected app.', async () => {
it('Successfully marked all notifications as read for selected app.', async () => {
axiosMock.onPut(markedAllNotificationsAsReadApiUrl).reply(200, { message: 'Notifications marked read.' });

const { message } = await markAllNotificationRead('discussions');

expect(message).toEqual('Notifications marked read.');
});

it('failed to mark all notifications as read for selected app.', async () => {
axiosMock.onPut(markedAllNotificationsAsReadApiUrl).reply(404);
await executeThunk(markAllNotificationsAsRead('discussions'), store.dispatch, store.getState);

expect(store.getState().notifications.notificationStatus).toEqual('failed');
});

it('denied to mark all notifications as read for selected app.', async () => {
axiosMock.onPut(markedAllNotificationsAsReadApiUrl).reply(403, {});
await executeThunk(markAllNotificationsAsRead('discussions'), store.dispatch);

expect(store.getState().notifications.notificationStatus).toEqual('denied');
it.each([
{ statusCode: 404, message: 'Failed to mark all notifications as read for selected app.' },
{ statusCode: 403, message: 'Denied to mark all notifications as read for selected app.' },
])('%s for notification mark all as read API.', async ({ statusCode, message }) => {
axiosMock.onPut(markedAllNotificationsAsReadApiUrl).reply(statusCode, { message });
try {
await markAllNotificationRead('discussions');
} catch (error) {
expect(error.response.status).toEqual(statusCode);
expect(error.response.data.message).toEqual(message);
}
});

it('successfully marked notification as read.', async () => {
axiosMock.onPut(markedNotificationAsReadApiUrl).reply(200, { message: 'Notification marked read.' });
it('Successfully marked notification as read.', async () => {
axiosMock.onPut(markedAllNotificationsAsReadApiUrl).reply(200, { message: 'Notification marked read.' });

const { data } = await markNotificationRead('discussions', 1);
const { data } = await markNotificationRead(1);

expect(data.message).toEqual('Notification marked read.');
});

it('failed to mark notification as read .', async () => {
axiosMock.onPut(markedNotificationAsReadApiUrl).reply(404);
await executeThunk(markNotificationsAsRead('discussions', 1), store.dispatch, store.getState);

expect(store.getState().notifications.notificationStatus).toEqual('failed');
});

it('denied to mark notification as read.', async () => {
axiosMock.onPut(markedNotificationAsReadApiUrl).reply(403, {});
await executeThunk(markNotificationsAsRead('discussions', 1), store.dispatch);

expect(store.getState().notifications.notificationStatus).toEqual('denied');
it.each([
{ statusCode: 404, message: 'Failed to mark notification as read.' },
{ statusCode: 403, message: 'Denied to mark notification as read.' },
])('%s for notification mark as read API.', async ({ statusCode, message }) => {
axiosMock.onPut(markedAllNotificationsAsReadApiUrl).reply(statusCode, { message });
try {
await markAllNotificationRead(1);
} catch (error) {
expect(error.response.status).toEqual(statusCode);
expect(error.response.data.message).toEqual(message);
}
});
});
45 changes: 9 additions & 36 deletions src/Notifications/data/redux.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import './__factories__';

const notificationCountsApiUrl = getNotificationsCountApiUrl();
const notificationsApiUrl = getNotificationsApiUrl();
const markedNotificationAsReadApiUrl = markAllNotificationsAsReadpiUrl('discussions', 1);
const markedAllNotificationsAsReadApiUrl = markAllNotificationsAsReadpiUrl('discussions');
const markedAllNotificationsAsReadApiUrl = markAllNotificationsAsReadpiUrl();
const markedAllNotificationsAsSeenApiUrl = markNotificationsSeenApiUrl('discussions');

let axiosMock;
Expand Down Expand Up @@ -52,7 +51,7 @@ describe('Notification Redux', () => {
axiosMock.reset();
});

it('successfully loaded initial notification states in the redux.', async () => {
it('Successfully loaded initial notification states in the redux.', async () => {
executeThunk(resetNotificationState(), store.dispatch, store.getState);

const { notifications } = store.getState();
Expand All @@ -70,13 +69,13 @@ describe('Notification Redux', () => {
expect(notifications.pagination.nextPage).toBeNull();
});

it('successfully loaded notifications list in the redux.', async () => {
it('Successfully loaded notifications list in the redux.', async () => {
const { notifications: { notifications } } = store.getState();

expect(Object.keys(notifications)).toHaveLength(2);
});

it('successfully loaded notification counts in the redux.', async () => {
it('Successfully loaded notification counts in the redux.', async () => {
const { notifications: { tabsCount } } = store.getState();

expect(tabsCount.count).toEqual(25);
Expand All @@ -86,40 +85,14 @@ describe('Notification Redux', () => {
expect(tabsCount.authoring).toEqual(5);
});

it('successfully loaded showNotificationTray status in the redux based on api.', async () => {
const { notifications: { showNotificationTray } } = store.getState();

expect(showNotificationTray).toEqual(true);
});

it('successfully store the count, numPages, currentPage, and nextPage data in redux.', async () => {
const { notifications: { pagination } } = store.getState();

expect(pagination.count).toEqual(10);
expect(pagination.currentPage).toEqual(1);
expect(pagination.numPages).toEqual(2);
});

it('successfully updated the selected app name in redux.', async () => {
const { notifications: { appName } } = store.getState();

expect(appName).toEqual('discussions');
});

it('successfully store notification ids in the selected app in apps.', async () => {
const { notifications: { apps } } = store.getState();

expect(apps.discussions).toHaveLength(2);
});

it('successfully marked all notifications as seen for selected app.', async () => {
it('Successfully marked all notifications as seen for selected app.', async () => {
axiosMock.onPut(markedAllNotificationsAsSeenApiUrl).reply(200);
await executeThunk(markNotificationsAsSeen('discussions'), store.dispatch, store.getState);

expect(store.getState().notifications.notificationStatus).toEqual('successful');
});

it('successfully marked all notifications as read for selected app in the redux.', async () => {
it('Successfully marked all notifications as read for selected app in the redux.', async () => {
axiosMock.onPut(markedAllNotificationsAsReadApiUrl).reply(200);
await executeThunk(markAllNotificationsAsRead('discussions'), store.dispatch, store.getState);

Expand All @@ -130,9 +103,9 @@ describe('Notification Redux', () => {
expect(firstNotification.lastRead).not.toBeNull();
});

it('successfully marked notification as read in the redux.', async () => {
axiosMock.onPut(markedNotificationAsReadApiUrl).reply(200);
await executeThunk(markNotificationsAsRead('discussions', 1), store.dispatch, store.getState);
it('Successfully marked notification as read in the redux.', async () => {
axiosMock.onPut(markedAllNotificationsAsReadApiUrl).reply(200);
await executeThunk(markNotificationsAsRead(1), store.dispatch, store.getState);

const { notifications: { notificationStatus, notifications } } = store.getState();
const firstNotification = Object.values(notifications)[0];
Expand Down
Loading

0 comments on commit 4483a73

Please sign in to comment.