test: added notification redux test cases
This commit is contained in:
1
src/Notifications/data/__factories__/index.js
Normal file
1
src/Notifications/data/__factories__/index.js
Normal file
@@ -0,0 +1 @@
|
||||
import './notifications.factory';
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Factory } from 'rosie';
|
||||
|
||||
Factory.define('notificationsCount')
|
||||
.attr('count', 45)
|
||||
.attr('countByAppName', {
|
||||
reminders: 10,
|
||||
discussions: 20,
|
||||
grades: 10,
|
||||
authoring: 5,
|
||||
})
|
||||
.attr('showNotificationTray', true);
|
||||
|
||||
Factory.define('notification')
|
||||
.sequence('id')
|
||||
.attr('type', 'post')
|
||||
.sequence('content', ['id'], (idx, notificationId) => `<p><b>User ${idx}</b> posts <b>Hello and welcome to SC0x
|
||||
${notificationId}!</b></p>`)
|
||||
.attr('course_name', 'Supply Chain Analytics')
|
||||
.sequence('content_url', (idx) => `https://example.com/${idx}`)
|
||||
.attr('last_read', null)
|
||||
.attr('last_seen', null)
|
||||
.sequence('created_at', ['createdDate'], (idx, date) => date);
|
||||
167
src/Notifications/data/api.test.js
Normal file
167
src/Notifications/data/api.test.js
Normal file
@@ -0,0 +1,167 @@
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
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);
|
||||
|
||||
let axiosMock = null;
|
||||
let store;
|
||||
|
||||
describe('Notifications API', () => {
|
||||
beforeEach(async () => {
|
||||
initializeMockApp({
|
||||
authenticatedUser: {
|
||||
userId: '123abc',
|
||||
username: 'testuser',
|
||||
administrator: false,
|
||||
roles: [],
|
||||
},
|
||||
});
|
||||
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
|
||||
Factory.resetAll();
|
||||
store = initializeStore();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
axiosMock.reset();
|
||||
});
|
||||
|
||||
it('successfully get notification counts for different tabs.', async () => {
|
||||
axiosMock.onGet(notificationCountsApiUrl).reply(200, (Factory.build('notificationsCount')));
|
||||
|
||||
const { count, countByAppName } = await getNotificationCounts();
|
||||
|
||||
expect(count).toEqual(45);
|
||||
expect(countByAppName.reminders).toEqual(10);
|
||||
expect(countByAppName.discussions).toEqual(20);
|
||||
expect(countByAppName.grades).toEqual(10);
|
||||
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('successfully get notifications.', async () => {
|
||||
axiosMock.onGet(notificationsApiUrl).reply(
|
||||
200,
|
||||
(Factory.buildList('notification', 2, null, { createdDate: new Date().toISOString() })),
|
||||
);
|
||||
|
||||
const { notifications } = await getNotifications('discussions', 1, 10);
|
||||
|
||||
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('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 () => {
|
||||
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('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 () => {
|
||||
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('successfully marked notification as read.', async () => {
|
||||
axiosMock.onPut(markedNotificationAsReadApiUrl).reply(200, { message: 'Notification marked read.' });
|
||||
|
||||
const { data } = await markNotificationRead('discussions', 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');
|
||||
});
|
||||
});
|
||||
140
src/Notifications/data/redux.test.js
Normal file
140
src/Notifications/data/redux.test.js
Normal file
@@ -0,0 +1,140 @@
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
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,
|
||||
} from './api';
|
||||
import {
|
||||
fetchAppsNotificationCount, fetchNotificationList, markNotificationsAsRead, markAllNotificationsAsRead,
|
||||
resetNotificationState, markNotificationsAsSeen,
|
||||
} from './thunks';
|
||||
|
||||
import './__factories__';
|
||||
|
||||
const notificationCountsApiUrl = getNotificationsCountApiUrl();
|
||||
const notificationsApiUrl = getNotificationsApiUrl();
|
||||
const markedNotificationAsReadApiUrl = markAllNotificationsAsReadpiUrl('discussions', 1);
|
||||
const markedAllNotificationsAsReadApiUrl = markAllNotificationsAsReadpiUrl('discussions');
|
||||
const markedAllNotificationsAsSeenApiUrl = markNotificationsSeenApiUrl('discussions');
|
||||
|
||||
let axiosMock;
|
||||
let store;
|
||||
|
||||
describe('Notification Redux', () => {
|
||||
beforeEach(async () => {
|
||||
initializeMockApp({
|
||||
authenticatedUser: {
|
||||
userId: '123abc',
|
||||
username: 'testuser',
|
||||
administrator: false,
|
||||
roles: [],
|
||||
},
|
||||
});
|
||||
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
|
||||
Factory.resetAll();
|
||||
store = initializeStore();
|
||||
|
||||
axiosMock.onGet(notificationCountsApiUrl).reply(200, (Factory.build('notificationsCount')));
|
||||
axiosMock.onGet(notificationsApiUrl).reply(200, (Factory.buildList('notification', 2, null)));
|
||||
await executeThunk(fetchAppsNotificationCount(), store.dispatch, store.getState);
|
||||
await executeThunk(fetchNotificationList({ page: 1, pageSize: 10 }), store.dispatch, store.getState);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
axiosMock.reset();
|
||||
});
|
||||
|
||||
it('successfully loaded initial notification states in the redux.', async () => {
|
||||
executeThunk(resetNotificationState(), store.dispatch, store.getState);
|
||||
|
||||
const { notifications } = store.getState();
|
||||
|
||||
expect(notifications.notificationStatus).toEqual('idle');
|
||||
expect(notifications.appName).toEqual('discussions');
|
||||
expect(notifications.appsId).toHaveLength(0);
|
||||
expect(notifications.apps).toEqual({});
|
||||
expect(notifications.notifications).toEqual({});
|
||||
expect(notifications.tabsCount).toEqual({});
|
||||
expect(notifications.showNotificationTray).toEqual(false);
|
||||
expect(notifications.pagination.count).toEqual(10);
|
||||
expect(notifications.pagination.numPages).toEqual(1);
|
||||
expect(notifications.pagination.currentPage).toEqual(1);
|
||||
expect(notifications.pagination.nextPage).toBeNull();
|
||||
});
|
||||
|
||||
it('successfully loaded notifications list in the redux.', async () => {
|
||||
const state = store.getState();
|
||||
|
||||
expect(Object.keys(state.notifications.notifications)).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('successfully loaded notification counts in the redux.', async () => {
|
||||
const { notifications: { tabsCount } } = store.getState();
|
||||
|
||||
expect(tabsCount.count).toEqual(25);
|
||||
expect(tabsCount.reminders).toEqual(10);
|
||||
expect(tabsCount.discussions).toEqual(0);
|
||||
expect(tabsCount.grades).toEqual(10);
|
||||
expect(tabsCount.authoring).toEqual(5);
|
||||
});
|
||||
|
||||
it('successfully loaded showNotificationTray status in the redux based on api.', async () => {
|
||||
const state = store.getState();
|
||||
|
||||
expect(state.notifications.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 state = store.getState();
|
||||
|
||||
expect(state.notifications.appName).toEqual('discussions');
|
||||
});
|
||||
|
||||
it('successfully store notification ids in the selected app in apps.', async () => {
|
||||
const state = store.getState();
|
||||
|
||||
expect(state.notifications.apps.discussions).toHaveLength(2);
|
||||
});
|
||||
|
||||
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 () => {
|
||||
axiosMock.onPut(markedAllNotificationsAsReadApiUrl).reply(200);
|
||||
await executeThunk(markAllNotificationsAsRead('discussions'), store.dispatch, store.getState);
|
||||
|
||||
const { notifications } = store.getState();
|
||||
const firstNotification = Object.values(notifications.notifications)[0];
|
||||
|
||||
expect(notifications.notificationStatus).toEqual('successful');
|
||||
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);
|
||||
|
||||
const { notifications } = store.getState();
|
||||
const firstNotification = Object.values(notifications.notifications)[0];
|
||||
|
||||
expect(notifications.notificationStatus).toEqual('successful');
|
||||
expect(firstNotification.lastRead).not.toBeNull();
|
||||
});
|
||||
});
|
||||
123
src/Notifications/data/selector.test.jsx
Normal file
123
src/Notifications/data/selector.test.jsx
Normal file
@@ -0,0 +1,123 @@
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
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 } from './api';
|
||||
import {
|
||||
selectNotifications,
|
||||
selectNotificationsByIds,
|
||||
selectNotificationStatus,
|
||||
selectNotificationTabs,
|
||||
selectNotificationTabsCount,
|
||||
selectPaginationData,
|
||||
selectSelectedAppName,
|
||||
selectSelectedAppNotificationIds,
|
||||
selectShowNotificationTray,
|
||||
} from './selectors';
|
||||
import { fetchAppsNotificationCount, fetchNotificationList } from './thunks';
|
||||
|
||||
import './__factories__';
|
||||
|
||||
const notificationCountsApiUrl = getNotificationsCountApiUrl();
|
||||
const notificationsApiUrl = getNotificationsApiUrl();
|
||||
|
||||
let axiosMock;
|
||||
let store;
|
||||
|
||||
describe('Notification Selectors', () => {
|
||||
beforeEach(async () => {
|
||||
initializeMockApp({
|
||||
authenticatedUser: {
|
||||
userId: '123abc',
|
||||
username: 'testuser',
|
||||
administrator: false,
|
||||
roles: [],
|
||||
},
|
||||
});
|
||||
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
|
||||
Factory.resetAll();
|
||||
store = initializeStore();
|
||||
|
||||
axiosMock.onGet(notificationCountsApiUrl).reply(200, (Factory.build('notificationsCount')));
|
||||
axiosMock.onGet(notificationsApiUrl).reply(200, (Factory.buildList('notification', 2, null)));
|
||||
await executeThunk(fetchAppsNotificationCount(), store.dispatch, store.getState);
|
||||
await executeThunk(fetchNotificationList({ page: 1, pageSize: 10 }), store.dispatch, store.getState);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
axiosMock.reset();
|
||||
});
|
||||
|
||||
it('should return notification status.', async () => {
|
||||
const state = store.getState();
|
||||
const status = selectNotificationStatus()(state);
|
||||
|
||||
expect(status).toEqual('successful');
|
||||
});
|
||||
|
||||
it('should return notification tabs count.', async () => {
|
||||
const state = store.getState();
|
||||
const tabsCount = selectNotificationTabsCount()(state);
|
||||
|
||||
expect(tabsCount.count).toEqual(25);
|
||||
expect(tabsCount.reminders).toEqual(10);
|
||||
expect(tabsCount.discussions).toEqual(0);
|
||||
expect(tabsCount.grades).toEqual(10);
|
||||
expect(tabsCount.authoring).toEqual(5);
|
||||
});
|
||||
|
||||
it('should return notification tabs.', async () => {
|
||||
const state = store.getState();
|
||||
const tabs = selectNotificationTabs()(state);
|
||||
|
||||
expect(tabs).toHaveLength(4);
|
||||
});
|
||||
|
||||
it('should return selected app notification ids.', async () => {
|
||||
const state = store.getState();
|
||||
const notificationIds = selectSelectedAppNotificationIds('discussions')(state);
|
||||
|
||||
expect(notificationIds).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('should return show notification tray status.', async () => {
|
||||
const state = store.getState();
|
||||
const showNotificationTrayStatus = selectShowNotificationTray()(state);
|
||||
|
||||
expect(showNotificationTrayStatus).toEqual(true);
|
||||
});
|
||||
|
||||
it('should return notifications.', async () => {
|
||||
const state = store.getState();
|
||||
const notifications = selectNotifications()(state);
|
||||
|
||||
expect(Object.keys(notifications)).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('should return notifications from Ids.', async () => {
|
||||
const state = store.getState();
|
||||
const notifications = selectNotificationsByIds('discussions')(state);
|
||||
|
||||
expect(notifications).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('should return selected app name.', async () => {
|
||||
const state = store.getState();
|
||||
const appName = selectSelectedAppName()(state);
|
||||
|
||||
expect(appName).toEqual('discussions');
|
||||
});
|
||||
|
||||
it('should return pagination data.', async () => {
|
||||
const state = store.getState();
|
||||
const paginationData = selectPaginationData()(state);
|
||||
|
||||
expect(paginationData.count).toEqual(10);
|
||||
expect(paginationData.currentPage).toEqual(1);
|
||||
expect(paginationData.numPages).toEqual(2);
|
||||
});
|
||||
});
|
||||
6
src/test-utils.js
Normal file
6
src/test-utils.js
Normal file
@@ -0,0 +1,6 @@
|
||||
const executeThunk = async (thunk, dispatch, getState) => {
|
||||
await thunk(dispatch, getState);
|
||||
await new Promise(setImmediate);
|
||||
};
|
||||
|
||||
export default executeThunk;
|
||||
Reference in New Issue
Block a user