Merge branch 'master' of github.com:MITx/mitx into fix/cdodge/export-draft-modules
Conflicts: common/lib/xmodule/xmodule/modulestore/draft.py
This commit is contained in:
@@ -21,8 +21,7 @@ Feature: Advanced (manual) course policy
|
||||
|
||||
Scenario: Test editing key value
|
||||
Given I am on the Advanced Course Settings page in Studio
|
||||
When I edit the value of a policy key
|
||||
And I press the "Save" notification button
|
||||
When I edit the value of a policy key and save
|
||||
Then the policy key value is changed
|
||||
And I reload the page
|
||||
Then the policy key value is changed
|
||||
|
||||
@@ -51,6 +51,11 @@ def edit_the_value_of_a_policy_key(step):
|
||||
e._element.send_keys(Keys.TAB, Keys.END, Keys.ARROW_LEFT, ' ', 'X')
|
||||
|
||||
|
||||
@step(u'I edit the value of a policy key and save$')
|
||||
def edit_the_value_of_a_policy_key(step):
|
||||
change_display_name_value(step, '"foo"')
|
||||
|
||||
|
||||
@step('I create a JSON object as a value$')
|
||||
def create_JSON_object(step):
|
||||
change_display_name_value(step, '{"key": "value", "key_2": "value_2"}')
|
||||
@@ -96,7 +101,7 @@ def the_policy_key_value_is_unchanged(step):
|
||||
|
||||
@step(u'the policy key value is changed$')
|
||||
def the_policy_key_value_is_changed(step):
|
||||
assert_equal(get_display_name_value(), '"Robot Super Course X"')
|
||||
assert_equal(get_display_name_value(), '"foo"')
|
||||
|
||||
|
||||
############# HELPERS ###############
|
||||
|
||||
@@ -18,8 +18,8 @@ COURSE_END_TIME_CSS = "#course-end-time"
|
||||
ENROLLMENT_START_TIME_CSS = "#course-enrollment-start-time"
|
||||
ENROLLMENT_END_TIME_CSS = "#course-enrollment-end-time"
|
||||
|
||||
DUMMY_TIME = "3:30pm"
|
||||
DEFAULT_TIME = "12:00am"
|
||||
DUMMY_TIME = "15:30"
|
||||
DEFAULT_TIME = "00:00"
|
||||
|
||||
|
||||
############### ACTIONS ####################
|
||||
|
||||
@@ -38,7 +38,7 @@ def i_click_the_edit_link_for_the_release_date(step):
|
||||
@step('I save a new section release date$')
|
||||
def i_save_a_new_section_release_date(step):
|
||||
set_date_and_time('input.start-date.date.hasDatepicker', '12/25/2013',
|
||||
'input.start-time.time.ui-timepicker-input', '12:00am')
|
||||
'input.start-time.time.ui-timepicker-input', '00:00')
|
||||
world.browser.click_link_by_text('Save')
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ def the_section_release_date_picker_not_visible(step):
|
||||
def the_section_release_date_is_updated(step):
|
||||
css = 'span.published-status'
|
||||
status_text = world.css_text(css)
|
||||
assert_equal(status_text, 'Will Release: 12/25/2013 at 12:00am')
|
||||
assert_equal(status_text, 'Will Release: 12/25/2013 at 00:00 UTC')
|
||||
|
||||
|
||||
############ HELPER METHODS ###################
|
||||
|
||||
@@ -57,18 +57,18 @@ def i_see_complete_subsection_name_with_quote_in_editor(step):
|
||||
|
||||
@step('I have set a release date and due date in different years$')
|
||||
def test_have_set_dates_in_different_years(step):
|
||||
set_date_and_time('input#start_date', '12/25/2011', 'input#start_time', '3:00am')
|
||||
set_date_and_time('input#start_date', '12/25/2011', 'input#start_time', '03:00')
|
||||
world.css_click('.set-date')
|
||||
# Use a year in the past so that current year will always be different.
|
||||
set_date_and_time('input#due_date', '01/02/2012', 'input#due_time', '4:00am')
|
||||
set_date_and_time('input#due_date', '01/02/2012', 'input#due_time', '04:00')
|
||||
|
||||
|
||||
@step('I see the correct dates$')
|
||||
def i_see_the_correct_dates(step):
|
||||
assert_equal('12/25/2011', world.css_find('input#start_date').first.value)
|
||||
assert_equal('3:00am', world.css_find('input#start_time').first.value)
|
||||
assert_equal('03:00', world.css_find('input#start_time').first.value)
|
||||
assert_equal('01/02/2012', world.css_find('input#due_date').first.value)
|
||||
assert_equal('4:00am', world.css_find('input#due_time').first.value)
|
||||
assert_equal('04:00', world.css_find('input#due_time').first.value)
|
||||
|
||||
|
||||
@step('I mark it as Homework$')
|
||||
|
||||
@@ -93,6 +93,69 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
|
||||
|
||||
return cnt
|
||||
|
||||
def test_draft_metadata(self):
|
||||
'''
|
||||
This verifies a bug we had where inherited metadata was getting written to the
|
||||
module as 'own-metadata' when publishing. Also verifies the metadata inheritance is
|
||||
properly computed
|
||||
'''
|
||||
store = modulestore()
|
||||
draft_store = modulestore('draft')
|
||||
import_from_xml(store, 'common/test/data/', ['simple'])
|
||||
|
||||
course = draft_store.get_item(Location(['i4x', 'edX', 'simple',
|
||||
'course', '2012_Fall', None]), depth=None)
|
||||
html_module = draft_store.get_item(['i4x', 'edX', 'simple', 'html', 'test_html', None])
|
||||
|
||||
self.assertEqual(html_module.lms.graceperiod, course.lms.graceperiod)
|
||||
self.assertNotIn('graceperiod', own_metadata(html_module))
|
||||
|
||||
draft_store.clone_item(html_module.location, html_module.location)
|
||||
|
||||
# refetch to check metadata
|
||||
html_module = draft_store.get_item(['i4x', 'edX', 'simple', 'html', 'test_html', None])
|
||||
|
||||
self.assertEqual(html_module.lms.graceperiod, course.lms.graceperiod)
|
||||
self.assertNotIn('graceperiod', own_metadata(html_module))
|
||||
|
||||
# publish module
|
||||
draft_store.publish(html_module.location, 0)
|
||||
|
||||
# refetch to check metadata
|
||||
html_module = draft_store.get_item(['i4x', 'edX', 'simple', 'html', 'test_html', None])
|
||||
|
||||
self.assertEqual(html_module.lms.graceperiod, course.lms.graceperiod)
|
||||
self.assertNotIn('graceperiod', own_metadata(html_module))
|
||||
|
||||
# put back in draft and change metadata and see if it's now marked as 'own_metadata'
|
||||
draft_store.clone_item(html_module.location, html_module.location)
|
||||
html_module = draft_store.get_item(['i4x', 'edX', 'simple', 'html', 'test_html', None])
|
||||
|
||||
new_graceperiod = timedelta(**{'hours': 1})
|
||||
|
||||
self.assertNotIn('graceperiod', own_metadata(html_module))
|
||||
html_module.lms.graceperiod = new_graceperiod
|
||||
self.assertIn('graceperiod', own_metadata(html_module))
|
||||
self.assertEqual(html_module.lms.graceperiod, new_graceperiod)
|
||||
|
||||
draft_store.update_metadata(html_module.location, own_metadata(html_module))
|
||||
|
||||
# read back to make sure it reads as 'own-metadata'
|
||||
html_module = draft_store.get_item(['i4x', 'edX', 'simple', 'html', 'test_html', None])
|
||||
|
||||
self.assertIn('graceperiod', own_metadata(html_module))
|
||||
self.assertEqual(html_module.lms.graceperiod, new_graceperiod)
|
||||
|
||||
# republish
|
||||
draft_store.publish(html_module.location, 0)
|
||||
|
||||
# and re-read and verify 'own-metadata'
|
||||
draft_store.clone_item(html_module.location, html_module.location)
|
||||
html_module = draft_store.get_item(['i4x', 'edX', 'simple', 'html', 'test_html', None])
|
||||
|
||||
self.assertIn('graceperiod', own_metadata(html_module))
|
||||
self.assertEqual(html_module.lms.graceperiod, new_graceperiod)
|
||||
|
||||
def test_get_depth_with_drafts(self):
|
||||
import_from_xml(modulestore(), 'common/test/data/', ['simple'])
|
||||
|
||||
@@ -609,6 +672,113 @@ class ContentStoreTest(ModuleStoreTestCase):
|
||||
self.assertIn('markdown', context, "markdown is missing from context")
|
||||
self.assertNotIn('markdown', problem.editable_metadata_fields, "Markdown slipped into the editable metadata fields")
|
||||
|
||||
def test_cms_imported_course_walkthrough(self):
|
||||
"""
|
||||
Import and walk through some common URL endpoints. This just verifies non-500 and no other
|
||||
correct behavior, so it is not a deep test
|
||||
"""
|
||||
import_from_xml(modulestore(), 'common/test/data/', ['simple'])
|
||||
loc = Location(['i4x', 'edX', 'simple', 'course', '2012_Fall', None])
|
||||
resp = self.client.get(reverse('course_index',
|
||||
kwargs={'org': loc.org,
|
||||
'course': loc.course,
|
||||
'name': loc.name}))
|
||||
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertContains(resp, 'Chapter 2')
|
||||
|
||||
# go to various pages
|
||||
|
||||
# import page
|
||||
resp = self.client.get(reverse('import_course',
|
||||
kwargs={'org': loc.org,
|
||||
'course': loc.course,
|
||||
'name': loc.name}))
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# export page
|
||||
resp = self.client.get(reverse('export_course',
|
||||
kwargs={'org': loc.org,
|
||||
'course': loc.course,
|
||||
'name': loc.name}))
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# manage users
|
||||
resp = self.client.get(reverse('manage_users',
|
||||
kwargs={'location': loc.url()}))
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# course info
|
||||
resp = self.client.get(reverse('course_info',
|
||||
kwargs={'org': loc.org,
|
||||
'course': loc.course,
|
||||
'name': loc.name}))
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# settings_details
|
||||
resp = self.client.get(reverse('settings_details',
|
||||
kwargs={'org': loc.org,
|
||||
'course': loc.course,
|
||||
'name': loc.name}))
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# settings_details
|
||||
resp = self.client.get(reverse('settings_grading',
|
||||
kwargs={'org': loc.org,
|
||||
'course': loc.course,
|
||||
'name': loc.name}))
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# static_pages
|
||||
resp = self.client.get(reverse('static_pages',
|
||||
kwargs={'org': loc.org,
|
||||
'course': loc.course,
|
||||
'coursename': loc.name}))
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# static_pages
|
||||
resp = self.client.get(reverse('asset_index',
|
||||
kwargs={'org': loc.org,
|
||||
'course': loc.course,
|
||||
'name': loc.name}))
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# go look at a subsection page
|
||||
subsection_location = loc._replace(category='sequential', name='test_sequence')
|
||||
resp = self.client.get(reverse('edit_subsection',
|
||||
kwargs={'location': subsection_location.url()}))
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# go look at the Edit page
|
||||
unit_location = loc._replace(category='vertical', name='test_vertical')
|
||||
resp = self.client.get(reverse('edit_unit',
|
||||
kwargs={'location': unit_location.url()}))
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# delete a component
|
||||
del_loc = loc._replace(category='html', name='test_html')
|
||||
resp = self.client.post(reverse('delete_item'),
|
||||
json.dumps({'id': del_loc.url()}), "application/json")
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# delete a unit
|
||||
del_loc = loc._replace(category='vertical', name='test_vertical')
|
||||
resp = self.client.post(reverse('delete_item'),
|
||||
json.dumps({'id': del_loc.url()}), "application/json")
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# delete a unit
|
||||
del_loc = loc._replace(category='sequential', name='test_sequence')
|
||||
resp = self.client.post(reverse('delete_item'),
|
||||
json.dumps({'id': del_loc.url()}), "application/json")
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# delete a chapter
|
||||
del_loc = loc._replace(category='chapter', name='chapter_2')
|
||||
resp = self.client.post(reverse('delete_item'),
|
||||
json.dumps({'id': del_loc.url()}), "application/json")
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
def test_import_metadata_with_attempts_empty_string(self):
|
||||
import_from_xml(modulestore(), 'common/test/data/', ['simple'])
|
||||
module_store = modulestore('direct')
|
||||
|
||||
Reference in New Issue
Block a user