Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions plugins/course-apps/learning_assistant/Settings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink } from '@openedx/paragon';

import AppSettingsModal from 'CourseAuthoring/pages-and-resources/app-settings-modal/AppSettingsModal';
import { useModel } from 'CourseAuthoring/generic/model-store';
import { useCourseAuthoringContext } from 'CourseAuthoring/CourseAuthoringContext';

import messages from './messages';

const LearningAssistantSettings = ({ onClose }) => {
const { courseApps } = useCourseAuthoringContext();
const appId = 'learning_assistant';
const appInfo = useModel('courseApps', appId);
const appInfo = courseApps.find((app) => app.id === appId);
const intl = useIntl();

// We need to render more than one link, so we use the bodyChildren prop.
Expand Down
61 changes: 36 additions & 25 deletions plugins/course-apps/learning_assistant/Settings.test.jsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,51 @@
import React from 'react';
import { screen, waitFor } from '@testing-library/react';

import { RequestStatus } from 'CourseAuthoring/data/constants';
import { CourseAuthoringProvider } from 'CourseAuthoring/CourseAuthoringContext';
import PagesAndResourcesProvider from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider';
import { getCourseAppsApiUrl, getCourseDetailsUrl } from 'CourseAuthoring/data/api';
import { initializeMocks, render } from 'CourseAuthoring/testUtils';
import LearningAssistantSettings from './Settings';

const onClose = () => {};
const courseId = 'course-v1:edX+TestX+Test_Course';

const renderComponent = () =>
render(
<CourseAuthoringProvider courseId={courseId}>
<PagesAndResourcesProvider courseId={courseId}>
<LearningAssistantSettings onClose={onClose} />
</PagesAndResourcesProvider>
</CourseAuthoringProvider>,
);

describe('Learning Assistant Settings', () => {
it('renders', async () => {
const initialState = {
models: {
courseApps: {
learning_assistant: {
id: 'learning_assistant',
enabled: true,
name: 'Learning Assistant',
description: 'Learning Assistant description',
allowedOperations: {
configure: false,
enable: true,
},
documentationLinks: {
learnMoreOpenaiDataPrivacy: 'www.example.com/learn-more-data-privacy',
learnMoreOpenai: 'www.example.com/learn-more',
},
},
const { axiosMock } = initializeMocks();

axiosMock.onGet(getCourseDetailsUrl(courseId, 'abc123')).reply(200, {
courseId,
name: 'Course Test',
start: Date(),
});

axiosMock.onGet(`${getCourseAppsApiUrl()}/${courseId}`).reply(200, [
{
id: 'learning_assistant',
name: 'Learning Assistant',
description: 'Learning Assistant description',
enabled: true,
documentation_links: {
learn_more_openai_data_privacy: 'www.example.com/learn-more-data-privacy',
learn_more_openai: 'www.example.com/learn-more',
},
allowed_operations: {
configure: false,
enable: true,
},
},
pagesAndResources: {
loadingStatus: RequestStatus.SUCCESSFUL,
},
};
]);

initializeMocks({ initialState });
render(<LearningAssistantSettings onClose={onClose} />);
renderComponent();

const toggleDescription = 'Reinforce learning concepts by sharing text-based course content '
+ 'with OpenAI (via API) to power an in-course Learning Assistant. Learners can leave feedback about the quality '
Expand Down
23 changes: 21 additions & 2 deletions plugins/course-apps/live/BbbSettings.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import { executeThunk } from 'CourseAuthoring/utils';
import PagesAndResourcesProvider from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider';

import { CourseAuthoringProvider } from 'CourseAuthoring/CourseAuthoringContext';
import { getCourseAppsApiUrl, getCourseDetailsUrl } from 'CourseAuthoring/data/api';
import LiveSettings from './Settings';
import {
generateLiveConfigurationApiResponse,
courseId,
initialState,
configurationProviders,
} from './factories/mockApiResponses';
import { fetchLiveConfiguration, fetchLiveProviders } from './data/thunks';
Expand Down Expand Up @@ -78,9 +78,28 @@ const mockStore = async ({

describe('BBB Settings', () => {
beforeEach(async () => {
const mocks = initializeMocks({ initialState });
const mocks = initializeMocks();
store = mocks.reduxStore;
axiosMock = mocks.axiosMock;

axiosMock.onGet(getCourseDetailsUrl(courseId, 'abc123')).reply(200, {
courseId,
name: 'Course Test',
start: Date(),
});
axiosMock.onGet(`${getCourseAppsApiUrl()}/${courseId}`).reply(200, [
{
id: 'live',
enabled: true,
name: 'Live',
description: 'Enable in-platform video conferencing by configuring live',
allowed_operations: {
enable: true,
configure: true,
},
documentation_links: {},
},
]);
});

test('Plan dropdown to be visible and enabled in UI', async () => {
Expand Down
37 changes: 29 additions & 8 deletions plugins/course-apps/live/Settings.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import { executeThunk } from 'CourseAuthoring/utils';
import PagesAndResourcesProvider from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider';

import { CourseAuthoringProvider } from 'CourseAuthoring/CourseAuthoringContext';
import { getCourseAppsApiUrl, getCourseDetailsUrl } from 'CourseAuthoring/data/api';
import LiveSettings from './Settings';
import {
generateLiveConfigurationApiResponse,
courseId,
initialState,
configurationProviders,
} from './factories/mockApiResponses';

Expand All @@ -35,14 +35,16 @@ const liveSettingsUrl = `/course/${courseId}/pages-and-resources/live/settings`;

// Modal creates a portal. Overriding ReactDOM.createPortal allows portals to be tested in jest.
ReactDOM.createPortal = jest.fn(node => node);
// jsdom doesn't implement scrollIntoView; AppSettingsModal calls it when showing a save error.
window.HTMLElement.prototype.scrollIntoView = jest.fn();

const renderComponent = () => {
const wrapper = render(
<PagesAndResourcesProvider courseId={courseId}>
<CourseAuthoringProvider>
<CourseAuthoringProvider courseId={courseId}>
<PagesAndResourcesProvider courseId={courseId}>
<LiveSettings onClose={() => {}} />
</CourseAuthoringProvider>
</PagesAndResourcesProvider>,
</PagesAndResourcesProvider>
</CourseAuthoringProvider>,
{
path: liveSettingsUrl,
routerProps: {
Expand Down Expand Up @@ -74,11 +76,28 @@ const mockStore = async ({

describe('LiveSettings', () => {
beforeEach(async () => {
const mocks = initializeMocks({
initialState,
});
const mocks = initializeMocks();
store = mocks.reduxStore;
axiosMock = mocks.axiosMock;

axiosMock.onGet(getCourseDetailsUrl(courseId, 'abc123')).reply(200, {
courseId,
name: 'Course Test',
start: Date(),
});
axiosMock.onGet(`${getCourseAppsApiUrl()}/${courseId}`).reply(200, [
{
id: 'live',
enabled: true,
name: 'Live',
description: 'Enable in-platform video conferencing by configuring live',
allowed_operations: {
enable: true,
configure: true,
},
documentation_links: {},
},
]);
});

test('Live Configuration modal is visible', async () => {
Expand All @@ -96,6 +115,7 @@ describe('LiveSettings', () => {
await mockStore({ enabled: true });
renderComponent();

await waitFor(() => expect(container.querySelector('label[for="enable-live-toggle"]')).not.toBeNull());
const label = container.querySelector('label[for="enable-live-toggle"]');
const helperText = container.querySelector('#enable-live-toggleHelpText');
const enableBadge = queryByTestId(container, 'enable-badge');
Expand All @@ -109,6 +129,7 @@ describe('LiveSettings', () => {
await mockStore({ enabled: false, piiSharingAllowed: false });
renderComponent();

await waitFor(() => expect(container.querySelector('label[for="enable-live-toggle"]')).not.toBeNull());
const label = container.querySelector('label[for="enable-live-toggle"]');
const helperText = container.querySelector('#enable-live-toggleHelpText');

Expand Down
23 changes: 21 additions & 2 deletions plugins/course-apps/live/ZoomSettings.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import ReactDOM from 'react-dom';
import { executeThunk } from 'CourseAuthoring/utils';
import PagesAndResourcesProvider from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider';
import { CourseAuthoringProvider } from 'CourseAuthoring/CourseAuthoringContext';
import { getCourseAppsApiUrl, getCourseDetailsUrl } from 'CourseAuthoring/data/api';
import LiveSettings from './Settings';
import {
generateLiveConfigurationApiResponse,
courseId,
initialState,
configurationProviders,
} from './factories/mockApiResponses';

Expand Down Expand Up @@ -69,9 +69,28 @@ const mockStore = async ({

describe('Zoom Settings', () => {
beforeEach(async () => {
const mocks = initializeMocks({ initialState });
const mocks = initializeMocks();
store = mocks.reduxStore;
axiosMock = mocks.axiosMock;

axiosMock.onGet(getCourseDetailsUrl(courseId, 'abc123')).reply(200, {
courseId,
name: 'Course Test',
start: Date(),
});
axiosMock.onGet(`${getCourseAppsApiUrl()}/${courseId}`).reply(200, [
{
id: 'live',
enabled: true,
name: 'Live',
description: 'Enable in-platform video conferencing by configuring live',
allowed_operations: {
enable: true,
configure: true,
},
documentation_links: {},
},
]);
});

test('LTI fields are visible when pii sharing is enabled', async () => {
Expand Down
Loading