diff --git a/cms/djangoapps/contentstore/tests/utils.py b/cms/djangoapps/contentstore/tests/utils.py index e4b19c1771..0682560f70 100644 --- a/cms/djangoapps/contentstore/tests/utils.py +++ b/cms/djangoapps/contentstore/tests/utils.py @@ -308,7 +308,7 @@ class CourseTestCase(ModuleStoreTestCase): # assert is here to make sure that the course being tested actually has verticals (units) to check. self.assertGreater(len(items), 0, "Course has no verticals (units) to check") for descriptor in items: - resp = self.client.get_html(get_url('unit_handler', descriptor.location)) + resp = self.client.get_html(get_url('container_handler', descriptor.location)) self.assertEqual(resp.status_code, 200) def assertAssetsEqual(self, asset_son, course1_id, course2_id): diff --git a/cms/djangoapps/contentstore/views/item.py b/cms/djangoapps/contentstore/views/item.py index 94ac3fcbef..51bfd23214 100644 --- a/cms/djangoapps/contentstore/views/item.py +++ b/cms/djangoapps/contentstore/views/item.py @@ -543,6 +543,23 @@ def create_xblock_info(usage_key, xblock, data=None, metadata=None): """ publish_state = compute_publish_state(xblock) if xblock else None + def safe_get_username(user_id): + """ + Guard against bad user_ids, like the infamous "**replace_user**". + Note that this will ignore our special known IDs (ModuleStoreEnum.UserID). + We should consider adding special handling for those values. + + :param user_id: the user id to get the username of + :return: username, or None if the user does not exist or user_id is None + """ + if user_id: + try: + return User.objects.get(id=user_id).username + except: # pylint: disable=bare-except + pass + + return None + xblock_info = { "id": unicode(xblock.location), "display_name": xblock.display_name_with_default, @@ -550,7 +567,7 @@ def create_xblock_info(usage_key, xblock, data=None, metadata=None): "has_changes": modulestore().has_changes(usage_key), "published": publish_state in (PublishState.public, PublishState.draft), "edited_on": get_default_time_display(xblock.edited_on) if xblock.edited_on else None, - "edited_by": User.objects.get(id=xblock.edited_by).username if xblock.edited_by else None + "edited_by": safe_get_username(xblock.edited_by) } if data is not None: xblock_info["data"] = data diff --git a/cms/djangoapps/contentstore/views/tests/test_container_page.py b/cms/djangoapps/contentstore/views/tests/test_container_page.py index c7768d57b2..81a272061d 100644 --- a/cms/djangoapps/contentstore/views/tests/test_container_page.py +++ b/cms/djangoapps/contentstore/views/tests/test_container_page.py @@ -29,18 +29,18 @@ class ContainerPageTestCase(StudioPageTestCase): past = datetime.datetime(1970, 1, 1, tzinfo=UTC) future = datetime.datetime.now(UTC) + datetime.timedelta(days=1) - self.released_private_vertical = ItemFactory.create( + self.released_private_vertical = self._create_item( parent_location=self.sequential.location, category='vertical', display_name='Released Private Unit', - user_id=self.user.id, start=past) - self.unreleased_private_vertical = ItemFactory.create( + start=past) + self.unreleased_private_vertical = self._create_item( parent_location=self.sequential.location, category='vertical', display_name='Unreleased Private Unit', - user_id=self.user.id, start=future) - self.released_public_vertical = ItemFactory.create( + start=future) + self.released_public_vertical = self._create_item( parent_location=self.sequential.location, category='vertical', display_name='Released Public Unit', - user_id=self.user.id, start=past) - self.unreleased_public_vertical = ItemFactory.create( + start=past) + self.unreleased_public_vertical = self._create_item( parent_location=self.sequential.location, category='vertical', display_name='Unreleased Public Unit', - user_id=self.user.id, start=future) + start=future) self.store.publish(self.unreleased_public_vertical.location, self.user.id) self.store.publish(self.released_public_vertical.location, self.user.id) @@ -124,6 +124,19 @@ class ContainerPageTestCase(StudioPageTestCase): self.validate_preview_html(self.child_container, self.container_view) self.validate_preview_html(self.child_vertical, self.reorderable_child_view) + def _create_item(self, parent_location, category, display_name, **kwargs): + """ + creates an item in the module store, without publishing it. + """ + return ItemFactory.create( + parent_location=parent_location, + category=category, + display_name=display_name, + publish_item=False, + user_id=self.user.id, + **kwargs + ) + def test_public_child_container_preview_html(self): """ Verify that a public container rendered as a child of the container page returns the expected HTML. diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py index a07f381bea..36ed33a2c5 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py @@ -538,7 +538,9 @@ class TestMixedModuleStore(unittest.TestCase): Tests already exist for both split and draft in their own test files. """ self.initdb(default_ms) - item = self.store.create_item(self.course_locations[self.MONGO_COURSEID], 'problem', block_id='orphan') + item = self.store.create_item( + self.course_locations[self.MONGO_COURSEID], 'problem', self.user_id, block_id='orphan' + ) self.assertTrue(self.store.has_changes(item.location)) self.store.publish(item.location, self.user_id) self.assertFalse(self.store.has_changes(item.location)) diff --git a/common/test/acceptance/pages/studio/container.py b/common/test/acceptance/pages/studio/container.py index 5d966cfac6..df0d25a859 100644 --- a/common/test/acceptance/pages/studio/container.py +++ b/common/test/acceptance/pages/studio/container.py @@ -215,6 +215,10 @@ class XBlockWrapper(PageObject): url = None BODY_SELECTOR = '.studio-xblock-wrapper' NAME_SELECTOR = '.xblock-display-name' + COMPONENT_BUTTONS = { + 'advanced_tab': '.editor-tabs li.inner_tab_wrap:nth-child(2) > a', + 'save_settings': '.action-save', + } def __init__(self, browser, locator): super(XBlockWrapper, self).__init__(browser) @@ -274,10 +278,33 @@ class XBlockWrapper(PageObject): """ return _click_edit(self, self._bounded_selector) + def open_advanced_tab(self): + """ + Click on Advanced Tab. + """ + self._click_button('advanced_tab') + + def save_settings(self): + """ + Click on settings Save button. + """ + self._click_button('save_settings') + @property def editor_selector(self): return '.xblock-studio_view' + def _click_button(self, button_name): + """ + Click on a button as specified by `button_name` + + Arguments: + button_name (str): button name + + """ + self.q(css=self.COMPONENT_BUTTONS[button_name]).first.click() + self.wait_for_ajax() + def _click_edit(page_object, bounded_selector=lambda(x): x): """ diff --git a/common/test/acceptance/tests/video/test_studio_video_module.py b/common/test/acceptance/tests/video/test_studio_video_module.py index 1ba3eed446..1988f17253 100644 --- a/common/test/acceptance/tests/video/test_studio_video_module.py +++ b/common/test/acceptance/tests/video/test_studio_video_module.py @@ -93,25 +93,19 @@ class CMSVideoBaseTest(UniqueCourseTest): def edit_component(self): """ - Make component editable and open components Edit Dialog. - - Arguments: - handout_filename (str): handout file name to be uploaded - save_settings (bool): save settings or not - + Open component Edit Dialog for first component on page. """ - self.unit_page.set_unit_visibility('private') - self.unit_page.components[0].edit() + self.unit_page.xblocks[0].edit() def open_advanced_tab(self): """ Open components advanced tab. """ - self.unit_page.components[0].open_advanced_tab() + self.unit_page.xblocks[0].open_advanced_tab() def save_unit_settings(self): """ Save component settings. """ - self.unit_page.components[0].save_settings() + self.unit_page.xblocks[0].save_settings()