Skip to content

Commit c3541a3

Browse files
test: added notification redux test cases
1 parent dad01fc commit c3541a3

6 files changed

Lines changed: 459 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import './notifications.factory';
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Factory } from 'rosie';
2+
3+
Factory.define('notificationsCount')
4+
.attr('count', 45)
5+
.attr('countByAppName', {
6+
reminders: 10,
7+
discussions: 20,
8+
grades: 10,
9+
authoring: 5,
10+
})
11+
.attr('showNotificationTray', true);
12+
13+
Factory.define('notification')
14+
.sequence('id')
15+
.attr('type', 'post')
16+
.sequence('content', ['id'], (idx, notificationId) => `<p><b>User ${idx}</b> posts <b>Hello and welcome to SC0x
17+
${notificationId}!</b></p>`)
18+
.attr('course_name', 'Supply Chain Analytics')
19+
.sequence('content_url', (idx) => `https://example.com/${idx}`)
20+
.attr('last_read', null)
21+
.attr('last_seen', null)
22+
.sequence('created_at', ['createdDate'], (idx, date) => date);

src/Notifications/data/api.test.js

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
import MockAdapter from 'axios-mock-adapter';
2+
import { Factory } from 'rosie';
3+
4+
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
5+
import { initializeMockApp } from '@edx/frontend-platform/testing';
6+
7+
import { initializeStore } from '../../store';
8+
import executeThunk from '../../test-utils';
9+
import {
10+
getNotificationsApiUrl, getNotificationsCountApiUrl, markAllNotificationsAsReadpiUrl, markNotificationsSeenApiUrl,
11+
getNotificationCounts, getNotifications, markNotificationSeen, markAllNotificationRead, markNotificationRead,
12+
} from './api';
13+
import {
14+
fetchAppsNotificationCount,
15+
fetchNotificationList,
16+
markAllNotificationsAsRead,
17+
markNotificationsAsRead,
18+
markNotificationsAsSeen,
19+
} from './thunks';
20+
21+
import './__factories__';
22+
23+
const notificationCountsApiUrl = getNotificationsCountApiUrl();
24+
const notificationsApiUrl = getNotificationsApiUrl();
25+
const markedAllNotificationsAsSeenApiUrl = markNotificationsSeenApiUrl('discussions');
26+
const markedAllNotificationsAsReadApiUrl = markAllNotificationsAsReadpiUrl('discussions');
27+
const markedNotificationAsReadApiUrl = markAllNotificationsAsReadpiUrl('discussions', 1);
28+
29+
let axiosMock = null;
30+
let store;
31+
32+
describe('Notifications API', () => {
33+
beforeEach(async () => {
34+
initializeMockApp({
35+
authenticatedUser: {
36+
userId: '123abc',
37+
username: 'testuser',
38+
administrator: false,
39+
roles: [],
40+
},
41+
});
42+
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
43+
Factory.resetAll();
44+
store = initializeStore();
45+
});
46+
47+
afterEach(() => {
48+
axiosMock.reset();
49+
});
50+
51+
it('successfully get notification counts for different tabs.', async () => {
52+
axiosMock.onGet(notificationCountsApiUrl).reply(200, (Factory.build('notificationsCount')));
53+
54+
const { count, countByAppName } = await getNotificationCounts();
55+
56+
expect(count).toEqual(45);
57+
expect(countByAppName.reminders).toEqual(10);
58+
expect(countByAppName.discussions).toEqual(20);
59+
expect(countByAppName.grades).toEqual(10);
60+
expect(countByAppName.authoring).toEqual(5);
61+
});
62+
63+
it('failed to get notification counts.', async () => {
64+
axiosMock.onGet(notificationCountsApiUrl).reply(404);
65+
await executeThunk(fetchAppsNotificationCount(), store.dispatch, store.getState);
66+
67+
expect(store.getState().notifications.notificationStatus).toEqual('failed');
68+
});
69+
70+
it('denied to get notification counts.', async () => {
71+
axiosMock.onGet(notificationCountsApiUrl).reply(403, {});
72+
await executeThunk(fetchAppsNotificationCount(), store.dispatch);
73+
74+
expect(store.getState().notifications.notificationStatus).toEqual('denied');
75+
});
76+
77+
it('successfully get notifications.', async () => {
78+
axiosMock.onGet(notificationsApiUrl).reply(
79+
200,
80+
(Factory.buildList('notification', 2, null, { createdDate: new Date().toISOString() })),
81+
);
82+
83+
const { notifications } = await getNotifications('discussions', 1, 10);
84+
85+
expect(notifications).toHaveLength(2);
86+
});
87+
88+
it('failed to get notifications.', async () => {
89+
axiosMock.onGet(notificationsApiUrl).reply(404);
90+
await executeThunk(fetchNotificationList({ page: 1, pageSize: 10 }), store.dispatch, store.getState);
91+
92+
expect(store.getState().notifications.notificationStatus).toEqual('failed');
93+
});
94+
95+
it('denied to get notifications.', async () => {
96+
axiosMock.onGet(notificationsApiUrl).reply(403, {});
97+
await executeThunk(fetchNotificationList({ page: 1, pageSize: 10 }), store.dispatch);
98+
99+
expect(store.getState().notifications.notificationStatus).toEqual('denied');
100+
});
101+
102+
it('successfully marked all notifications as seen for selected app.', async () => {
103+
axiosMock.onPut(markedAllNotificationsAsSeenApiUrl).reply(200, { message: 'Notifications marked seen.' });
104+
105+
const { message } = await markNotificationSeen('discussions');
106+
107+
expect(message).toEqual('Notifications marked seen.');
108+
});
109+
110+
it('failed to mark all notifications as seen for selected app.', async () => {
111+
axiosMock.onPut(markedAllNotificationsAsSeenApiUrl).reply(404);
112+
await executeThunk(markNotificationsAsSeen('discussions'), store.dispatch, store.getState);
113+
114+
expect(store.getState().notifications.notificationStatus).toEqual('failed');
115+
});
116+
117+
it('denied to mark all notifications as seen for selected app.', async () => {
118+
axiosMock.onPut(markedAllNotificationsAsSeenApiUrl).reply(403, {});
119+
await executeThunk(markNotificationsAsSeen('discussions'), store.dispatch);
120+
121+
expect(store.getState().notifications.notificationStatus).toEqual('denied');
122+
});
123+
124+
it('successfully marked all notifications as read for selected app.', async () => {
125+
axiosMock.onPut(markedAllNotificationsAsReadApiUrl).reply(200, { message: 'Notifications marked read.' });
126+
127+
const { message } = await markAllNotificationRead('discussions');
128+
129+
expect(message).toEqual('Notifications marked read.');
130+
});
131+
132+
it('failed to mark all notifications as read for selected app.', async () => {
133+
axiosMock.onPut(markedAllNotificationsAsReadApiUrl).reply(404);
134+
await executeThunk(markAllNotificationsAsRead('discussions'), store.dispatch, store.getState);
135+
136+
expect(store.getState().notifications.notificationStatus).toEqual('failed');
137+
});
138+
139+
it('denied to mark all notifications as read for selected app.', async () => {
140+
axiosMock.onPut(markedAllNotificationsAsReadApiUrl).reply(403, {});
141+
await executeThunk(markAllNotificationsAsRead('discussions'), store.dispatch);
142+
143+
expect(store.getState().notifications.notificationStatus).toEqual('denied');
144+
});
145+
146+
it('successfully marked notification as read.', async () => {
147+
axiosMock.onPut(markedNotificationAsReadApiUrl).reply(200, { message: 'Notification marked read.' });
148+
149+
const { data } = await markNotificationRead('discussions', 1);
150+
151+
expect(data.message).toEqual('Notification marked read.');
152+
});
153+
154+
it('failed to mark notification as read .', async () => {
155+
axiosMock.onPut(markedNotificationAsReadApiUrl).reply(404);
156+
await executeThunk(markNotificationsAsRead('discussions', 1), store.dispatch, store.getState);
157+
158+
expect(store.getState().notifications.notificationStatus).toEqual('failed');
159+
});
160+
161+
it('denied to mark notification as read.', async () => {
162+
axiosMock.onPut(markedNotificationAsReadApiUrl).reply(403, {});
163+
await executeThunk(markNotificationsAsRead('discussions', 1), store.dispatch);
164+
165+
expect(store.getState().notifications.notificationStatus).toEqual('denied');
166+
});
167+
});
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import MockAdapter from 'axios-mock-adapter';
2+
import { Factory } from 'rosie';
3+
4+
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
5+
import { initializeMockApp } from '@edx/frontend-platform/testing';
6+
7+
import { initializeStore } from '../../store';
8+
import executeThunk from '../../test-utils';
9+
import {
10+
getNotificationsApiUrl, getNotificationsCountApiUrl, markAllNotificationsAsReadpiUrl, markNotificationsSeenApiUrl,
11+
} from './api';
12+
import {
13+
fetchAppsNotificationCount, fetchNotificationList, markNotificationsAsRead, markAllNotificationsAsRead,
14+
resetNotificationState, markNotificationsAsSeen,
15+
} from './thunks';
16+
17+
import './__factories__';
18+
19+
const notificationCountsApiUrl = getNotificationsCountApiUrl();
20+
const notificationsApiUrl = getNotificationsApiUrl();
21+
const markedNotificationAsReadApiUrl = markAllNotificationsAsReadpiUrl('discussions', 1);
22+
const markedAllNotificationsAsReadApiUrl = markAllNotificationsAsReadpiUrl('discussions');
23+
const markedAllNotificationsAsSeenApiUrl = markNotificationsSeenApiUrl('discussions');
24+
25+
let axiosMock;
26+
let store;
27+
28+
describe('Notification Redux', () => {
29+
beforeEach(async () => {
30+
initializeMockApp({
31+
authenticatedUser: {
32+
userId: '123abc',
33+
username: 'testuser',
34+
administrator: false,
35+
roles: [],
36+
},
37+
});
38+
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
39+
Factory.resetAll();
40+
store = initializeStore();
41+
42+
axiosMock.onGet(notificationCountsApiUrl).reply(200, (Factory.build('notificationsCount')));
43+
axiosMock.onGet(notificationsApiUrl).reply(200, (Factory.buildList('notification', 2, null)));
44+
await executeThunk(fetchAppsNotificationCount(), store.dispatch, store.getState);
45+
await executeThunk(fetchNotificationList({ page: 1, pageSize: 10 }), store.dispatch, store.getState);
46+
});
47+
48+
afterEach(() => {
49+
axiosMock.reset();
50+
});
51+
52+
it('successfully loaded initial notification states in the redux.', async () => {
53+
executeThunk(resetNotificationState(), store.dispatch, store.getState);
54+
55+
const { notifications } = store.getState();
56+
57+
expect(notifications.notificationStatus).toEqual('idle');
58+
expect(notifications.appName).toEqual('discussions');
59+
expect(notifications.appsId).toHaveLength(0);
60+
expect(notifications.apps).toEqual({});
61+
expect(notifications.notifications).toEqual({});
62+
expect(notifications.tabsCount).toEqual({});
63+
expect(notifications.showNotificationTray).toEqual(false);
64+
expect(notifications.pagination.count).toEqual(10);
65+
expect(notifications.pagination.numPages).toEqual(1);
66+
expect(notifications.pagination.currentPage).toEqual(1);
67+
expect(notifications.pagination.nextPage).toBeNull();
68+
});
69+
70+
it('successfully loaded notifications list in the redux.', async () => {
71+
const state = store.getState();
72+
73+
expect(Object.keys(state.notifications.notifications)).toHaveLength(2);
74+
});
75+
76+
it('successfully loaded notification counts in the redux.', async () => {
77+
const { notifications: { tabsCount } } = store.getState();
78+
79+
expect(tabsCount.count).toEqual(25);
80+
expect(tabsCount.reminders).toEqual(10);
81+
expect(tabsCount.discussions).toEqual(0);
82+
expect(tabsCount.grades).toEqual(10);
83+
expect(tabsCount.authoring).toEqual(5);
84+
});
85+
86+
it('successfully loaded showNotificationTray status in the redux based on api.', async () => {
87+
const state = store.getState();
88+
89+
expect(state.notifications.showNotificationTray).toEqual(true);
90+
});
91+
92+
it('successfully store the count, numPages, currentPage, and nextPage data in redux.', async () => {
93+
const { notifications: { pagination } } = store.getState();
94+
95+
expect(pagination.count).toEqual(10);
96+
expect(pagination.currentPage).toEqual(1);
97+
expect(pagination.numPages).toEqual(2);
98+
});
99+
100+
it('successfully updated the selected app name in redux.', async () => {
101+
const state = store.getState();
102+
103+
expect(state.notifications.appName).toEqual('discussions');
104+
});
105+
106+
it('successfully store notification ids in the selected app in apps.', async () => {
107+
const state = store.getState();
108+
109+
expect(state.notifications.apps.discussions).toHaveLength(2);
110+
});
111+
112+
it('successfully marked all notifications as seen for selected app.', async () => {
113+
axiosMock.onPut(markedAllNotificationsAsSeenApiUrl).reply(200);
114+
await executeThunk(markNotificationsAsSeen('discussions'), store.dispatch, store.getState);
115+
116+
expect(store.getState().notifications.notificationStatus).toEqual('successful');
117+
});
118+
119+
it('successfully marked all notifications as read for selected app in the redux.', async () => {
120+
axiosMock.onPut(markedAllNotificationsAsReadApiUrl).reply(200);
121+
await executeThunk(markAllNotificationsAsRead('discussions'), store.dispatch, store.getState);
122+
123+
const { notifications } = store.getState();
124+
const firstNotification = Object.values(notifications.notifications)[0];
125+
126+
expect(notifications.notificationStatus).toEqual('successful');
127+
expect(firstNotification.lastRead).not.toBeNull();
128+
});
129+
130+
it('successfully marked notification as read in the redux.', async () => {
131+
axiosMock.onPut(markedNotificationAsReadApiUrl).reply(200);
132+
await executeThunk(markNotificationsAsRead('discussions', 1), store.dispatch, store.getState);
133+
134+
const { notifications } = store.getState();
135+
const firstNotification = Object.values(notifications.notifications)[0];
136+
137+
expect(notifications.notificationStatus).toEqual('successful');
138+
expect(firstNotification.lastRead).not.toBeNull();
139+
});
140+
});

0 commit comments

Comments
 (0)