def validate_split_test(self): """ Returns a StudioValidation object describing the current state of the split_test_module (not including superclass validation messages). """ _ = self.runtime.service(self, "i18n").ugettext # pylint: disable=redefined-outer-name split_validation = StudioValidation(self.location) if self.user_partition_id < 0: split_validation.add( StudioValidationMessage( StudioValidationMessage.NOT_CONFIGURED, _(u"The experiment is not associated with a group configuration."), action_class='edit-button', action_label=_(u"Select a Group Configuration") ) ) else: user_partition = self.get_selected_partition() if not user_partition: split_validation.add( StudioValidationMessage( StudioValidationMessage.ERROR, _(u"The experiment uses a deleted group configuration. Select a valid group configuration or delete this experiment.") ) ) else: # If the user_partition selected is not valid for the split_test module, error. # This can only happen via XML and import/export. if not get_split_user_partitions([user_partition]): split_validation.add( StudioValidationMessage( StudioValidationMessage.ERROR, _(u"The experiment uses a group configuration that is not supported for experiments. " u"Select a valid group configuration or delete this experiment.") ) ) else: [active_children, inactive_children] = self.active_and_inactive_children() if len(active_children) < len(user_partition.groups): split_validation.add( StudioValidationMessage( StudioValidationMessage.ERROR, _(u"The experiment does not contain all of the groups in the configuration."), action_runtime_event='add-missing-groups', action_label=_(u"Add Missing Groups") ) ) if len(inactive_children) > 0: split_validation.add( StudioValidationMessage( StudioValidationMessage.WARNING, _(u"The experiment has an inactive group. " u"Move content into active groups, then delete the inactive group.") ) ) return split_validation
def validate_split_test(self): """ Returns a StudioValidation object describing the current state of the split_test_module (not including superclass validation messages). """ _ = self.runtime.service(self, "i18n").ugettext # pylint: disable=redefined-outer-name split_validation = StudioValidation(self.location) if self.user_partition_id < 0: split_validation.add( StudioValidationMessage( StudioValidationMessage.NOT_CONFIGURED, _(u"The experiment is not associated with a group configuration." ), action_class='edit-button', action_label=_(u"Select a Group Configuration"))) else: user_partition = self.get_selected_partition() if not user_partition: split_validation.add( StudioValidationMessage( StudioValidationMessage.ERROR, _(u"The experiment uses a deleted group configuration. Select a valid group configuration or delete this experiment." ))) else: # If the user_partition selected is not valid for the split_test module, error. # This can only happen via XML and import/export. if not get_split_user_partitions([user_partition]): split_validation.add( StudioValidationMessage( StudioValidationMessage.ERROR, _(u"The experiment uses a group configuration that is not supported for experiments. " u"Select a valid group configuration or delete this experiment." ))) else: [active_children, inactive_children] = self.active_and_inactive_children() if len(active_children) < len(user_partition.groups): split_validation.add( StudioValidationMessage( StudioValidationMessage.ERROR, _(u"The experiment does not contain all of the groups in the configuration." ), action_runtime_event='add-missing-groups', action_label=_(u"Add Missing Groups"))) if len(inactive_children) > 0: split_validation.add( StudioValidationMessage( StudioValidationMessage.WARNING, _(u"The experiment has an inactive group. " u"Move content into active groups, then delete the inactive group." ))) return split_validation
def verify_validation_add_usage_info(self, expected_result, mocked_message, mocked_validation_messages): """ Helper method for testing validation information present after add_usage_info. """ self._add_user_partitions() split_test = self._create_content_experiment(cid=0, name_suffix='0')[1] validation = StudioValidation(split_test.location) validation.add(mocked_message) mocked_validation_messages.return_value = validation group_configuration = GroupConfiguration.get_split_test_partitions_with_usage(self.store, self.course)[0] self.assertEqual(expected_result.to_json(), group_configuration['usage'][0]['validation'])
def verify_validation_add_usage_info(self, expected_result, mocked_message, mocked_validation_messages): """ Helper method for testing validation information present after add_usage_info. """ self._add_user_partitions() split_test = self._create_content_experiment(cid=0, name_suffix='0')[1] validation = StudioValidation(split_test.location) validation.add(mocked_message) mocked_validation_messages.return_value = validation group_configuration = GroupConfiguration.add_usage_info(self.course, self.store)[0] self.assertEqual(expected_result.to_json(), group_configuration['usage'][0]['validation'])
def validate(self): validation = super(ConditionalDescriptor, self).validate() if not self.sources_list: conditional_validation = StudioValidation(self.location) conditional_validation.add( StudioValidationMessage( StudioValidationMessage.NOT_CONFIGURED, _(u"This component has no source components configured yet." ), action_class='edit-button', action_label=_(u"Configure list of sources"))) validation = StudioValidation.copy(validation) validation.summary = conditional_validation.messages[0] return validation
def test_to_json(self): """ Test the ability to serialize a `StudioValidation` instance. """ validation = StudioValidation("id") expected = {"xblock_id": "id", "messages": [], "empty": True} self.assertEqual(expected, validation.to_json()) validation.add( StudioValidationMessage(StudioValidationMessage.ERROR, u"Error message", action_label=u"Action label", action_class="edit-button")) validation.add( StudioValidationMessage(StudioValidationMessage.NOT_CONFIGURED, u"Not configured message", action_label=u"Action label", action_runtime_event="make groups")) validation.set_summary( StudioValidationMessage(StudioValidationMessage.WARNING, u"Summary message", action_label=u"Summary label", action_runtime_event="fix everything")) # Note: it is important to test all the expected strings here because the client-side model depends on them # (for instance, "warning" vs. using the xblock constant ValidationMessageTypes.WARNING). expected = { "xblock_id": "id", "messages": [{ "type": "error", "text": u"Error message", "action_label": u"Action label", "action_class": "edit-button" }, { "type": "not-configured", "text": u"Not configured message", "action_label": u"Action label", "action_runtime_event": "make groups" }], "summary": { "type": "warning", "text": u"Summary message", "action_label": u"Summary label", "action_runtime_event": "fix everything" }, "empty": False } self.assertEqual(expected, validation.to_json())
def test_to_json(self): """ Test the ability to serialize a `StudioValidation` instance. """ validation = StudioValidation("id") expected = { "xblock_id": "id", "messages": [], "empty": True } self.assertEqual(expected, validation.to_json()) validation.add( StudioValidationMessage( StudioValidationMessage.ERROR, u"Error message", action_label=u"Action label", action_class="edit-button" ) ) validation.add( StudioValidationMessage( StudioValidationMessage.NOT_CONFIGURED, u"Not configured message", action_label=u"Action label", action_runtime_event="make groups" ) ) validation.set_summary( StudioValidationMessage( StudioValidationMessage.WARNING, u"Summary message", action_label=u"Summary label", action_runtime_event="fix everything" ) ) # Note: it is important to test all the expected strings here because the client-side model depends on them # (for instance, "warning" vs. using the xblock constant ValidationMessageTypes.WARNING). expected = { "xblock_id": "id", "messages": [ {"type": "error", "text": u"Error message", "action_label": u"Action label", "action_class": "edit-button"}, {"type": "not-configured", "text": u"Not configured message", "action_label": u"Action label", "action_runtime_event": "make groups"} ], "summary": {"type": "warning", "text": u"Summary message", "action_label": u"Summary label", "action_runtime_event": "fix everything"}, "empty": False } self.assertEqual(expected, validation.to_json())
def test_copy_studio_validation(self): validation = StudioValidation("id") validation.add( StudioValidationMessage(StudioValidationMessage.WARNING, u"Warning message", action_label=u"Action Label") ) validation_copy = StudioValidation.copy(validation) self.assertFalse(validation_copy) self.assertEqual(1, len(validation_copy.messages)) expected = { "type": StudioValidationMessage.WARNING, "text": u"Warning message", "action_label": u"Action Label" } self.assertEqual(expected, validation_copy.messages[0].to_json())
def validate(self): validation = super(ConditionalDescriptor, self).validate() if not self.sources_list: conditional_validation = StudioValidation(self.location) conditional_validation.add( StudioValidationMessage( StudioValidationMessage.NOT_CONFIGURED, _(u"This component has no source components configured yet."), action_class='edit-button', action_label=_(u"Configure list of sources") ) ) validation = StudioValidation.copy(validation) validation.summary = conditional_validation.messages[0] return validation
def validate(self): validation = super(ConditionalBlock, self).validate() # lint-amnesty, pylint: disable=super-with-arguments if not self.sources_list: conditional_validation = StudioValidation(self.location) conditional_validation.add( StudioValidationMessage( StudioValidationMessage.NOT_CONFIGURED, _(u"This component has no source components configured yet."), action_class='edit-button', action_label=_(u"Configure list of sources") ) ) validation = StudioValidation.copy(validation) validation.summary = conditional_validation.messages[0] return validation
def test_copy_studio_validation(self): validation = StudioValidation("id") validation.add( StudioValidationMessage(StudioValidationMessage.WARNING, "Warning message", action_label="Action Label")) validation_copy = StudioValidation.copy(validation) assert not validation_copy assert 1 == len(validation_copy.messages) expected = { "type": StudioValidationMessage.WARNING, "text": "Warning message", "action_label": "Action Label" } assert expected == validation_copy.messages[0].to_json()
def test_empty(self): """ Test that `empty` return True iff there are no messages and no summary. Also test the "bool" property of `Validation`. """ validation = StudioValidation("id") self.assertTrue(validation.empty) self.assertTrue(validation) validation.add(StudioValidationMessage(StudioValidationMessage.ERROR, u"Error message")) self.assertFalse(validation.empty) self.assertFalse(validation) validation_with_summary = StudioValidation("id") validation_with_summary.set_summary( StudioValidationMessage(StudioValidationMessage.NOT_CONFIGURED, u"Summary message") ) self.assertFalse(validation.empty) self.assertFalse(validation)
def test_add_messages(self): """ Test the behavior of calling `add_messages` with combination of `StudioValidation` instances. """ validation_1 = StudioValidation("id") validation_1.set_summary(StudioValidationMessage(StudioValidationMessage.WARNING, u"Summary message")) validation_1.add(StudioValidationMessage(StudioValidationMessage.ERROR, u"Error message")) validation_2 = StudioValidation("id") validation_2.set_summary(StudioValidationMessage(StudioValidationMessage.ERROR, u"Summary 2 message")) validation_2.add(StudioValidationMessage(StudioValidationMessage.NOT_CONFIGURED, u"Not configured")) validation_1.add_messages(validation_2) self.assertEqual(2, len(validation_1.messages)) self.assertEqual(StudioValidationMessage.ERROR, validation_1.messages[0].type) self.assertEqual(u"Error message", validation_1.messages[0].text) self.assertEqual(StudioValidationMessage.NOT_CONFIGURED, validation_1.messages[1].type) self.assertEqual(u"Not configured", validation_1.messages[1].text) self.assertEqual(StudioValidationMessage.WARNING, validation_1.summary.type) self.assertEqual(u"Summary message", validation_1.summary.text)