Commit 76b6d33b by Braden MacDonald Committed by E. Kolpakov

Refresh children automatically when library setting is changed

parent 904007a9
...@@ -363,7 +363,7 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe ...@@ -363,7 +363,7 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe
js_module_name = "VerticalDescriptor" js_module_name = "VerticalDescriptor"
@XBlock.handler @XBlock.handler
def refresh_children(self, request, suffix): # pylint: disable=unused-argument def refresh_children(self, request, suffix, update_db=True): # pylint: disable=unused-argument
""" """
Refresh children: Refresh children:
This method is to be used when any of the libraries that this block This method is to be used when any of the libraries that this block
...@@ -375,8 +375,12 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe ...@@ -375,8 +375,12 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe
This method will update this block's 'source_libraries' field to store This method will update this block's 'source_libraries' field to store
the version number of the libraries used, so we easily determine if the version number of the libraries used, so we easily determine if
this block is up to date or not. this block is up to date or not.
If update_db is True (default), this will explicitly persist the changes
to the modulestore by calling update_item()
""" """
user_id = self.runtime.service(self, 'user').user_id user_service = self.runtime.service(self, 'user')
user_id = user_service.user_id if user_service else None # May be None when creating bok choy test fixtures
root_children = [] root_children = []
store = self.system.modulestore store = self.system.modulestore
...@@ -395,6 +399,8 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe ...@@ -395,6 +399,8 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe
new_libraries = [] new_libraries = []
for library_key, old_version in self.source_libraries: # pylint: disable=unused-variable for library_key, old_version in self.source_libraries: # pylint: disable=unused-variable
library = _get_library(self.system.modulestore, library_key) # pylint: disable=protected-access library = _get_library(self.system.modulestore, library_key) # pylint: disable=protected-access
if library is None:
raise ValueError("Required library not found.")
def copy_children_recursively(from_block): def copy_children_recursively(from_block):
""" """
...@@ -434,9 +440,21 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe ...@@ -434,9 +440,21 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe
new_libraries.append(LibraryVersionReference(library_key, library.location.library_key.version_guid)) new_libraries.append(LibraryVersionReference(library_key, library.location.library_key.version_guid))
self.source_libraries = new_libraries self.source_libraries = new_libraries
self.children = root_children # pylint: disable=attribute-defined-outside-init self.children = root_children # pylint: disable=attribute-defined-outside-init
self.system.modulestore.update_item(self, user_id) if update_db:
self.system.modulestore.update_item(self, user_id)
return Response() return Response()
def editor_saved(self, user, old_metadata, old_content):
"""
If source_libraries has been edited, refresh_children automatically.
"""
old_source_libraries = LibraryList().from_json(old_metadata.get('source_libraries', []))
if set(old_source_libraries) != set(self.source_libraries):
try:
self.refresh_children(None, None, update_db=False) # update_db=False since update_item() is about to be called anyways
except ValueError:
pass # The validation area will display an error message, no need to do anything now.
def has_dynamic_children(self): def has_dynamic_children(self):
""" """
Inform the runtime that our children vary per-user. Inform the runtime that our children vary per-user.
......
...@@ -313,6 +313,14 @@ class XBlockWrapper(PageObject): ...@@ -313,6 +313,14 @@ class XBlockWrapper(PageObject):
return self.q(css=self._bounded_selector('.xblock-student_view'))[0].text return self.q(css=self._bounded_selector('.xblock-student_view'))[0].text
@property @property
def author_content(self):
"""
Returns the text content of the xblock as displayed on the container page.
(For blocks which implement a distinct author_view).
"""
return self.q(css=self._bounded_selector('.xblock-author_view'))[0].text
@property
def name(self): def name(self):
titles = self.q(css=self._bounded_selector(self.NAME_SELECTOR)).text titles = self.q(css=self._bounded_selector(self.NAME_SELECTOR)).text
if titles: if titles:
......
...@@ -92,7 +92,6 @@ class LibraryContentTest(UniqueCourseTest): ...@@ -92,7 +92,6 @@ class LibraryContentTest(UniqueCourseTest):
modal = StudioLibraryContentXBlockEditModal(library_container_block.edit()) modal = StudioLibraryContentXBlockEditModal(library_container_block.edit())
modal.count = count modal.count = count
library_container_block.save_settings() library_container_block.save_settings()
library_container_block.refresh_children()
self._go_to_unit_page(change_login=False) self._go_to_unit_page(change_login=False)
unit_page.wait_for_page() unit_page.wait_for_page()
unit_page.publish_action.click() unit_page.publish_action.click()
......
...@@ -136,19 +136,29 @@ class StudioLibraryContainerTest(ContainerBase, StudioLibraryTest): ...@@ -136,19 +136,29 @@ class StudioLibraryContainerTest(ContainerBase, StudioLibraryTest):
""" """
Scenario: Given I have a library, a course and library content xblock in a course Scenario: Given I have a library, a course and library content xblock in a course
When I go to studio unit page for library content block When I go to studio unit page for library content block
Then I update the library being used
Then I refresh the page
Then I can see that library content block needs to be updated Then I can see that library content block needs to be updated
When I click on the update link When I click on the update link
Then I can see that the content no longer needs to be updated Then I can see that the content no longer needs to be updated
""" """
expected_text = "This component is out of date. The library has new content." expected_text = "This component is out of date. The library has new content."
library_container = self._get_library_xblock_wrapper(self.unit_page.xblocks[0]) library_block = self._get_library_xblock_wrapper(self.unit_page.xblocks[0])
self.assertFalse(library_block.has_validation_warning)
self.assertIn("3 matching components", library_block.author_content)
self.library_fixture.create_xblock(self.library_fixture.library_location, XBlockFixtureDesc("html", "Html4"))
self.assertTrue(library_container.has_validation_warning) self.unit_page.visit() # Reload the page
self.assertIn(expected_text, library_container.validation_warning_text)
library_container.refresh_children() self.assertTrue(library_block.has_validation_warning)
self.assertIn(expected_text, library_block.validation_warning_text)
library_block.refresh_children()
self.unit_page.wait_for_page() # Wait for the page to reload self.unit_page.wait_for_page() # Wait for the page to reload
library_container = self._get_library_xblock_wrapper(self.unit_page.xblocks[0]) library_block = self._get_library_xblock_wrapper(self.unit_page.xblocks[0])
self.assertFalse(library_container.has_validation_message) self.assertFalse(library_block.has_validation_message)
self.assertIn("4 matching components", library_block.author_content)
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