diff --git a/cms/djangoapps/contentstore/views/tests/test_item.py b/cms/djangoapps/contentstore/views/tests/test_item.py index 7d125edb46..c646a5b879 100644 --- a/cms/djangoapps/contentstore/views/tests/test_item.py +++ b/cms/djangoapps/contentstore/views/tests/test_item.py @@ -2389,7 +2389,8 @@ class TestXBlockInfo(ItemTest): super(TestXBlockInfo, self).setUp() user_id = self.user.id self.chapter = ItemFactory.create( - parent_location=self.course.location, category='chapter', display_name="Week 1", user_id=user_id + parent_location=self.course.location, category='chapter', display_name="Week 1", user_id=user_id, + highlights=['highlight'], ) self.sequential = ItemFactory.create( parent_location=self.chapter.location, category='sequential', display_name="Lesson 1", user_id=user_id @@ -2596,6 +2597,7 @@ class TestXBlockInfo(ItemTest): self.assertEqual(xblock_info['graded'], False) self.assertEqual(xblock_info['due'], None) self.assertEqual(xblock_info['format'], None) + self.assertEqual(xblock_info['highlights'], self.chapter.highlights) # Finally, validate the entire response for consistency self.validate_xblock_info_consistency(xblock_info, has_child_info=has_child_info) diff --git a/cms/static/js/spec/views/pages/course_outline_spec.js b/cms/static/js/spec/views/pages/course_outline_spec.js index 1b943f744e..f92b986bb6 100644 --- a/cms/static/js/spec/views/pages/course_outline_spec.js +++ b/cms/static/js/spec/views/pages/course_outline_spec.js @@ -7,7 +7,7 @@ define(['jquery', 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers', 'common/j var createCourseOutlinePage, displayNameInput, model, outlinePage, requests, getItemsOfType, getItemHeaders, verifyItemsExpanded, expandItemsAndVerifyState, collapseItemsAndVerifyState, selectBasicSettings, selectVisibilitySettings, selectAdvancedSettings, createMockCourseJSON, createMockSectionJSON, - createMockSubsectionJSON, verifyTypePublishable, mockCourseJSON, mockEmptyCourseJSON, + createMockSubsectionJSON, verifyTypePublishable, mockCourseJSON, mockEmptyCourseJSON, setSelfPaced, mockSingleSectionCourseJSON, createMockVerticalJSON, createMockIndexJSON, mockCourseEntranceExamJSON, mockOutlinePage = readFixtures('mock/mock-course-outline-page.underscore'), mockRerunNotification = readFixtures('mock/mock-course-rerun-notification.underscore'); @@ -55,7 +55,9 @@ define(['jquery', 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers', 'common/j }, user_partitions: [], group_access: {}, - user_partition_info: {} + user_partition_info: {}, + highlights: [], + highlights_enabled: true }, options, {child_info: {children: children}}); }; @@ -160,6 +162,11 @@ define(['jquery', 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers', 'common/j this.$(".modal-section .settings-tab-button[data-tab='advanced']").click(); }; + setSelfPaced = function() { + /* global course */ + course.set('self_paced', true); + }; + createCourseOutlinePage = function(test, courseJSON, createOnly) { requests = AjaxHelpers.requests(test); model = new XBlockOutlineInfo(courseJSON, {parse: true}); @@ -255,7 +262,7 @@ define(['jquery', 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers', 'common/j 'due-date-editor', 'grading-editor', 'publish-editor', 'staff-lock-editor', 'unit-access-editor', 'content-visibility-editor', 'settings-modal-tabs', 'timed-examination-preference-editor', 'access-editor', - 'show-correctness-editor' + 'show-correctness-editor', 'highlights-editor' ]); appendSetFixtures(mockOutlinePage); mockCourseJSON = createMockCourseJSON({}, [ @@ -522,6 +529,166 @@ define(['jquery', 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers', 'common/j }); }); + describe('Section Highlights', function() { + var createCourse, createCourseWithHighlights, createCourseWithHighlightsDisabled, mockHighlightValues, + highlightsLink, highlightInputs, openHighlights, saveHighlights, setHighlights, + expectHighlightLinkTextToBe, expectHighlightsToBe, expectServerHandshakeWithHighlights, + expectHighlightsToUpdate, + maxNumHighlights = 5; + + beforeEach(function() { + setSelfPaced(); + }); + + createCourse = function(sectionOptions) { + createCourseOutlinePage(this, + createMockCourseJSON({}, [ + createMockSectionJSON(sectionOptions) + ]) + ); + }; + + createCourseWithHighlights = function(highlights) { + createCourse({highlights: highlights}); + }; + + createCourseWithHighlightsDisabled = function() { + createCourse({highlights_enabled: false}); + }; + + mockHighlightValues = function(numberOfHighlights) { + var highlights = [], + i; + for (i = 0; i < numberOfHighlights; i++) { + highlights.push('Highlight' + (i + 1)); + } + return highlights; + }; + + highlightsLink = function() { + return outlinePage.$('.section-status >> .highlights-button'); + }; + + highlightInputs = function() { + return $('.highlight-input-text'); + }; + + openHighlights = function() { + highlightsLink().click(); + }; + + saveHighlights = function() { + $('.wrapper-modal-window .action-save').click(); + }; + + setHighlights = function(highlights) { + var i; + for (i = 0; i < highlights.length; i++) { + $(highlightInputs()[i]).val(highlights[i]); + } + for (i = highlights.length; i < maxNumHighlights; i++) { + $(highlightInputs()[i]).val(''); + } + }; + + expectHighlightLinkTextToBe = function(expectedValue) { + expect(highlightsLink()).toContainText(expectedValue); + }; + + expectHighlightsToBe = function(expectedHighlights) { + var highlights = highlightInputs(), + i; + + expect(highlights).toHaveLength(maxNumHighlights); + + for (i = 0; i < expectedHighlights.length; i++) { + expect(highlights[i]).toHaveValue(expectedHighlights[i]); + } + for (i = expectedHighlights.length; i < maxNumHighlights; i++) { + expect(highlights[i]).toHaveValue(''); + expect(highlights[i]).toHaveAttr('placeholder', 'A highlight to look forward to this week.'); + } + }; + + expectServerHandshakeWithHighlights = function(highlights) { + // POST to update section + AjaxHelpers.expectJsonRequest(requests, 'POST', '/xblock/mock-section', { + publish: 'republish', + metadata: { + highlights: highlights + } + }); + AjaxHelpers.respondWithJson(requests, {}); + + // GET updated section + AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/outline/mock-section'); + AjaxHelpers.respondWithJson(requests, createMockSectionJSON({highlights: highlights})); + }; + + expectHighlightsToUpdate = function(originalHighlights, updatedHighlights) { + createCourseWithHighlights(originalHighlights); + + openHighlights(); + setHighlights(updatedHighlights); + saveHighlights(); + + expectServerHandshakeWithHighlights(updatedHighlights); + + openHighlights(); + expectHighlightsToBe(updatedHighlights); + }; + + it('does not display a link when highlights is disabled', function() { + createCourseWithHighlightsDisabled(); + expect(highlightsLink()).toHaveLength(0); + }); + + it('displays link when no highlights exist', function() { + createCourseWithHighlights([]); + expectHighlightLinkTextToBe('Enter Section Highlights'); + }); + + it('displays link when highlights exist', function() { + var highlights = mockHighlightValues(2); + createCourseWithHighlights(highlights); + expectHighlightLinkTextToBe('Section Highlights: 2 entered'); + }); + + it('can view when no highlights exist', function() { + createCourseWithHighlights([]); + openHighlights(); + expectHighlightsToBe([]); + }); + + it('can view existing highlights', function() { + var highlights = mockHighlightValues(2); + createCourseWithHighlights(highlights); + openHighlights(); + expectHighlightsToBe(highlights); + }); + + it('can add highlights', function() { + expectHighlightsToUpdate( + mockHighlightValues(0), + mockHighlightValues(1) + ); + }); + + it('can remove highlights', function() { + expectHighlightsToUpdate( + mockHighlightValues(5), + mockHighlightValues(3) + ); + }); + + it('can edit highlights', function() { + var originalHighlights = mockHighlightValues(3), + editedHighlights = originalHighlights; + editedHighlights[2] = 'A New Value'; + expectHighlightsToUpdate(originalHighlights, editedHighlights); + }); + }); + describe('Section', function() { var getDisplayNameWrapper; @@ -530,7 +697,7 @@ define(['jquery', 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers', 'common/j }; it('can be deleted', function() { - var promptSpy = EditHelpers.createPromptSpy(), requestCount; + var promptSpy = EditHelpers.createPromptSpy(); createCourseOutlinePage(this, createMockCourseJSON({}, [ createMockSectionJSON(), createMockSectionJSON({id: 'mock-section-2', display_name: 'Mock Section 2'}) @@ -922,8 +1089,7 @@ define(['jquery', 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers', 'common/j ]) ]); createCourseOutlinePage(this, mockCourseJSON, false); - /* global course */ - course.set('self_paced', true); + setSelfPaced(); outlinePage.$('.outline-subsection .configure-button').click(); expect($('.edit-settings-release').length).toBe(0); expect($('.grading-due-date').length).toBe(0);