Commit 0c5b511c by cahrens

Include tail from header tag in course update.

Fixes bug STUD-590.
parent b0689a4e
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):
......
......@@ -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 <strong>middle</strong> after"
Then I should see the update "before <strong>middle</strong> after"
And when I reload the page
Then I should see the update "before <strong>middle</strong> 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
......
......@@ -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 = '<iframe width="560" height="315" src="http://www.youtube.com/embed/RocY-Jd93XU" frameborder="0">'
content = init_content + '</iframe>'
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 = '<ol/>'
payload = {'content': content,
'date': 'January 11, 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 11, 2013')
self.assertHTMLEqual(content, payload['content'], "self closing ol")
url = reverse('course_info_json',
......@@ -75,6 +72,11 @@ class CourseUpdateTest(CourseTestCase):
"application/json"),
'Failed to save', status_code=400)
# test an update with text in the tail of the header
content = 'outside <strong>inside</strong> after'
payload = get_response(content, 'June 22, 2000')
self.assertHTMLEqual(content, payload['content'], "text outside tag")
# now try to update a non-existent update
url = reverse('course_info_json',
kwargs={'org': self.course.location.org,
......@@ -101,33 +103,18 @@ class CourseUpdateTest(CourseTestCase):
# set to valid html which would break an xml parser
content = "<p><br><br></p>"
payload = {'content': content,
'date': 'January 11, 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)
self.assertHTMLEqual(content, json.loads(resp.content)['content'])
payload = get_response(content, 'January 11, 2013')
self.assertHTMLEqual(content, payload['content'])
# now try to delete a non-existent update
url = reverse('course_info_json', kwargs={'org': self.course.location.org,
'course': self.course.location.course,
'provided_id': '19'})
payload = {'content': content,
'date': 'January 21, 2013'}
self.assertContains(self.client.delete(url), "delete", status_code=400)
# now delete a real update
content = 'blah blah'
payload = {'content': content,
'date': 'January 28, 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 28, 2013')
this_id = payload['id']
self.assertHTMLEqual(content, payload['content'], "single iframe")
# first count the entries
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment