diff --git a/src/course-outline/CourseOutline.test.jsx b/src/course-outline/CourseOutline.test.jsx index 7a62beb475..4087cfeee7 100644 --- a/src/course-outline/CourseOutline.test.jsx +++ b/src/course-outline/CourseOutline.test.jsx @@ -1,14 +1,34 @@ import React from 'react'; -import { render, waitFor } from '@testing-library/react'; +import { + render, waitFor, cleanup, +} from '@testing-library/react'; import { IntlProvider } from '@edx/frontend-platform/i18n'; import { AppProvider } from '@edx/frontend-platform/react'; import { initializeMockApp } from '@edx/frontend-platform'; import MockAdapter from 'axios-mock-adapter'; import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth'; +import { + getCourseBestPracticesApiUrl, + getCourseLaunchApiUrl, + getCourseOutlineIndexApiUrl, + getCourseReindexApiUrl, + getEnableHighlightsEmailsApiUrl, +} from './data/api'; +import { + enableCourseHighlightsEmailsQuery, + fetchCourseBestPracticesQuery, + fetchCourseLaunchQuery, + fetchCourseOutlineIndexQuery, + fetchCourseReindexQuery, +} from './data/thunk'; import initializeStore from '../store'; -import { courseOutlineIndexMock } from './__mocks__'; -import { getCourseOutlineIndexApiUrl } from './data/api'; +import { + courseOutlineIndexMock, + courseBestPracticesMock, + courseLaunchMock, +} from './__mocks__'; +import { executeThunk } from '../utils'; import CourseOutline from './CourseOutline'; import messages from './messages'; @@ -33,7 +53,7 @@ const RootWrapper = () => ( ); describe('', () => { - beforeEach(() => { + beforeEach(async () => { initializeMockApp({ authenticatedUser: { userId: 3, @@ -45,13 +65,13 @@ describe('', () => { store = initializeStore(); axiosMock = new MockAdapter(getAuthenticatedHttpClient()); - }); - - it('render CourseOutline component correctly', async () => { axiosMock .onGet(getCourseOutlineIndexApiUrl(courseId)) .reply(200, courseOutlineIndexMock); + await executeThunk(fetchCourseOutlineIndexQuery(courseId), store.dispatch); + }); + it('render CourseOutline component correctly', async () => { const { getByText } = render(); await waitFor(() => { @@ -59,4 +79,75 @@ describe('', () => { expect(getByText(messages.headingSubtitle.defaultMessage)).toBeInTheDocument(); }); }); + + it('check reindex and render success alert is correctly', async () => { + const { getByText } = render(); + + axiosMock + .onGet(getCourseReindexApiUrl(courseOutlineIndexMock.reindexLink)) + .reply(200); + await executeThunk(fetchCourseReindexQuery(courseId, courseOutlineIndexMock.reindexLink), store.dispatch); + + expect(getByText(messages.alertSuccessDescription.defaultMessage)).toBeInTheDocument(); + }); + + it('render error alert after failed reindex correctly', async () => { + const { getByText } = render(); + + axiosMock + .onGet(getCourseReindexApiUrl('some link')) + .reply(500); + await executeThunk(fetchCourseReindexQuery(courseId, 'some link'), store.dispatch); + + expect(getByText(messages.alertErrorTitle.defaultMessage)).toBeInTheDocument(); + }); + + it('render checklist value correctly', async () => { + const { getByText } = render(); + + axiosMock + .onGet(getCourseBestPracticesApiUrl({ + courseId, excludeGraded: true, all: true, + })) + .reply(200, courseBestPracticesMock); + + axiosMock + .onGet(getCourseLaunchApiUrl({ + courseId, gradedOnly: true, validateOras: true, all: true, + })) + .reply(200, courseLaunchMock); + + await executeThunk(fetchCourseLaunchQuery({ + courseId, gradedOnly: true, validateOras: true, all: true, + }), store.dispatch); + await executeThunk(fetchCourseBestPracticesQuery({ + courseId, excludeGraded: true, all: true, + }), store.dispatch); + + expect(getByText('4/9 completed')).toBeInTheDocument(); + }); + + it('check enable highlights when enable highlights query is successfully', async () => { + cleanup(); + const { getByText } = render(); + + axiosMock + .onGet(getCourseOutlineIndexApiUrl(courseId)) + .reply(200, { + ...courseOutlineIndexMock, + highlightsEnabledForMessaging: false, + }); + + axiosMock + .onPost(getEnableHighlightsEmailsApiUrl(courseId), { + publish: 'republish', + metadata: { + highlights_enabled_for_messaging: true, + }, + }) + .reply(200); + + await executeThunk(enableCourseHighlightsEmailsQuery(courseId), store.dispatch); + expect(getByText('Enabled')).toBeInTheDocument(); + }); }); diff --git a/src/course-outline/__mocks__/courseBestPractices.js b/src/course-outline/__mocks__/courseBestPractices.js new file mode 100644 index 0000000000..494c54d856 --- /dev/null +++ b/src/course-outline/__mocks__/courseBestPractices.js @@ -0,0 +1,43 @@ +module.exports = { + isSelfPaced: false, + sections: { + totalNumber: 6, + totalVisible: 4, + numberWithHighlights: 2, + highlightsActiveForCourse: true, + highlightsEnabled: true, + }, + subsections: { + totalVisible: 5, + numWithOneBlockType: 2, + numBlockTypes: { + min: 0, + max: 3, + mean: 1, + median: 1, + mode: 1, + }, + }, + units: { + totalVisible: 9, + numBlocks: { + min: 1, + max: 2, + mean: 2, + median: 2, + mode: 2, + }, + }, + videos: { + totalNumber: 7, + numMobileEncoded: 0, + numWithValId: 3, + durations: { + min: null, + max: null, + mean: null, + median: null, + mode: null, + }, + }, +}; diff --git a/src/course-outline/__mocks__/courseLaunch.js b/src/course-outline/__mocks__/courseLaunch.js new file mode 100644 index 0000000000..40b629f465 --- /dev/null +++ b/src/course-outline/__mocks__/courseLaunch.js @@ -0,0 +1,31 @@ +module.exports = { + isSelfPaced: false, + dates: { + hasStartDate: true, + hasEndDate: false, + }, + assignments: { + totalNumber: 11, + totalVisible: 7, + assignmentsWithDatesBeforeStart: [], + assignmentsWithDatesAfterEnd: [], + assignmentsWithOraDatesBeforeStart: [], + assignmentsWithOraDatesAfterEnd: [], + }, + grades: { + hasGradingPolicy: true, + sumOfWeights: 1, + }, + certificates: { + isActivated: false, + hasCertificate: false, + isEnabled: true, + }, + updates: { + hasUpdate: true, + }, + proctoring: { + needsProctoringEscalationEmail: false, + hasProctoringEscalationEmail: false, + }, +}; diff --git a/src/course-outline/__mocks__/courseOutlineIndex.js b/src/course-outline/__mocks__/courseOutlineIndex.js index c767f85f26..b65784c9be 100644 --- a/src/course-outline/__mocks__/courseOutlineIndex.js +++ b/src/course-outline/__mocks__/courseOutlineIndex.js @@ -1,29 +1,2952 @@ module.exports = { - course_release_date: 'Set Date', - course_structure: {}, - deprecated_blocks_info: { - deprecated_enabled_block_types: [], + courseReleaseDate: 'Set Date', + courseStructure: { + id: 'block-v1:edX+DemoX+Demo_Course+type@course+block@course', + displayName: 'Demonstration Course', + category: 'course', + hasChildren: true, + unitLevelDiscussions: false, + editedOn: 'Aug 23, 2023 at 12:35 UTC', + published: true, + publishedOn: 'Aug 23, 2023 at 11:32 UTC', + studioUrl: '/course/course-v1:edX+DemoX+Demo_Course', + releasedToStudents: false, + releaseDate: 'Nov 09, 2023 at 22:00 UTC', + visibilityState: null, + hasExplicitStaffLock: false, + start: '2023-11-09T22:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + highlightsEnabledForMessaging: true, + highlightsEnabled: true, + highlightsPreviewOnly: false, + highlightsDocUrl: 'http://edx.readthedocs.io/projects/open-edx-building-and-running-a-course/en/latest/developing_course/course_sections.html#set-section-highlights-for-weekly-course-highlight-messages', + enableProctoredExams: false, + createZendeskTickets: true, + enableTimedExams: true, + childInfo: { + category: 'chapter', + displayName: 'Section', + children: [ + { + id: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b', + displayName: 'Introduction 12', + category: 'chapter', + hasChildren: true, + editedOn: 'Aug 23, 2023 at 12:35 UTC', + published: true, + publishedOn: 'Aug 23, 2023 at 12:35 UTC', + studioUrl: '/course/course-v1:edX+DemoX+Demo_Course?show=block-v1%3AedX%2BDemoX%2BDemo_Course%2Btype%40chapter%2Bblock%40d8a6192ade314473a78242dfeedfbf5b', + releasedToStudents: true, + releaseDate: 'Aug 10, 2023 at 22:00 UTC', + visibilityState: 'staff_only', + hasExplicitStaffLock: true, + start: '2023-08-10T22:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + highlights: [ + 'New Highlight 1', + 'New Highlight 4', + ], + highlightsEnabled: true, + highlightsPreviewOnly: false, + highlightsDocUrl: 'http://edx.readthedocs.io/projects/open-edx-building-and-running-a-course/en/latest/developing_course/course_sections.html#set-section-highlights-for-weekly-course-highlight-messages', + childInfo: { + category: 'sequential', + displayName: 'Subsection', + children: [ + { + id: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction', + displayName: 'Demo Course Overview', + category: 'sequential', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/course/course-v1:edX+DemoX+Demo_Course?show=block-v1%3AedX%2BDemoX%2BDemo_Course%2Btype%40sequential%2Bblock%40edx_introduction', + releasedToStudents: true, + releaseDate: 'Jan 01, 1970 at 05:00 UTC', + visibilityState: 'staff_only', + hasExplicitStaffLock: false, + start: '1970-01-01T05:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + hideAfterDue: false, + isProctoredExam: false, + wasExamEverLinkedWithExternal: false, + onlineProctoringRules: '', + isPracticeExam: false, + isOnboardingExam: false, + isTimeLimited: false, + examReviewRules: '', + defaultTimeLimitMinutes: null, + proctoringExamConfigurationLink: null, + supportsOnboarding: false, + showReviewRules: true, + childInfo: { + category: 'vertical', + displayName: 'Unit', + children: [ + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc', + displayName: 'Introduction: Video and Sequences', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc', + releasedToStudents: true, + releaseDate: 'Jan 01, 1970 at 05:00 UTC', + visibilityState: 'staff_only', + hasExplicitStaffLock: false, + start: '1970-01-01T05:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: true, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + ], + }, + ancestorHasStaffLock: true, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + ], + }, + ancestorHasStaffLock: false, + staffOnlyMessage: true, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions', + displayName: 'Example Week 2: Get Interactive', + category: 'chapter', + hasChildren: true, + editedOn: 'Aug 16, 2023 at 11:52 UTC', + published: true, + publishedOn: 'Aug 16, 2023 at 11:52 UTC', + studioUrl: '/course/course-v1:edX+DemoX+Demo_Course?show=block-v1%3AedX%2BDemoX%2BDemo_Course%2Btype%40chapter%2Bblock%40graded_interactions', + releasedToStudents: false, + releaseDate: 'Nov 09, 2023 at 22:00 UTC', + visibilityState: 'ready', + hasExplicitStaffLock: false, + start: '2023-11-09T22:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + highlights: [ + 'New', + ], + highlightsEnabled: true, + highlightsPreviewOnly: false, + highlightsDocUrl: 'http://edx.readthedocs.io/projects/open-edx-building-and-running-a-course/en/latest/developing_course/course_sections.html#set-section-highlights-for-weekly-course-highlight-messages', + childInfo: { + category: 'sequential', + displayName: 'Subsection', + children: [ + { + id: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@simulations', + displayName: "Lesson 2 - Let's Get Interactive!", + category: 'sequential', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/course/course-v1:edX+DemoX+Demo_Course?show=block-v1%3AedX%2BDemoX%2BDemo_Course%2Btype%40sequential%2Bblock%40simulations', + releasedToStudents: true, + releaseDate: 'Jan 01, 1970 at 05:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '1970-01-01T05:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + hideAfterDue: false, + isProctoredExam: false, + wasExamEverLinkedWithExternal: false, + onlineProctoringRules: '', + isPracticeExam: false, + isOnboardingExam: false, + isTimeLimited: false, + examReviewRules: '', + defaultTimeLimitMinutes: null, + proctoringExamConfigurationLink: null, + supportsOnboarding: false, + showReviewRules: true, + childInfo: { + category: 'vertical', + displayName: 'Unit', + children: [ + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@d0d804e8863c4a95a659c04d8a2b2bc0', + displayName: "Lesson 2 - Let's Get Interactive! ", + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@d0d804e8863c4a95a659c04d8a2b2bc0', + releasedToStudents: true, + releaseDate: 'Jan 01, 1970 at 05:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '1970-01-01T05:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_2dbb0072785e', + displayName: 'An Interactive Reference Table', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_2dbb0072785e', + releasedToStudents: true, + releaseDate: 'Jan 01, 1970 at 05:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '1970-01-01T05:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_98cf62510471', + displayName: 'Zooming Diagrams', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_98cf62510471', + releasedToStudents: true, + releaseDate: 'Jan 01, 1970 at 05:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '1970-01-01T05:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_d32bf9b2242c', + displayName: 'Electronic Sound Experiment', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_d32bf9b2242c', + releasedToStudents: true, + releaseDate: 'Jan 01, 1970 at 05:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '1970-01-01T05:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@4e592689563243c484af947465eaef0d', + displayName: 'New Unit', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@4e592689563243c484af947465eaef0d', + releasedToStudents: true, + releaseDate: 'Jan 01, 1970 at 05:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '1970-01-01T05:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + ], + }, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@graded_simulations', + displayName: 'Homework - Labs and Demos', + category: 'sequential', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/course/course-v1:edX+DemoX+Demo_Course?show=block-v1%3AedX%2BDemoX%2BDemo_Course%2Btype%40sequential%2Bblock%40graded_simulations', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: 'Homework', + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + hideAfterDue: false, + isProctoredExam: false, + wasExamEverLinkedWithExternal: false, + onlineProctoringRules: '', + isPracticeExam: false, + isOnboardingExam: false, + isTimeLimited: false, + examReviewRules: '', + defaultTimeLimitMinutes: null, + proctoringExamConfigurationLink: null, + supportsOnboarding: false, + showReviewRules: true, + childInfo: { + category: 'vertical', + displayName: 'Unit', + children: [ + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@d6cee45205a449369d7ef8f159b22bdf', + displayName: 'Labs and Demos', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@d6cee45205a449369d7ef8f159b22bdf', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_aae927868e55', + displayName: 'Code Grader', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_aae927868e55', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_c037f3757df1', + displayName: 'Electric Circuit Simulator', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_c037f3757df1', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_bc69a47c6fae', + displayName: 'Protein Creator', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_bc69a47c6fae', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@8f89194410954e768bde1764985454a7', + displayName: 'Molecule Structures', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@8f89194410954e768bde1764985454a7', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + ], + }, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@175e76c4951144a29d46211361266e0e', + displayName: 'Homework - Essays', + category: 'sequential', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/course/course-v1:edX+DemoX+Demo_Course?show=block-v1%3AedX%2BDemoX%2BDemo_Course%2Btype%40sequential%2Bblock%40175e76c4951144a29d46211361266e0e', + releasedToStudents: false, + releaseDate: 'Nov 09, 2023 at 22:00 UTC', + visibilityState: 'ready', + hasExplicitStaffLock: false, + start: '2023-11-09T22:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + hideAfterDue: false, + isProctoredExam: false, + wasExamEverLinkedWithExternal: false, + onlineProctoringRules: '', + isPracticeExam: false, + isOnboardingExam: false, + isTimeLimited: false, + examReviewRules: '', + defaultTimeLimitMinutes: null, + proctoringExamConfigurationLink: null, + supportsOnboarding: false, + showReviewRules: true, + childInfo: { + category: 'vertical', + displayName: 'Unit', + children: [ + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@fb79dcbad35b466a8c6364f8ffee9050', + displayName: 'Peer Assessed Essays', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@fb79dcbad35b466a8c6364f8ffee9050', + releasedToStudents: false, + releaseDate: 'Nov 09, 2023 at 22:00 UTC', + visibilityState: 'ready', + hasExplicitStaffLock: false, + start: '2023-11-09T22:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + ], + }, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + ], + }, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@1414ffd5143b4b508f739b563ab468b7', + displayName: 'About Exams and Certificates', + category: 'chapter', + hasChildren: true, + editedOn: 'Aug 10, 2023 at 10:40 UTC', + published: true, + publishedOn: 'Aug 10, 2023 at 10:40 UTC', + studioUrl: '/course/course-v1:edX+DemoX+Demo_Course?show=block-v1%3AedX%2BDemoX%2BDemo_Course%2Btype%40chapter%2Bblock%401414ffd5143b4b508f739b563ab468b7', + releasedToStudents: false, + releaseDate: 'Jan 01, 2030 at 05:00 UTC', + visibilityState: 'needs_attention', + hasExplicitStaffLock: false, + start: '2030-01-01T05:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + highlights: [], + highlightsEnabled: true, + highlightsPreviewOnly: false, + highlightsDocUrl: 'http://edx.readthedocs.io/projects/open-edx-building-and-running-a-course/en/latest/developing_course/course_sections.html#set-section-highlights-for-weekly-course-highlight-messages', + childInfo: { + category: 'sequential', + displayName: 'Subsection', + children: [ + { + id: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow', + displayName: 'edX Exams', + category: 'sequential', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/course/course-v1:edX+DemoX+Demo_Course?show=block-v1%3AedX%2BDemoX%2BDemo_Course%2Btype%40sequential%2Bblock%40workflow', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: 'Exam', + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + hideAfterDue: false, + isProctoredExam: false, + wasExamEverLinkedWithExternal: false, + onlineProctoringRules: '', + isPracticeExam: false, + isOnboardingExam: false, + isTimeLimited: false, + examReviewRules: '', + defaultTimeLimitMinutes: null, + proctoringExamConfigurationLink: null, + supportsOnboarding: false, + showReviewRules: true, + childInfo: { + category: 'vertical', + displayName: 'Unit', + children: [ + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@934cc32c177d41b580c8413e561346b3', + displayName: 'EdX Exams', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@934cc32c177d41b580c8413e561346b3', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_f04afeac0131', + displayName: 'Immediate Feedback', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_f04afeac0131', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@b6662b497c094bcc9b870d8270c90c93', + displayName: 'Getting Answers', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@b6662b497c094bcc9b870d8270c90c93', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@f91d8d31f7cf48ce990f8d8745ae4cfa', + displayName: 'Answering More Than Once', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@f91d8d31f7cf48ce990f8d8745ae4cfa', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_ac391cde8a91', + displayName: 'Limited Checks', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_ac391cde8a91', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_36e0beb03f0a', + displayName: 'Randomized Questions', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_36e0beb03f0a', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@1b0e2c2c84884b95b1c99fb678cc964c', + displayName: 'Overall Grade Performance', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@1b0e2c2c84884b95b1c99fb678cc964c', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@c7e98fd39a6944edb6b286c32e1150ff', + displayName: 'Passing a Course', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@c7e98fd39a6944edb6b286c32e1150ff', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@d6eaa391d2be41dea20b8b1bfbcb1c45', + displayName: 'Getting Your edX Certificate', + category: 'vertical', + hasChildren: true, + editedOn: 'Jul 07, 2023 at 11:14 UTC', + published: true, + publishedOn: 'Jul 07, 2023 at 11:14 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@d6eaa391d2be41dea20b8b1bfbcb1c45', + releasedToStudents: true, + releaseDate: 'Feb 05, 2013 at 00:00 UTC', + visibilityState: 'live', + hasExplicitStaffLock: false, + start: '2013-02-05T00:00:00Z', + graded: true, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + ], + }, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + ], + }, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + { + id: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@46e11a7b395f45b9837df6c6ac609004', + displayName: 'Publish section', + category: 'chapter', + hasChildren: true, + editedOn: 'Aug 23, 2023 at 12:22 UTC', + published: true, + publishedOn: 'Aug 23, 2023 at 12:22 UTC', + studioUrl: '/course/course-v1:edX+DemoX+Demo_Course?show=block-v1%3AedX%2BDemoX%2BDemo_Course%2Btype%40chapter%2Bblock%4046e11a7b395f45b9837df6c6ac609004', + releasedToStudents: false, + releaseDate: 'Nov 09, 2023 at 22:00 UTC', + visibilityState: 'ready', + hasExplicitStaffLock: false, + start: '2023-11-09T22:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + highlights: [], + highlightsEnabled: true, + highlightsPreviewOnly: false, + highlightsDocUrl: 'http://edx.readthedocs.io/projects/open-edx-building-and-running-a-course/en/latest/developing_course/course_sections.html#set-section-highlights-for-weekly-course-highlight-messages', + childInfo: { + category: 'sequential', + displayName: 'Subsection', + children: [ + { + id: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@1945e9656cbe4abe8f2020c67e9e1f61', + displayName: 'Subsection sub', + category: 'sequential', + hasChildren: true, + editedOn: 'Aug 23, 2023 at 11:32 UTC', + published: true, + publishedOn: 'Aug 23, 2023 at 11:33 UTC', + studioUrl: '/course/course-v1:edX+DemoX+Demo_Course?show=block-v1%3AedX%2BDemoX%2BDemo_Course%2Btype%40sequential%2Bblock%401945e9656cbe4abe8f2020c67e9e1f61', + releasedToStudents: false, + releaseDate: 'Nov 09, 2023 at 22:00 UTC', + visibilityState: 'ready', + hasExplicitStaffLock: false, + start: '2023-11-09T22:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + hideAfterDue: false, + isProctoredExam: false, + wasExamEverLinkedWithExternal: false, + onlineProctoringRules: '', + isPracticeExam: false, + isOnboardingExam: false, + isTimeLimited: false, + examReviewRules: '', + defaultTimeLimitMinutes: null, + proctoringExamConfigurationLink: null, + supportsOnboarding: false, + showReviewRules: true, + childInfo: { + category: 'vertical', + displayName: 'Unit', + children: [ + { + id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@b8149aa5af944aed8eebf9c7dc9f3d0b', + displayName: 'Unit', + category: 'vertical', + hasChildren: true, + editedOn: 'Aug 23, 2023 at 11:32 UTC', + published: true, + publishedOn: 'Aug 23, 2023 at 11:33 UTC', + studioUrl: '/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@b8149aa5af944aed8eebf9c7dc9f3d0b', + releasedToStudents: false, + releaseDate: 'Nov 09, 2023 at 22:00 UTC', + visibilityState: 'ready', + hasExplicitStaffLock: false, + start: '2023-11-09T22:00:00Z', + graded: false, + dueDate: '', + due: null, + relativeWeeksDue: null, + format: null, + courseGraders: [ + 'Homework', + 'Exam', + ], + hasChanges: false, + actions: { + deletable: true, + draggable: true, + childAddable: true, + duplicable: true, + }, + explanatoryMessage: null, + groupAccess: {}, + userPartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + showCorrectness: 'always', + discussionEnabled: true, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + ], + }, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + ], + }, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + ], + }, + ancestorHasStaffLock: false, + staffOnlyMessage: false, + hasPartitionGroupComponents: false, + userPartitionInfo: { + selectablePartitions: [ + { + id: 50, + name: 'Enrollment Track Groups', + scheme: 'enrollment_track', + groups: [ + { + id: 2, + name: 'Verified Certificate', + selected: false, + deleted: false, + }, + { + id: 1, + name: 'Audit', + selected: false, + deleted: false, + }, + ], + }, + ], + selectedPartitionIndex: -1, + selectedGroupsLabel: '', + }, + }, + deprecatedBlocksInfo: { + deprecatedEnabledBlockTypes: [], blocks: [], - advance_settings_url: '/settings/advanced/course-v1:edx+101+y76', + advanceSettingsUrl: '/settings/advanced/course-v1:edx+101+y76', }, - discussions_incontext_feedback_url: '', - discussions_incontext_learnmore_url: '', - initial_state: { - expanded_locators: [ + discussionsIncontextFeedbackUrl: '', + discussionsIncontextLearnmoreUrl: '', + initialState: { + expandedLocators: [ 'block-v1:edx+101+y76+type@chapter+block@03de0adc9d1c4cc097062d80eb04abf6', 'block-v1:edx+101+y76+type@sequential+block@8a85e287e30a47e98d8c1f37f74a6a9d', ], - locator_to_show: 'block-v1:edx+101+y76+type@chapter+block@03de0adc9d1c4cc097062d80eb04abf6', + locatorToShow: 'block-v1:edx+101+y76+type@chapter+block@03de0adc9d1c4cc097062d80eb04abf6', }, - language_code: 'en', - learn_more_develop_course_url: 'https://edx.readthedocs.io/projects/open-edx-building-and-running-a-course/en/latest/developing_course/index.html', - learn_more_grading_url: 'https://edx.readthedocs.io/projects/open-edx-building-and-running-a-course/en/latest/grading/index.html', - learn_more_outline_url: 'https://edx.readthedocs.io/projects/open-edx-building-and-running-a-course/en/latest/developing_course/course_outline.html', - learn_more_visibility_url: 'https://edx.readthedocs.io/projects/open-edx-building-and-running-a-course/en/latest/developing_course/controlling_content_visibility.html', - lms_link: '//localhost:18000/courses/course-v1:edx+101+y76/jump_to/block-v1:edx+101+y76+type@course+block@course', - mfe_proctored_exam_settings_url: '', - notification_dismiss_url: '/course_notifications/course-v1:edx+101+y76/2', - proctoring_errors: [], - reindex_link: '/course/course-v1:edx+101+y76/search_reindex', - rerun_notification_id: 2, + languageCode: 'en', + lmsLink: '//localhost:18000/courses/course-v1:edx+101+y76/jump_to/block-v1:edx+101+y76+type@course+block@course', + mfeProctoredExamSettingsUrl: '', + notificationDismissUrl: '/course_notifications/course-v1:edx+101+y76/2', + proctoringErrors: [], + reindexLink: '/course/course-v1:edx+101+y76/search_reindex', + rerunNotificationId: 2, }; diff --git a/src/course-outline/__mocks__/courseOutlineIndexWithoutSections.js b/src/course-outline/__mocks__/courseOutlineIndexWithoutSections.js new file mode 100644 index 0000000000..89a48492d9 --- /dev/null +++ b/src/course-outline/__mocks__/courseOutlineIndexWithoutSections.js @@ -0,0 +1,25 @@ +module.exports = { + courseReleaseDate: 'Set Date', + courseStructure: {}, + deprecatedBlocksInfo: { + deprecatedEnabledBlockTypes: [], + blocks: [], + advanceSettingsUrl: '/settings/advanced/course-v1:edx+101+y76', + }, + discussionsIncontextFeedbackUrl: '', + discussionsIncontextLearnmoreUrl: '', + initialState: { + expandedLocators: [ + 'block-v1:edx+101+y76+type@chapter+block@03de0adc9d1c4cc097062d80eb04abf6', + 'block-v1:edx+101+y76+type@sequential+block@8a85e287e30a47e98d8c1f37f74a6a9d', + ], + locatorToShow: 'block-v1:edx+101+y76+type@chapter+block@03de0adc9d1c4cc097062d80eb04abf6', + }, + languageCode: 'en', + lmsLink: '//localhost:18000/courses/course-v1:edx+101+y76/jump_to/block-v1:edx+101+y76+type@course+block@course', + mfeProctoredExamSettingsUrl: '', + notificationDismissUrl: '/course_notifications/course-v1:edx+101+y76/2', + proctoringErrors: [], + reindexLink: '/course/course-v1:edx+101+y76/search_reindex', + rerunNotificationId: 2, +}; diff --git a/src/course-outline/__mocks__/index.js b/src/course-outline/__mocks__/index.js index 1f90fb7828..e699605ef6 100644 --- a/src/course-outline/__mocks__/index.js +++ b/src/course-outline/__mocks__/index.js @@ -1,2 +1,4 @@ -// eslint-disable-next-line import/prefer-default-export export { default as courseOutlineIndexMock } from './courseOutlineIndex'; +export { default as courseOutlineIndexWithoutSections } from './courseOutlineIndexWithoutSections'; +export { default as courseBestPracticesMock } from './courseBestPractices'; +export { default as courseLaunchMock } from './courseLaunch'; diff --git a/src/course-outline/data/api.js b/src/course-outline/data/api.js index 6232d659fc..dbc68e8cb9 100644 --- a/src/course-outline/data/api.js +++ b/src/course-outline/data/api.js @@ -14,7 +14,7 @@ export const getCourseLaunchApiUrl = ({ validateOras, all, }) => `${getApiBaseUrl()}/api/courses/v1/validation/${courseId}/?graded_only=${gradedOnly}&validate_oras=${validateOras}&all=${all}`; -const getEnableHighlightsEmailsApiUrl = (courseId) => { +export const getEnableHighlightsEmailsApiUrl = (courseId) => { const formattedCourseId = courseId.split('course-v1:')[1]; return `${getApiBaseUrl()}/xblock/block-v1:${formattedCourseId}+type@course+block@course`; }; diff --git a/src/course-outline/data/thunk.js b/src/course-outline/data/thunk.js index 91b611accc..194ae03d79 100644 --- a/src/course-outline/data/thunk.js +++ b/src/course-outline/data/thunk.js @@ -31,10 +31,8 @@ export function fetchCourseOutlineIndexQuery(courseId) { dispatch(updateStatusBar({ courseReleaseDate, highlightsEnabledForMessaging, highlightsDocUrl })); dispatch(updateOutlineIndexLoadingStatus({ status: RequestStatus.SUCCESSFUL })); - return true; } catch (error) { dispatch(updateOutlineIndexLoadingStatus({ status: RequestStatus.FAILED })); - return false; } }; } @@ -86,10 +84,8 @@ export function enableCourseHighlightsEmailsQuery(courseId) { dispatch(fetchCourseOutlineIndexQuery(courseId)); dispatch(updateSavingStatus({ status: RequestStatus.SUCCESSFUL })); - return true; } catch (error) { dispatch(updateSavingStatus({ status: RequestStatus.FAILED })); - return false; } }; } @@ -101,12 +97,8 @@ export function fetchCourseReindexQuery(courseId, reindexLink) { try { await restartIndexingOnCourse(reindexLink); dispatch(updateReindexLoadingStatus({ status: RequestStatus.SUCCESSFUL })); - // dispatch(fetchCourseOutlineIndexQuery(courseId)); - - return true; } catch (error) { dispatch(updateReindexLoadingStatus({ status: RequestStatus.FAILED })); - return false; } }; } diff --git a/src/course-outline/header-navigations/HeaderNavigation.test.jsx b/src/course-outline/header-navigations/HeaderNavigation.test.jsx index 7bdb1e8ea4..dff210eb87 100644 --- a/src/course-outline/header-navigations/HeaderNavigation.test.jsx +++ b/src/course-outline/header-navigations/HeaderNavigation.test.jsx @@ -66,4 +66,20 @@ describe('', () => { fireEvent.click(viewLiveButton); expect(handleViewLiveMock).toHaveBeenCalledTimes(1); }); + + it('render collapse button correctly', () => { + const { getByRole } = renderComponent({ + isSectionsExpanded: true, + }); + + expect(getByRole('button', { name: messages.collapseAllButton.defaultMessage })).toBeInTheDocument(); + }); + + it('render expand button correctly', () => { + const { getByRole } = renderComponent({ + isSectionsExpanded: false, + }); + + expect(getByRole('button', { name: messages.expandAllButton.defaultMessage })).toBeInTheDocument(); + }); }); diff --git a/src/course-outline/status-bar/StatusBar.jsx b/src/course-outline/status-bar/StatusBar.jsx index d32edabaf1..72564d86a1 100644 --- a/src/course-outline/status-bar/StatusBar.jsx +++ b/src/course-outline/status-bar/StatusBar.jsx @@ -40,7 +40,7 @@ const StatusBar = ({ } return ( - +
{intl.formatMessage(messages.startDateTitle)}
', () => { fireEvent.click(enableHighlightsButton); expect(openEnableHighlightsModalMock).toHaveBeenCalledTimes(1); }); + + it('not render component when isLoading is true', () => { + const { queryByTestId } = renderComponent({ + isLoading: true, + }); + + expect(queryByTestId('outline-status-bar')).not.toBeInTheDocument(); + }); }); diff --git a/src/course-outline/utils/courseChecklistValidators.test.js b/src/course-outline/utils/courseChecklistValidators.test.js new file mode 100644 index 0000000000..401475bc2f --- /dev/null +++ b/src/course-outline/utils/courseChecklistValidators.test.js @@ -0,0 +1,297 @@ +import * as validators from './courseChecklistValidators'; + +describe('courseCheckValidators utility functions', () => { + describe('hasWelcomeMessage', () => { + it('returns true when course run has an update', () => { + expect(validators.hasWelcomeMessage({ hasUpdate: true })).toEqual(true); + }); + + it('returns false when course run does not have an update', () => { + expect(validators.hasWelcomeMessage({ hasUpdate: false })).toEqual(false); + }); + }); + + describe('hasGradingPolicy', () => { + it('returns true when sum of weights is 1', () => { + expect(validators.hasGradingPolicy( + { hasGradingPolicy: true, sumOfWeights: 1 }, + )).toEqual(true); + }); + + it('returns true when sum of weights is not 1 due to floating point approximation (1.00004)', () => { + expect(validators.hasGradingPolicy( + { hasGradingPolicy: true, sumOfWeights: 1.00004 }, + )).toEqual(true); + }); + + it('returns false when sum of weights is not 1', () => { + expect(validators.hasGradingPolicy( + { hasGradingPolicy: true, sumOfWeights: 2 }, + )).toEqual(false); + }); + + it('returns true when hasGradingPolicy is true', () => { + expect(validators.hasGradingPolicy( + { hasGradingPolicy: true, sumOfWeights: 1 }, + )).toEqual(true); + }); + + it('returns false when hasGradingPolicy is false', () => { + expect(validators.hasGradingPolicy( + { hasGradingPolicy: false, sumOfWeights: 1 }, + )).toEqual(false); + }); + }); + + describe('hasCertificate', () => { + it('returns true when certificates are activated and course run has a certificate', () => { + expect(validators.hasCertificate({ isActivated: true, hasCertificate: true })) + .toEqual(true); + }); + + it('returns false when certificates are not activated and course run has a certificate', () => { + expect(validators.hasCertificate({ isActivated: false, hasCertificate: true })) + .toEqual(false); + }); + + it('returns false when certificates are activated and course run does not have a certificate', () => { + expect(validators.hasCertificate({ isActivated: true, hasCertificate: false })) + .toEqual(false); + }); + + it('returns false when certificates are not activated and course run does not have a certificate', () => { + expect(validators.hasCertificate({ isActivated: false, hasCertificate: false })) + .toEqual(false); + }); + }); + + describe('hasDates', () => { + it('returns true when course run has start date and end date', () => { + expect(validators.hasDates({ hasStartDate: true, hasEndDate: true })).toEqual(true); + }); + + it('returns false when course run has no start date and end date', () => { + expect(validators.hasDates({ hasStartDate: false, hasEndDate: true })).toEqual(false); + }); + + it('returns true when course run has start date and no end date', () => { + expect(validators.hasDates({ hasStartDate: true, hasEndDate: false })).toEqual(false); + }); + + it('returns true when course run has no start date and no end date', () => { + expect(validators.hasDates({ hasStartDate: false, hasEndDate: false })).toEqual(false); + }); + }); + + describe('hasAssignmentDeadlines', () => { + it('returns true when a course run has start and end date and all assignments are within range', () => { + expect(validators.hasAssignmentDeadlines( + { + assignmentsWithDatesBeforeStart: 0, + assignmentsWithDatesAfterEnd: 0, + assignmentsWithOraDatesAfterEnd: 0, + assignmentsWithOraDatesBeforeStart: 0, + }, + { + hasStartDate: true, + hasEndDate: true, + }, + )).toEqual(true); + }); + + it('returns false when a course run has no start and no end date', () => { + expect(validators.hasAssignmentDeadlines( + {}, + { + hasStartDate: false, + hasEndDate: false, + }, + )).toEqual(false); + }); + + it('returns false when a course has start and end date and no assignments', () => { + expect(validators.hasAssignmentDeadlines( + { + totalNumber: 0, + }, + { + hasStartDate: true, + hasEndDate: true, + }, + )).toEqual(false); + }); + + it('returns false when a course run has start and end date and assignments before start', () => { + expect(validators.hasAssignmentDeadlines( + { + assignmentsWithDatesBeforeStart: ['test'], + assignmentsWithDatesAfterEnd: 0, + assignmentsWithOraDatesAfterEnd: 0, + assignmentsWithOraDatesBeforeStart: 0, + }, + { + hasStartDate: true, + hasEndDate: true, + }, + )).toEqual(false); + }); + + it('returns false when a course run has start and end date and assignments after end', () => { + expect(validators.hasAssignmentDeadlines( + { + assignmentsWithDatesBeforeStart: 0, + assignmentsWithDatesAfterEnd: ['test'], + assignmentsWithOraDatesAfterEnd: 0, + assignmentsWithOraDatesBeforeStart: 0, + }, + { + hasStartDate: true, + hasEndDate: true, + }, + )).toEqual(false); + }); + }); + + it( + 'returns false when a course run has start and end date and an ora with a date before start', + () => { + expect(validators.hasAssignmentDeadlines( + { + assignmentsWithDatesBeforeStart: 0, + assignmentsWithDatesAfterEnd: 0, + assignmentsWithOraDatesAfterEnd: 0, + assignmentsWithOraDatesBeforeStart: ['test'], + }, + { + hasStartDate: true, + hasEndDate: true, + }, + )).toEqual(false); + }, + ); + + it( + 'returns false when a course run has start and end date and an ora with a date after end', + () => { + expect(validators.hasAssignmentDeadlines( + { + assignmentsWithDatesBeforeStart: 0, + assignmentsWithDatesAfterEnd: 0, + assignmentsWithOraDatesAfterEnd: ['test'], + assignmentsWithOraDatesBeforeStart: 0, + }, + { + hasStartDate: true, + hasEndDate: true, + }, + )).toEqual(false); + }, + ); + + describe('hasShortVideoDuration', () => { + it('returns true if course run has no videos', () => { + expect(validators.hasShortVideoDuration({ totalNumber: 0 })).toEqual(true); + }); + + it('returns true if course run videos have a median duration <= to 600', () => { + expect(validators.hasShortVideoDuration({ totalNumber: 1, durations: { median: 100 } })) + .toEqual(true); + }); + + it('returns true if course run videos have a median duration > to 600', () => { + expect(validators.hasShortVideoDuration({ totalNumber: 10, durations: { median: 700 } })) + .toEqual(false); + }); + }); + + describe('hasMobileFriendlyVideos', () => { + it('returns true if course run has no videos', () => { + expect(validators.hasMobileFriendlyVideos({ totalNumber: 0 })).toEqual(true); + }); + + it('returns true if course run videos are >= 90% mobile friendly', () => { + expect(validators.hasMobileFriendlyVideos({ totalNumber: 10, numMobileEncoded: 9 })) + .toEqual(true); + }); + + it('returns true if course run videos are < 90% mobile friendly', () => { + expect(validators.hasMobileFriendlyVideos({ totalNumber: 10, numMobileEncoded: 8 })) + .toEqual(false); + }); + }); + + describe('hasDiverseSequences', () => { + it('returns true if < 20% of visible subsections have more than one block type', () => { + expect(validators.hasDiverseSequences({ totalVisible: 10, numWithOneBlockType: 1 })) + .toEqual(true); + }); + + it('returns false if no visible subsections', () => { + expect(validators.hasDiverseSequences({ totalVisible: 0 })).toEqual(false); + }); + + it('returns false if >= 20% of visible subsections have more than one block type', () => { + expect(validators.hasDiverseSequences({ totalVisible: 10, numWithOneBlockType: 3 })) + .toEqual(false); + }); + + it('return false if < 0 visible subsections', () => { + expect(validators.hasDiverseSequences({ totalVisible: -1, numWithOneBlockType: 1 })) + .toEqual(false); + }); + }); + + describe('hasWeeklyHighlights', () => { + it('returns true when course run has highlights enabled', () => { + const data = { highlightsActiveForCourse: true, highlightsEnabled: true }; + expect(validators.hasWeeklyHighlights(data)).toEqual(true); + }); + + it('returns false when course run has highlights enabled', () => { + const data = { highlightsActiveForCourse: false, highlightsEnabled: false }; + expect(validators.hasWeeklyHighlights(data)).toEqual(false); + + data.highlightsEnabled = true; + data.highlightsActiveForCourse = false; + expect(validators.hasWeeklyHighlights(data)).toEqual(false); + + data.highlightsEnabled = false; + data.highlightsActiveForCourse = true; + expect(validators.hasWeeklyHighlights(data)).toEqual(false); + }); + }); + + describe('hasShortUnitDepth', () => { + it('returns true when course run has median number of blocks <= 3', () => { + const units = { + numBlocks: { + median: 3, + }, + }; + + expect(validators.hasShortUnitDepth(units)).toEqual(true); + }); + + it('returns false when course run has median number of blocks > 3', () => { + const units = { + numBlocks: { + median: 4, + }, + }; + + expect(validators.hasShortUnitDepth(units)).toEqual(false); + }); + }); + + describe('hasProctoringEscalationEmail', () => { + it('returns true when the course has a proctoring escalation email', () => { + const proctoring = { hasProctoringEscalationEmail: true }; + expect(validators.hasProctoringEscalationEmail(proctoring)).toEqual(true); + }); + + it('returns false when the course does not have a proctoring escalation email', () => { + const proctoring = { hasProctoringEscalationEmail: false }; + expect(validators.hasProctoringEscalationEmail(proctoring)).toEqual(false); + }); + }); +}); diff --git a/src/course-outline/utils/getChecklistValues.test.js b/src/course-outline/utils/getChecklistValues.test.js new file mode 100644 index 0000000000..24ac32e973 --- /dev/null +++ b/src/course-outline/utils/getChecklistValues.test.js @@ -0,0 +1,86 @@ +import { getChecklistValues } from './getChecklistValues'; +import { CHECKLIST_FILTERS } from '../constants'; + +const checklist = [ + { + id: 'welcomeMessage', + pacingTypeFilter: CHECKLIST_FILTERS.ALL, + }, + { + id: 'gradingPolicy', + pacingTypeFilter: CHECKLIST_FILTERS.ALL, + }, + { + id: 'certificate', + pacingTypeFilter: CHECKLIST_FILTERS.ALL, + }, + { + id: 'courseDates', + pacingTypeFilter: CHECKLIST_FILTERS.ALL, + }, + { + id: 'assignmentDeadlines', + pacingTypeFilter: CHECKLIST_FILTERS.INSTRUCTOR_PACED, + }, + { + id: 'weeklyHighlights', + pacingTypeFilter: CHECKLIST_FILTERS.SELF_PACED, + }, + { + id: 'proctoringEmail', + pacingTypeFilter: CHECKLIST_FILTERS.ALL, + }, +]; + +let courseData; +describe('getChecklistValues utility function', () => { + beforeEach(() => { + courseData = { + isSelfPaced: true, + hasCertificatesEnabled: true, + hasHighlightsEnabled: true, + needsProctoringEscalationEmail: true, + }; + }); + it('returns only checklist items with filters ALL and SELF_PACED when isSelfPaced is true', () => { + const filteredChecklist = getChecklistValues({ checklist, ...courseData }); + + filteredChecklist.forEach((( + item => expect(item.pacingTypeFilter === CHECKLIST_FILTERS.ALL + || item.pacingTypeFilter === CHECKLIST_FILTERS.SELF_PACED) + ))); + + expect(filteredChecklist.filter(item => item.pacingTypeFilter === CHECKLIST_FILTERS.ALL).length) + .toEqual(checklist.filter(item => item.pacingTypeFilter === CHECKLIST_FILTERS.ALL).length); + expect(filteredChecklist.filter(item => item.pacingTypeFilter === CHECKLIST_FILTERS.SELF_PACED).length) + .toEqual(checklist.filter(item => item.pacingTypeFilter === CHECKLIST_FILTERS.SELF_PACED).length); + }); + + it('returns only checklist items with filters ALL and INSTRUCTOR_PACED when isSelfPaced is false', () => { + courseData.isSelfPaced = false; + const filteredChecklist = getChecklistValues({ checklist, ...courseData }); + + filteredChecklist.forEach((( + item => expect(item.pacingTypeFilter === CHECKLIST_FILTERS.ALL + || item.pacingTypeFilter === CHECKLIST_FILTERS.INSTRUCTOR_PACED) + ))); + + expect(filteredChecklist.filter(item => item.pacingTypeFilter === CHECKLIST_FILTERS.ALL).length) + .toEqual(checklist.filter(item => item.pacingTypeFilter === CHECKLIST_FILTERS.ALL).length); + expect(filteredChecklist + .filter(item => item.pacingTypeFilter === CHECKLIST_FILTERS.INSTRUCTOR_PACED).length) + .toEqual(checklist.filter(item => item.pacingTypeFilter === CHECKLIST_FILTERS.INSTRUCTOR_PACED).length); + }); + + it('excludes weekly highlights when they are disabled', () => { + courseData.hasHighlightsEnabled = false; + const filteredChecklist = getChecklistValues({ checklist, ...courseData }); + expect(filteredChecklist.filter(item => item.id === 'weeklyHighlights').length).toEqual(0); + }); + + it('excludes proctoring escalation email when not needed', () => { + courseData.needsProctoringEscalationEmail = false; + const filteredChecklist = getChecklistValues({ checklist, ...courseData }); + expect(filteredChecklist.filter(item => item.id === 'proctoringEmail').length).toEqual(0); + }); +});