Files
2025-04-02 12:04:48 -04:00

283 lines
9.3 KiB
JavaScript

import ReactDOM from 'react-dom';
import React from 'react';
import { MemoryRouter, Routes, Route } from 'react-router-dom';
import {
getConfig, initializeMockApp, setConfig,
} from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { AppProvider, PageWrap } from '@edx/frontend-platform/react';
import {
findByTestId, queryByTestId, render, waitFor, getByText, fireEvent,
} from '@testing-library/react';
import MockAdapter from 'axios-mock-adapter';
import PagesAndResourcesProvider from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider';
import initializeStore from 'CourseAuthoring/store';
import { executeThunk } from 'CourseAuthoring/utils';
import XpertUnitSummarySettings from './Settings';
import * as API from './data/api';
import * as Thunks from './data/thunks';
const courseId = 'course-v1:edX+TestX+Test_Course';
let axiosMock;
let store;
let container;
// Modal creates a portal. Overriding ReactDOM.createPortal allows portals to be tested in jest.
ReactDOM.createPortal = jest.fn(node => node);
function renderComponent() {
const wrapper = render(
<AppProvider store={store} wrapWithRouter={false}>
<PagesAndResourcesProvider courseId={courseId}>
<MemoryRouter initialEntries={['/xpert-unit-summary/settings']}>
<Routes>
<Route
path="/xpert-unit-summary/settings"
element={<PageWrap><XpertUnitSummarySettings courseId={courseId} /></PageWrap>}
/>
<Route
path="/"
element={<PageWrap><div /></PageWrap>}
/>
</Routes>
</MemoryRouter>
</PagesAndResourcesProvider>
</AppProvider>,
);
container = wrapper.container;
}
function generateCourseLevelAPIResponse({
success, enabled,
}) {
return {
response: {
success, enabled,
},
};
}
describe('XpertUnitSummarySettings', () => {
beforeEach(() => {
setConfig({
...getConfig(),
BASE_URL: 'http://test.edx.org',
LMS_BASE_URL: 'http://lmstest.edx.org',
CMS_BASE_URL: 'http://cmstest.edx.org',
LOGIN_URL: 'http://support.edx.org/login',
LOGOUT_URL: 'http://support.edx.org/logout',
REFRESH_ACCESS_TOKEN_ENDPOINT: 'http://support.edx.org/access_token',
ACCESS_TOKEN_COOKIE_NAME: 'cookie',
CSRF_TOKEN_API_PATH: '/',
SUPPORT_URL: 'http://support.edx.org',
});
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: true,
roles: [],
},
});
store = initializeStore({
models: {
courseDetails: {
[courseId]: {
start: Date(),
},
},
},
});
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
});
describe('with successful network connections', () => {
beforeEach(() => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: true,
}));
renderComponent();
});
test('Shows switch on if enabled from backend', async () => {
const enableBadge = await findByTestId(container, 'enable-badge');
expect(container.querySelector('#enable-xpert-unit-summary-toggle').checked).toBeTruthy();
expect(enableBadge).toBeTruthy();
});
test('Shows switch on if disabled from backend', async () => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: false,
}));
renderComponent();
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
expect(container.querySelector('#enable-xpert-unit-summary-toggle').checked).toBeTruthy();
expect(queryByTestId(container, 'enable-badge')).toBeTruthy();
});
test('Shows enable radio selected if enabled from backend', async () => {
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
expect(queryByTestId(container, 'enable-radio').checked).toBeTruthy();
});
test('Shows disable radio selected if enabled from backend', async () => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: false,
}));
renderComponent();
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
expect(queryByTestId(container, 'disable-radio').checked).toBeTruthy();
});
});
describe('first time course configuration', () => {
beforeEach(() => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(400, generateCourseLevelAPIResponse({
success: false,
enabled: undefined,
}));
renderComponent();
});
test('Does not show as enabled if configuration does not exist', async () => {
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
expect(container.querySelector('#enable-xpert-unit-summary-toggle').checked).not.toBeTruthy();
expect(queryByTestId(container, 'enable-badge')).not.toBeTruthy();
});
});
describe('saving configuration changes', () => {
beforeEach(() => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: false,
}));
axiosMock.onPost(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: true,
}));
renderComponent();
});
test('Saving configuration changes', async () => {
jest.spyOn(API, 'postXpertSettings');
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
expect(queryByTestId(container, 'disable-radio').checked).toBeTruthy();
fireEvent.click(queryByTestId(container, 'enable-radio'));
fireEvent.click(getByText(container, 'Save'));
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
expect(API.postXpertSettings).toBeCalled();
});
});
describe('testing configurable gating', () => {
beforeEach(async () => {
axiosMock.onGet(API.getXpertConfigurationStatusUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: true,
}));
jest.spyOn(API, 'getXpertPluginConfigurable');
await executeThunk(Thunks.fetchXpertPluginConfigurable(courseId), store.dispatch);
renderComponent();
});
test('getting Xpert Plugin configurable status', () => {
expect(API.getXpertPluginConfigurable).toBeCalled();
});
});
describe('removing course configuration', () => {
beforeEach(() => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: true,
}));
axiosMock.onDelete(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: undefined,
}));
renderComponent();
});
test('Deleting course configuration', async () => {
jest.spyOn(API, 'deleteXpertSettings');
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
fireEvent.click(container.querySelector('#enable-xpert-unit-summary-toggle'));
fireEvent.click(getByText(container, 'Save'));
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
expect(API.deleteXpertSettings).toBeCalled();
});
});
describe('resetting course units', () => {
test('reset all units to be enabled', async () => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: true,
}));
axiosMock.onPost(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: true,
}));
renderComponent();
jest.spyOn(API, 'postXpertSettings');
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
fireEvent.click(queryByTestId(container, 'reset-units'));
expect(API.postXpertSettings).toBeCalledWith(courseId, { reset: true, enabled: true });
});
test('reset all units to be disabled', async () => {
axiosMock.onGet(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: false,
}));
axiosMock.onPost(API.getXpertSettingsUrl(courseId))
.reply(200, generateCourseLevelAPIResponse({
success: true,
enabled: false,
}));
renderComponent();
jest.spyOn(API, 'postXpertSettings');
await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy());
fireEvent.click(queryByTestId(container, 'reset-units'));
expect(API.postXpertSettings).toBeCalledWith(courseId, { reset: true, enabled: false });
});
});
});