diff --git a/cms/djangoapps/contentstore/course_info_model.py b/cms/djangoapps/contentstore/course_info_model.py index 7ea09333ed..b7611969c1 100644 --- a/cms/djangoapps/contentstore/course_info_model.py +++ b/cms/djangoapps/contentstore/course_info_model.py @@ -1,5 +1,4 @@ from xmodule.modulestore.exceptions import ItemNotFoundError -from xmodule.modulestore import Location from xmodule.modulestore.django import modulestore from lxml import html, etree import re @@ -39,18 +38,12 @@ def get_course_updates(location): if course_html_parsed.tag == 'ol': # 0 is the newest for idx, update in enumerate(course_html_parsed): - if (len(update) == 0): - continue - elif (len(update) == 1): - # could enforce that update[0].tag == 'h2' - content = update[0].tail - else: - content = "\n".join([html.tostring(ele) for ele in update[1:]]) - - # make the id on the client be 1..len w/ 1 being the oldest and len being the newest - course_upd_collection.append({"id": location_base + "/" + str(len(course_html_parsed) - idx), - "date": update.findtext("h2"), - "content": content}) + if len(update) > 0: + content = _course_info_content(update) + # make the id on the client be 1..len w/ 1 being the oldest and len being the newest + course_upd_collection.append({"id": location_base + "/" + str(len(course_html_parsed) - idx), + "date": update.findtext("h2"), + "content": content}) return course_upd_collection @@ -104,14 +97,22 @@ def update_course_updates(location, update, passed_id=None): course_updates.data = html.tostring(course_html_parsed) modulestore('direct').update_item(location, course_updates.data) - if (len(new_html_parsed) == 1): - content = new_html_parsed[0].tail - else: - content = "\n".join([html.tostring(ele) for ele in new_html_parsed[1:]]) - return {"id": passed_id, "date": update['date'], - "content": content} + "content": _course_info_content(new_html_parsed)} + + +def _course_info_content(html_parsed): + """ + Constructs the HTML for the course info update, not including the header. + """ + if len(html_parsed) == 1: + # could enforce that update[0].tag == 'h2' + content = html_parsed[0].tail + else: + content = html_parsed[0].tail if html_parsed[0].tail is not None else "" + content += "\n".join([html.tostring(ele) for ele in html_parsed[1:]]) + return content def delete_course_update(location, update, passed_id): diff --git a/cms/djangoapps/contentstore/features/course-updates.feature b/cms/djangoapps/contentstore/features/course-updates.feature index 15257bd911..6f24fba68c 100644 --- a/cms/djangoapps/contentstore/features/course-updates.feature +++ b/cms/djangoapps/contentstore/features/course-updates.feature @@ -47,6 +47,14 @@ Feature: CMS.Course updates Then I see the handout "Test" And I see a "saving" notification + Scenario: Text outside of tags is preserved + Given I have opened a new course in Studio + And I go to the course updates page + When I add a new update with the text "before middle after" + Then I should see the update "before middle after" + And when I reload the page + Then I should see the update "before middle after" + Scenario: Static links are rewritten when previewing a course update Given I have opened a new course in Studio And I go to the course updates page diff --git a/cms/djangoapps/contentstore/tests/test_course_updates.py b/cms/djangoapps/contentstore/tests/test_course_updates.py index c121b1bc09..c47cdb9ef7 100644 --- a/cms/djangoapps/contentstore/tests/test_course_updates.py +++ b/cms/djangoapps/contentstore/tests/test_course_updates.py @@ -9,6 +9,23 @@ class CourseUpdateTest(CourseTestCase): '''The do all and end all of unit test cases.''' def test_course_update(self): '''Go through each interface and ensure it works.''' + def get_response(content, date): + """ + Helper method for making call to server and returning response. + + Does not supply a provided_id. + """ + payload = {'content': content, + 'date': date} + url = reverse('course_info_json', + kwargs={'org': self.course.location.org, + 'course': self.course.location.course, + 'provided_id': ''}) + + resp = self.client.post(url, json.dumps(payload), "application/json") + + return json.loads(resp.content) + # first get the update to force the creation url = reverse('course_info', kwargs={'org': self.course.location.org, @@ -18,17 +35,7 @@ class CourseUpdateTest(CourseTestCase): init_content = '' - payload = {'content': content, - 'date': 'January 8, 2013'} - url = reverse('course_info_json', - kwargs={'org': self.course.location.org, - 'course': self.course.location.course, - 'provided_id': ''}) - - resp = self.client.post(url, json.dumps(payload), "application/json") - - payload = json.loads(resp.content) - + payload = get_response(content, 'January 8, 2013') self.assertHTMLEqual(payload['content'], content) first_update_url = reverse('course_info_json', @@ -48,17 +55,7 @@ class CourseUpdateTest(CourseTestCase): # now put in an evil update content = '