def submit_studio_edits(self, data, suffix=''):
     """
     AJAX handler for studio_view() Save button
     """
     values = {}  # dict of new field values we are updating
     to_reset = []  # list of field names to delete from this XBlock
     for field_name in self.editable_fields:
         field = self.fields[field_name]
         if field_name in data['values']:
             if isinstance(field, JSONField):
                 values[field_name] = field.from_json(data['values'][field_name])
             else:
                 raise JsonHandlerError(400, "Unsupported field type: {}".format(field_name))
         elif field_name in data['defaults'] and field.is_set_on(self):
             to_reset.append(field_name)
     self.clean_studio_edits(values)
     validation = Validation(self.scope_ids.usage_id)
     # We cannot set the fields on self yet, because even if validation fails, studio is going to save any changes we
     # make. So we create a "fake" object that has all the field values we are about to set.
     preview_data = FutureFields(
         new_fields_dict=values,
         newly_removed_fields=to_reset,
         fallback_obj=self
     )
     self.validate_field_data(validation, preview_data)
     if validation:
         for field_name, value in values.iteritems():
             setattr(self, field_name, value)
         for field_name in to_reset:
             self.fields[field_name].delete_from(self)
         return {'result': 'success'}
     else:
         raise JsonHandlerError(400, validation.to_json())
Exemple #2
0
 def submit_studio_edits(self, data, suffix=''):
     """
     AJAX handler for studio_view() Save button
     """
     values = {}  # dict of new field values we are updating
     to_reset = []  # list of field names to delete from this XBlock
     for field_name in self.editable_fields:
         field = self.fields[field_name]
         if field_name in data['values']:
             if isinstance(field, JSONField):
                 values[field_name] = field.from_json(
                     data['values'][field_name])
             else:
                 raise JsonHandlerError(
                     400, "Unsupported field type: {}".format(field_name))
         elif field_name in data['defaults'] and field.is_set_on(self):
             to_reset.append(field_name)
     self.clean_studio_edits(values)
     validation = Validation(self.scope_ids.usage_id)
     # We cannot set the fields on self yet, because even if validation fails, studio is going to save any changes we
     # make. So we create a "fake" object that has all the field values we are about to set.
     preview_data = FutureFields(new_fields_dict=values,
                                 newly_removed_fields=to_reset,
                                 fallback_obj=self)
     self.validate_field_data(validation, preview_data)
     if validation:
         for field_name, value in six.iteritems(values):
             setattr(self, field_name, value)
         for field_name in to_reset:
             self.fields[field_name].delete_from(self)
         return {'result': 'success'}
     else:
         raise JsonHandlerError(400, validation.to_json())
Exemple #3
0
    def test_add_messages_error(self):
        """
        Test that calling `add_messages` with something that is not a `Validation` instances throw an error.
        """
        validation = Validation("id")

        with assert_raises(TypeError):
            validation.add_messages("foo")
Exemple #4
0
    def test_add_messages_error(self):
        """
        Test that calling `add_messages` with something that is not a `Validation` instances throw an error.
        """
        validation = Validation("id")

        with assert_raises(TypeError):
            validation.add_messages("foo")
Exemple #5
0
    def fe_submit_studio_edits(self, data, suffix=''):
        """
        AJAX handler for studio edit submission
        """

        if self.xblock_id is None:
            self.xblock_id = unicode(
                self.location.replace(branch=None, version=None))

        updated_question_template = data['question_template']
        updated_variables = data['variables']
        updated_answer_template = data['answer_template']

        qgb_db_service.update_question_template(self.xblock_id,
                                                updated_question_template,
                                                updated_variables,
                                                updated_answer_template)

        # "refresh" XBlock's values
        self.question_template = updated_question_template
        self.variables = updated_variables
        self.answer_template = updated_answer_template

        # call parent method
        # StudioEditableXBlockMixin.submit_studio_edits(self, data, suffix)
        # self.submit_studio_edits(data, suffix)
        # super(FormulaExerciseXBlock, self).submit_studio_edits(data, suffix)

        # copy from StudioEditableXBlockMixin (can not call parent method)
        values = {}  # dict of new field values we are updating
        to_reset = []  # list of field names to delete from this XBlock
        for field_name in self.editable_fields:
            field = self.fields[field_name]
            if field_name in data['values']:
                if isinstance(field, JSONField):
                    values[field_name] = field.from_json(
                        data['values'][field_name])
                else:
                    raise JsonHandlerError(
                        400, "Unsupported field type: {}".format(field_name))
            elif field_name in data['defaults'] and field.is_set_on(self):
                to_reset.append(field_name)
        self.clean_studio_edits(values)
        validation = Validation(self.scope_ids.usage_id)
        # We cannot set the fields on self yet, because even if validation fails, studio is going to save any changes we
        # make. So we create a "fake" object that has all the field values we are about to set.
        preview_data = FutureFields(new_fields_dict=values,
                                    newly_removed_fields=to_reset,
                                    fallback_obj=self)
        self.validate_field_data(validation, preview_data)
        if validation:
            for field_name, value in values.iteritems():
                setattr(self, field_name, value)
            for field_name in to_reset:
                self.fields[field_name].delete_from(self)
            return {'result': 'success'}
        else:
            raise JsonHandlerError(400, validation.to_json())
Exemple #6
0
    def test_empty(self):
        """
        Test that `empty` return True iff there are no messages.
        Also test the "bool" property of `Validation`.
        """
        validation = Validation("id")
        self.assertTrue(validation.empty)
        self.assertTrue(validation)

        validation.add(ValidationMessage(ValidationMessage.ERROR, "Error message"))
        self.assertFalse(validation.empty)
        self.assertFalse(validation)
Exemple #7
0
    def test_empty(self):
        """
        Test that `empty` return True iff there are no messages.
        Also test the "bool" property of `Validation`.
        """
        validation = Validation("id")
        self.assertTrue(validation.empty)
        self.assertTrue(validation)

        validation.add(ValidationMessage(ValidationMessage.ERROR, "Error message"))
        self.assertFalse(validation.empty)
        self.assertFalse(validation)
Exemple #8
0
    def test_to_json(self):
        """
        Test the ability to serialize a `Validation` instance.
        """
        validation = Validation("id")
        expected = {"xblock_id": "id", "messages": [], "empty": True}
        self.assertEqual(expected, validation.to_json())

        validation.add(
            ValidationMessage(ValidationMessage.ERROR, "Error message"))
        validation.add(
            ValidationMessage(ValidationMessage.WARNING, "Warning message"))

        expected = {
            "xblock_id":
            "id",
            "messages": [{
                "type": ValidationMessage.ERROR,
                "text": "Error message"
            }, {
                "type": ValidationMessage.WARNING,
                "text": "Warning message"
            }],
            "empty":
            False
        }
        self.assertEqual(expected, validation.to_json())
    def test_copy(self):
        validation = Validation("id")
        validation.add(ValidationMessage(ValidationMessage.ERROR, u"Error message"))

        studio_validation = StudioValidation.copy(validation)
        self.assertIsInstance(studio_validation, StudioValidation)
        self.assertFalse(studio_validation)
        self.assertEqual(1, len(studio_validation.messages))
        expected = {
            "type": StudioValidationMessage.ERROR,
            "text": u"Error message"
        }
        self.assertEqual(expected, studio_validation.messages[0].to_json())
        self.assertIsNone(studio_validation.summary)
Exemple #10
0
    def test_copy(self):
        validation = Validation("id")
        validation.add(ValidationMessage(ValidationMessage.ERROR, u"Error message"))

        studio_validation = StudioValidation.copy(validation)
        self.assertIsInstance(studio_validation, StudioValidation)
        self.assertFalse(studio_validation)
        self.assertEqual(1, len(studio_validation.messages))
        expected = {
            "type": StudioValidationMessage.ERROR,
            "text": u"Error message"
        }
        self.assertEqual(expected, studio_validation.messages[0].to_json())
        self.assertIsNone(studio_validation.summary)
Exemple #11
0
    def test_copy(self):
        validation = Validation("id")
        validation.add(
            ValidationMessage(ValidationMessage.ERROR, "Error message"))

        studio_validation = StudioValidation.copy(validation)
        assert isinstance(studio_validation, StudioValidation)
        assert not studio_validation
        assert 1 == len(studio_validation.messages)
        expected = {
            "type": StudioValidationMessage.ERROR,
            "text": "Error message"
        }
        assert expected == studio_validation.messages[0].to_json()
        assert studio_validation.summary is None
Exemple #12
0
 def validate(self):
     """
     Ask this xblock to validate itself. Subclasses are expected to override this
     method, as there is currently only a no-op implementation. Any overriding method
     should call super to collect validation results from its superclasses, and then
     add any additional results as necessary.
     """
     return Validation(self.scope_ids.usage_id)
Exemple #13
0
    def test_add_messages(self):
        """
        Test the behavior of adding the messages from another `Validation` object to this instance.
        """
        validation_1 = Validation("id")
        validation_1.add(ValidationMessage(ValidationMessage.ERROR, "Error message"))

        validation_2 = Validation("id")
        validation_2.add(ValidationMessage(ValidationMessage.WARNING, "Warning message"))

        validation_1.add_messages(validation_2)
        self.assertEqual(2, len(validation_1.messages))

        self.assertEqual(ValidationMessage.ERROR, validation_1.messages[0].type)
        self.assertEqual("Error message", validation_1.messages[0].text)

        self.assertEqual(ValidationMessage.WARNING, validation_1.messages[1].type)
        self.assertEqual("Warning message", validation_1.messages[1].text)
Exemple #14
0
    def test_add_messages(self):
        """
        Test the behavior of adding the messages from another `Validation` object to this instance.
        """
        validation_1 = Validation("id")
        validation_1.add(ValidationMessage(ValidationMessage.ERROR, "Error message"))

        validation_2 = Validation("id")
        validation_2.add(ValidationMessage(ValidationMessage.WARNING, "Warning message"))

        validation_1.add_messages(validation_2)
        self.assertEqual(2, len(validation_1.messages))

        self.assertEqual(ValidationMessage.ERROR, validation_1.messages[0].type)
        self.assertEqual("Error message", validation_1.messages[0].text)

        self.assertEqual(ValidationMessage.WARNING, validation_1.messages[1].type)
        self.assertEqual("Warning message", validation_1.messages[1].text)
Exemple #15
0
    def test_to_json(self):
        """
        Test the ability to serialize a `Validation` instance.
        """
        validation = Validation("id")
        expected = {
            "xblock_id": "id",
            "messages": [],
            "empty": True
        }
        self.assertEqual(expected, validation.to_json())

        validation.add(ValidationMessage(ValidationMessage.ERROR, "Error message"))
        validation.add(ValidationMessage(ValidationMessage.WARNING, "Warning message"))

        expected = {
            "xblock_id": "id",
            "messages": [
                {"type": ValidationMessage.ERROR, "text": "Error message"},
                {"type": ValidationMessage.WARNING, "text": "Warning message"}
            ],
            "empty": False
        }
        self.assertEqual(expected, validation.to_json())
Exemple #16
0
 def verify_validation(self, data, expect_success):
     validation = Validation('xblock_id')
     self.block.validate_field_data(validation, data)
     self.assertEqual(bool(validation), expect_success)