From b2a17b35b0f1de8f6da4336cc043c0c568791116 Mon Sep 17 00:00:00 2001 From: "E. Kolpakov" Date: Tue, 30 Dec 2014 11:12:10 +0300 Subject: [PATCH] Validation warning if library content XBlock configured to fetch more problems than libraries and filtering allow --- .../xmodule/xmodule/library_content_module.py | 30 +++++++++++++++---- .../studio/test_studio_library_container.py | 27 +++++++++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/common/lib/xmodule/xmodule/library_content_module.py b/common/lib/xmodule/xmodule/library_content_module.py index fcbef1fc00..b8058e8e7f 100644 --- a/common/lib/xmodule/xmodule/library_content_module.py +++ b/common/lib/xmodule/xmodule/library_content_module.py @@ -388,6 +388,11 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe return False return True + def _set_validation_error_if_empty(self, validation, summary): + """ Helper method to only set validation summary if it's empty """ + if validation.empty: + validation.set_summary(summary) + def validate(self): """ Validates the state of this Library Content Module Instance. This @@ -408,19 +413,20 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe ) return validation lib_tools = self.runtime.service(self, 'library_tools') - has_children_matching_filter = False + matching_children_count = 0 for library_key, version in self.source_libraries: if not self._validate_library_version(validation, lib_tools, version, library_key): break library = lib_tools.get_library(library_key) children_matching_filter = lib_tools.get_filtered_children(library, self.capa_type) - # get_filtered_children returns generator, so we're basically checking if there are at least one child - # that satisfy filtering. Children are never equal to None, so None is returned only if generator was empty - has_children_matching_filter |= next(children_matching_filter, None) is not None + # get_filtered_children returns generator, so can't use len. + # And we don't actually need those children, so no point of constructing a list + matching_children_count += sum(1 for child in children_matching_filter) - if not has_children_matching_filter and validation.empty: - validation.set_summary( + if matching_children_count == 0: + self._set_validation_error_if_empty( + validation, StudioValidationMessage( StudioValidationMessage.WARNING, _(u'There are no content matching configured filters in the selected libraries.'), @@ -429,6 +435,18 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe ) ) + if matching_children_count < self.max_count: + self._set_validation_error_if_empty( + validation, + StudioValidationMessage( + StudioValidationMessage.WARNING, + _(u'Configured to fetch {count} blocks, library and filter settings yield only {actual} blocks.') + .format(actual=matching_children_count, count=self.max_count), + action_class='edit-button', + action_label=_(u"Edit block configuration") + ) + ) + return validation def editor_saved(self, user, old_metadata, old_content): diff --git a/common/test/acceptance/tests/studio/test_studio_library_container.py b/common/test/acceptance/tests/studio/test_studio_library_container.py index 747db98752..4634fb09ac 100644 --- a/common/test/acceptance/tests/studio/test_studio_library_container.py +++ b/common/test/acceptance/tests/studio/test_studio_library_container.py @@ -186,6 +186,8 @@ class StudioLibraryContainerTest(StudioLibraryTest, UniqueCourseTest): When I go to studio unit page for library content block And I set Problem Type selector so that no libraries have matching content Then I can see that "No matching content" warning is shown + When I set Problem Type selector so that there are matching content + Then I can see that warning messages are not shown """ expected_text = 'There are no content matching configured filters in the selected libraries. ' \ 'Edit Problem Type Filter' @@ -213,3 +215,28 @@ class StudioLibraryContainerTest(StudioLibraryTest, UniqueCourseTest): # Library should contain single Dropdown problem, so now there should be no errors again self.assertFalse(library_container.has_validation_error) self.assertFalse(library_container.has_validation_warning) + + def test_not_enough_children_blocks(self): + """ + 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 + And I set Problem Type selector so "Any" + Then I can see that "No matching content" warning is shown + """ + expected_tpl = "Configured to fetch {count} blocks, library and filter settings yield only {actual} blocks." + + library_container = self._get_library_xblock_wrapper(self.unit_page.xblocks[0]) + + # precondition check - assert block is configured fine + self.assertFalse(library_container.has_validation_error) + self.assertFalse(library_container.has_validation_warning) + + edit_modal = StudioLibraryContentXBlockEditModal(library_container.edit()) + edit_modal.count = 50 + library_container.save_settings() + + self.assertTrue(library_container.has_validation_warning) + self.assertIn( + expected_tpl.format(count=50, actual=len(self.library_fixture.children)), + library_container.validation_warning_text + )