Skip to content
Draft
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: 2 additions & 3 deletions plugins/course-apps/proctoring/Settings.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -471,9 +471,8 @@ describe('ProctoredExamSettings', () => {
screen.getByDisplayValue('mockproc');
});
// (1) for studio settings
// (2) waffle flags
// (3) for course details
expect(axiosMock.history.get.length).toBe(3);
// (2) for course details
expect(axiosMock.history.get.length).toBe(2);
Comment thread
farhan marked this conversation as resolved.
expect(axiosMock.history.get[0].url.includes('proctored_exam_settings')).toEqual(true);
});

Expand Down
20 changes: 3 additions & 17 deletions src/CourseAuthoringContext.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { getConfig } from '@edx/frontend-platform';
import {
createContext,
useContext,
Expand All @@ -10,7 +9,7 @@ import { useNavigate } from 'react-router';
import { useToggleWithValue } from '@src/hooks';
import { type UnitXBlock, type XBlock } from '@src/data/types';
import { CourseDetailsData } from './data/api';
import { useCourseDetails, useWaffleFlags } from './data/apiHooks';
import { useCourseDetails } from './data/apiHooks';
import { RequestStatusType } from './data/constants';
import { getOutlineIndexData } from './course-outline/data/selectors';

Expand Down Expand Up @@ -53,7 +52,6 @@ export const CourseAuthoringProvider = ({
courseId,
}: CourseAuthoringProviderProps) => {
const navigate = useNavigate();
const waffleFlags = useWaffleFlags();
const { data: courseDetails, status: courseDetailStatus } = useCourseDetails(courseId);
const canChangeProviders = getAuthenticatedUser().administrator || new Date(courseDetails?.start ?? 0) > new Date();
const { courseStructure } = useSelector(getOutlineIndexData);
Expand All @@ -65,25 +63,13 @@ export const CourseAuthoringProvider = ({
closeUnlinkModal,
] = useToggleWithValue<ModalState>();

const getUnitUrl = (locator: string) => {
if (getConfig().ENABLE_UNIT_PAGE === 'true' && waffleFlags.useNewUnitPage) {
// instanbul ignore next
return `/course/${courseId}/container/${locator}`;
}
return `${getConfig().STUDIO_BASE_URL}/container/${locator}`;
};
const getUnitUrl = (locator: string) => `/course/${courseId}/container/${locator}`;

/**
* Open the unit page for a given locator.
*/
const openUnitPage = async (locator: string) => {
const url = getUnitUrl(locator);
if (getConfig().ENABLE_UNIT_PAGE === 'true' && waffleFlags.useNewUnitPage) {
// instanbul ignore next
navigate(url);
} else {
window.location.assign(url);
}
navigate(getUnitUrl(locator));
};

const context = useMemo<CourseAuthoringContextData>(() => ({
Expand Down
10 changes: 3 additions & 7 deletions src/course-checklist/ChecklistSection/ChecklistItemBody.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,18 @@ import { ActionRow, Button, Icon } from '@openedx/paragon';
import { CheckCircle, RadioButtonUnchecked } from '@openedx/paragon/icons';
import { getConfig } from '@edx/frontend-platform';

import { useWaffleFlags } from '@src/data/apiHooks';

import messages from './messages';

const getUpdateLinks = (courseId, waffleFlags) => {
const getUpdateLinks = (courseId) => {
const baseUrl = getConfig().STUDIO_BASE_URL;
const isLegacyOutlineUrl = !waffleFlags.useNewCourseOutlinePage;

return {
welcomeMessage: `/course/${courseId}/course_info`,
gradingPolicy: `/course/${courseId}/settings/grading`,
certificate: `/course/${courseId}/certificates`,
courseDates: `/course/${courseId}/settings/details/#schedule`,
proctoringEmail: `${baseUrl}/pages-and-resources/proctoring/settings`,
outline: isLegacyOutlineUrl ? `${baseUrl}/course/${courseId}` : `/course/${courseId}`,
outline: `/course/${courseId}`,
};
};

Expand All @@ -29,8 +26,7 @@ const ChecklistItemBody = ({
isCompleted,
}) => {
const intl = useIntl();
const waffleFlags = useWaffleFlags(courseId);
const updateLinks = getUpdateLinks(courseId, waffleFlags);
const updateLinks = getUpdateLinks(courseId);

return (
<ActionRow>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,14 @@ import { FormattedMessage, FormattedNumber } from '@edx/frontend-platform/i18n';
import { Icon } from '@openedx/paragon';
import { Link } from 'react-router-dom';
import { ModeComment } from '@openedx/paragon/icons';
import { getConfig } from '@edx/frontend-platform';
import { useWaffleFlags } from '../../data/apiHooks';
import messages from './messages';

const ChecklistItemComment = ({
courseId,
checkId,
data,
}) => {
const waffleFlags = useWaffleFlags(courseId);

const getPathToCourseOutlinePage = (assignmentId) => (waffleFlags.useNewCourseOutlinePage
? `/course/${courseId}#${assignmentId}` :
`${getConfig().STUDIO_BASE_URL}/course/${courseId}#${assignmentId}`);
const getPathToCourseOutlinePage = (assignmentId) => `/course/${courseId}#${assignmentId}`;

const commentWrapper = (comment) => (
<div className="row m-0 mt-3 pt-3 border-top align-items-center" data-identifier="comment">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ describe('ChecklistSection', () => {
const { axiosMock } = initializeMocks();
axiosMock
.onGet(getApiWaffleFlagsUrl(courseId))
.reply(200, {
useNewCourseOutlinePage: true,
});
.reply(200, {});
});

it('a heading using the dataHeading prop', () => {
Expand Down
15 changes: 0 additions & 15 deletions src/course-unit/add-component/AddComponent.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
/* eslint-disable react/prop-types */
import userEvent, { UserEvent } from '@testing-library/user-event';

import { mockWaffleFlags } from '@src/data/apiHooks.mock';
import { RenderResult } from '@testing-library/react';
import {
act,
Expand Down Expand Up @@ -360,20 +359,6 @@ describe('<AddComponent />', () => {
}, expect.any(Function));
});

it('adds a PDF block and launches the legacy iframe editor', async () => {
const user = userEvent.setup();
mockWaffleFlags({ useNewPdfEditor: false });
const { getByRole, queryAllByRole } = renderComponent();
await createPdfBlock({ getByRole, queryAllByRole, user });
expect(handleCreateNewCourseXBlockMock).toHaveBeenCalled();
expect(handleCreateNewCourseXBlockMock).toHaveBeenCalledWith({
parentLocator: '123',
type: COMPONENT_TYPES.pdf,
// Setting the category and not supplying an additional function launches the traditional editor.
category: COMPONENT_TYPES.pdf,
});
});

it('verifies "Text" component selection in modal', async () => {
const user = userEvent.setup();
const { getByRole, getByText } = renderComponent();
Expand Down
6 changes: 3 additions & 3 deletions src/course-unit/add-component/AddComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const AddComponent = ({
const [selectedComponents, setSelectedComponents] = useState<SelectedComponent[]>([]);
const [usageId, setUsageId] = useState(null);
const { sendMessageToIframe } = useIframe();
const { useVideoGalleryFlow, useNewPdfEditor } = useWaffleFlags(courseId ?? undefined);
const { useVideoGalleryFlow } = useWaffleFlags(courseId ?? undefined);

const courseUnit = useSelector(getCourseUnitData);
const sequenceId = courseUnit?.ancestorInfo?.ancestors?.[0]?.id;
Expand Down Expand Up @@ -181,13 +181,13 @@ const AddComponent = ({
// *in code* and not just in UI seems like a mistake in retrospect.
//
// There will be more of these, and soon.
if (moduleName === COMPONENT_TYPES.pdf && useNewPdfEditor) {
if (moduleName === COMPONENT_TYPES.pdf) {
handleCreateNewCourseXBlock(
{ type: moduleName, parentLocator: blockId },
/* istanbul ignore next */
({ courseKey, locator }) => {
setCourseId(courseKey);
setBlockType(moduleName);
setBlockType(moduleName ?? null);
setNewBlockId(locator);
showXBlockEditorModal();
},
Expand Down
23 changes: 1 addition & 22 deletions src/course-unit/breadcrumbs/Breadcrumbs.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import userEvent from '@testing-library/user-event';
import { getConfig } from '@edx/frontend-platform';
import {
initializeMocks,
waitFor,
Expand Down Expand Up @@ -54,7 +53,7 @@ describe('<Breadcrumbs />', () => {
await executeThunk(fetchCourseSectionVerticalData(courseId), reduxStore.dispatch);
axiosMock
.onGet(getApiWaffleFlagsUrl(courseId))
.reply(200, { useNewCourseOutlinePage: true });
.reply(200, {});
});

it('render Breadcrumbs component correctly', async () => {
Expand Down Expand Up @@ -150,24 +149,4 @@ describe('<Breadcrumbs />', () => {
await user.click(dropdownItem);
expect(dropdownItem).toHaveAttribute('href', url);
});

it('falls back to window.location.href when the waffle flag is disabled', async () => {
const user = userEvent.setup();
// eslint-disable-next-line @typescript-eslint/naming-convention
const { ancestor_xblocks: [{ children: [{ display_name, url }] }] } = courseSectionVerticalMock;
axiosMock
.onGet(getApiWaffleFlagsUrl(courseId))
.reply(200, { useNewCourseOutlinePage: false });

const { getByText, getByRole } = renderComponent();

const dropdownBtn = getByText(breadcrumbsExpected.section.displayName);
await user.click(dropdownBtn);

const dropdownItem = getByRole('link', { name: display_name });
// We need waitFor here because the waffle flag defaults to true but asynchronously loads false from our axiosMock
await waitFor(() => {
expect(dropdownItem).toHaveAttribute('href', `${getConfig().STUDIO_BASE_URL}${url}`);
});
});
});
14 changes: 2 additions & 12 deletions src/course-unit/breadcrumbs/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,21 @@ import {
ArrowDropDown as ArrowDropDownIcon,
ChevronRight as ChevronRightIcon,
} from '@openedx/paragon/icons';
import { getConfig } from '@edx/frontend-platform';

import { useWaffleFlags } from '../../data/apiHooks';
import { getCourseSectionVertical } from '../data/selectors';
import { adoptCourseSectionUrl, subsectionFirstUnitEditUrl } from '../utils';

const Breadcrumbs = ({ courseId, parentUnitId }: { courseId: string; parentUnitId: string; }) => {
const { ancestorXblocks = [] } = useSelector(getCourseSectionVertical);
const waffleFlags = useWaffleFlags(courseId);

const getPathToCourseOutlinePage = (url) => (waffleFlags.useNewCourseOutlinePage
? url :
`${getConfig().STUDIO_BASE_URL}${url}`);

const getPathToCourseUnitPage = (url) => (waffleFlags.useNewUnitPage
? adoptCourseSectionUrl({ url, courseId, parentUnitId })
: `${getConfig().STUDIO_BASE_URL}${url}`);
const getPathToCourseUnitPage = (url) => adoptCourseSectionUrl({ url, courseId, parentUnitId });

// based on the level of breadcrumbs the url will differ
// at the subsection level it should navigate to the first unit if available
// if no unit then navigate to the subsection outline
function getPathToCoursePage(index, url, usageKey: string) {
let navUrl: string;
if (index === 0) {
navUrl = getPathToCourseOutlinePage(url);
navUrl = url;
} else if (index === 1) {
navUrl = subsectionFirstUnitEditUrl({ courseId, subsectionId: usageKey });
} else {
Expand Down
4 changes: 1 addition & 3 deletions src/custom-pages/CustomPages.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,7 @@ describe('CustomPages', () => {
axiosMock = mocks.axiosMock;
axiosMock
.onGet(getApiWaffleFlagsUrl(courseId))
.reply(200, {
useNewCourseOutlinePage: true,
});
.reply(200, {});
});
it('should ', async () => {
renderComponent();
Expand Down
7 changes: 1 addition & 6 deletions src/custom-pages/CustomPages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import DraggableList, { SortableItem } from '@src/generic/DraggableList';
import ErrorAlert from '@src/editors/sharedComponents/ErrorAlerts/ErrorAlert';
import { RequestStatus } from '@src/data/constants';
import { useModels } from '@src/generic/model-store';
import { useWaffleFlags } from '@src/data/apiHooks';
import getPageHeadTitle from '@src/generic/utils';
import { getPagePath } from '@src/utils';
import { DeprecatedReduxState } from '@src/store';
Expand Down Expand Up @@ -70,8 +69,6 @@ const CustomPages = () => {
const deletePageStatus = useSelector((state: DeprecatedReduxState) => state.customPages.deletingStatus);
const savingStatus = useSelector(getSavingStatus);
const loadingStatus = useSelector(getLoadingStatus);
const waffleFlags = useWaffleFlags(courseId);

const pages = useModels('customPages', customPagesIds);

const handleAddPage = () => {
Expand Down Expand Up @@ -128,9 +125,7 @@ const CustomPages = () => {
links={[
{
label: 'Content',
to: waffleFlags.useNewCourseOutlinePage
? `/course/${courseId}`
: `${config.STUDIO_BASE_URL}/course/${courseId}`,
to: `/course/${courseId}`,
},
{ label: 'Pages and Resources', to: getPagePath(courseId, 'true', 'tabs') },
]}
Expand Down
11 changes: 0 additions & 11 deletions src/data/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,6 @@ export const waffleFlagDefaults = {
enableCourseOptimizer: false,
enableNotifications: false,
enableCourseOptimizerCheckPrevRunLinks: false,
useNewHomePage: true,
useNewCustomPages: true,
useNewUpdatesPage: true,
useNewImportPage: false,
useNewExportPage: true,
useNewFilesUploadsPage: true,
useNewVideoUploadsPage: true,
useNewCourseOutlinePage: true,
useNewUnitPage: false,
useNewTextbooksPage: true,
useNewPdfEditor: true,
useReactMarkdownEditor: true,
useVideoGalleryFlow: false,
enableAuthzCourseAuthoring: false,
Expand Down
2 changes: 1 addition & 1 deletion src/data/apiHooks.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as apiHooks from './apiHooks';
* loading; if you need more realistic handling, use:
* axiosMock
* .onGet(getApiWaffleFlagsUrl(courseId))
* .reply(200, { useNewCourseOutlinePage: true }); // etc
* .reply(200, { enableCourseOptimizer: true }); // etc
*/
export function mockWaffleFlags(overrides: Partial<Record<WaffleFlagName, boolean>> = {}) {
return jest.spyOn(apiHooks, 'useWaffleFlags').mockImplementation(() => ({
Expand Down
Loading
Loading