Ejemplo n.º 1
0
    def test_serialize_missing_names_and_labels(self):
        # Configure rubric criteria and options with no names or labels
        # This *should* never happen, but if it does, recover gracefully
        # by assigning unique names and empty labels
        self._configure_xblock({})

        for criterion in self.oa_block.rubric_criteria:
            del criterion["name"]
            del criterion["label"]
            for option in criterion["options"]:
                del option["name"]
                del option["label"]

        xml = serialize_content(self.oa_block)
        content_dict = parse_from_xml_str(xml)

        # Verify that all names are unique
        # and that all labels are empty
        criterion_names = set()
        option_names = set()
        criteria_count = 0
        options_count = 0
        for criterion in content_dict["rubric_criteria"]:
            criterion_names.add(criterion["name"])
            self.assertEqual(criterion["label"], u"")
            criteria_count += 1

            for option in criterion["options"]:
                option_names.add(option["name"])
                self.assertEqual(option["label"], u"")
                options_count += 1

        self.assertEqual(len(criterion_names), criteria_count)
        self.assertEqual(len(option_names), options_count)
Ejemplo n.º 2
0
    def xml(self, data, suffix=''):
        """
        Retrieve the XBlock's content definition, serialized as XML.

        Args:
            data (dict): Not used

        Kwargs:
            suffix (str): Not used

        Returns:
            dict with keys 'success' (bool), 'message' (unicode), and 'xml' (unicode)
        """
        try:
            xml = serialize_content(self)

        # We do not expect `serialize_content` to raise an exception,
        # but if it does, handle it gracefully.
        except Exception as ex:
            msg = _(
                'An unexpected error occurred while loading the problem: {error}'
            ).format(error=ex.message)
            logger.error(msg)
            return {'success': False, 'msg': msg, 'xml': u''}
        else:
            return {'success': True, 'msg': '', 'xml': xml}
Ejemplo n.º 3
0
    def test_mutated_criteria_dict(self):
        self.oa_block.title = "Test title"
        self.oa_block.rubric_assessments = self.BASIC_ASSESSMENTS
        self.oa_block.start = None
        self.oa_block.due = None
        self.oa_block.submission_start = None
        self.oa_block.submission_due = None

        # We have to be really permissive with the data we'll accept.
        # If the data we're retrieving is somehow corrupted,
        # Studio authors should still be able to retrive an XML representation
        # so they can edit and fix the issue.
        # To test this, we systematically mutate a valid rubric dictionary by
        # mutating the dictionary, then asserting that we can parse the generated XML.
        for criteria_dict in self.BASIC_CRITERIA:
            for mutated_dict in self._dict_mutations(criteria_dict):
                self.oa_block.rubric_criteria = mutated_dict
                xml = serialize_content(self.oa_block)

                try:
                    etree.fromstring(xml)
                except Exception as ex:  # pylint:disable=W0703
                    msg = "Could not parse mutated criteria dict {criteria}\n{ex}".format(
                        criteria=mutated_dict, ex=ex)
                    self.fail(msg)
Ejemplo n.º 4
0
    def test_serialize_missing_names_and_labels(self):
        # Configure rubric criteria and options with no names or labels
        # This *should* never happen, but if it does, recover gracefully
        # by assigning unique names and empty labels
        self._configure_xblock({})

        for criterion in self.oa_block.rubric_criteria:
            del criterion['name']
            del criterion['label']
            for option in criterion['options']:
                del option['name']
                del option['label']

        xml = serialize_content(self.oa_block)
        content_dict = parse_from_xml_str(xml)

        # Verify that all names are unique
        # and that all labels are empty
        criterion_names = set()
        option_names = set()
        criteria_count = 0
        options_count = 0
        for criterion in content_dict['rubric_criteria']:
            criterion_names.add(criterion['name'])
            self.assertEqual(criterion['label'], '')
            criteria_count += 1

            for option in criterion['options']:
                option_names.add(option['name'])
                self.assertEqual(option['label'], '')
                options_count += 1

        self.assertEqual(len(criterion_names), criteria_count)
        self.assertEqual(len(option_names), options_count)
Ejemplo n.º 5
0
    def test_serialize(self, data):
        self.oa_block.title = data['title']
        self.oa_block.prompt = data['prompt']
        self.oa_block.rubric_feedback_prompt = data['rubric_feedback_prompt']
        self.oa_block.start = _parse_date(data['start'])
        self.oa_block.due = _parse_date(data['due'])
        self.oa_block.submission_start = data['submission_start']
        self.oa_block.submission_due = data['submission_due']
        self.oa_block.rubric_criteria = data['criteria']
        self.oa_block.rubric_assessments = data['assessments']
        xml = serialize_content(self.oa_block)

        # Compare the XML with our expected output
        # To make the comparison robust, first parse the actual and expected XML
        # then compare elements/attributes in the tree.
        try:
            parsed_actual = etree.fromstring(xml)
        except (ValueError, etree.XMLSyntaxError):
            self.fail("Could not parse output XML:\n{}".format(xml))

        # Assume that the test data XML is valid; if not, this will raise an error
        # instead of a test failure.
        parsed_expected = etree.fromstring("".join(data['expected_xml']))

        # Pretty-print and reparse the expected XML
        pretty_expected = etree.tostring(parsed_expected,
                                         pretty_print=True,
                                         encoding='utf-8')
        parsed_expected = etree.fromstring(pretty_expected)

        # Walk both trees, comparing elements and attributes
        actual_elements = [el for el in parsed_actual.getiterator()]
        expected_elements = [el for el in parsed_expected.getiterator()]

        self.assertEqual(
            len(actual_elements),
            len(expected_elements),
            msg="Incorrect XML output:\nActual: {}\nExpected: {}".format(
                xml, pretty_expected))

        for actual, expected in zip(actual_elements, expected_elements):
            self.assertEqual(actual.tag, expected.tag)
            self.assertEqual(
                actual.text,
                expected.text,
                msg=
                u"Incorrect text for {tag}.  Expected '{expected}' but found '{actual}'"
                .format(tag=actual.tag,
                        expected=expected.text,
                        actual=actual.text))
            self.assertItemsEqual(
                actual.items(),
                expected.items(),
                msg=
                u"Incorrect attributes for {tag}.  Expected {expected} but found {actual}"
                .format(tag=actual.tag,
                        expected=expected.items(),
                        actual=actual.items()))
Ejemplo n.º 6
0
    def test_mutated_field(self, field):
        self._configure_xblock({})

        for mutated_value in [0, "\u9282", None]:
            setattr(self.oa_block, field, mutated_value)
            xml = serialize_content(self.oa_block)

            try:
                etree.fromstring(xml)
            except Exception as ex:  # pylint:disable=W0703
                msg = "Could not parse mutated field {field} with value {value}\n{ex}".format(
                    field=field, value=mutated_value, ex=ex)
                self.fail(msg)
Ejemplo n.º 7
0
    def test_mutated_prompts_dict(self):
        self._configure_xblock({})

        for prompts_list in self.BASIC_PROMPTS:
            for mutated_list in self._list_mutations(prompts_list):
                self.oa_block.prompts = mutated_list
                xml = serialize_content(self.oa_block)

                try:
                    etree.fromstring(xml)
                except Exception as ex:  # pylint:disable=W0703
                    msg = f"Could not parse mutated prompts list {mutated_list}\n{ex}"
                    self.fail(msg)
Ejemplo n.º 8
0
    def test_mutated_prompts_dict(self):
        self._configure_xblock({})

        for prompts_list in self.BASIC_PROMPTS:
            for mutated_list in self._list_mutations(prompts_list):
                self.oa_block.prompts = mutated_list
                xml = serialize_content(self.oa_block)

                try:
                    etree.fromstring(xml)
                except Exception as ex:  # pylint:disable=W0703
                    msg = "Could not parse mutated prompts list {prompts}\n{ex}".format(prompts=mutated_list, ex=ex)
                    self.fail(msg)
Ejemplo n.º 9
0
    def test_mutated_assessments_dict(self):
        self._configure_xblock({})

        for assessment_dict in self.BASIC_ASSESSMENTS:
            for mutated_dict in self._dict_mutations(assessment_dict):
                self.oa_block.rubric_assessments = [mutated_dict]
                xml = serialize_content(self.oa_block)

                try:
                    etree.fromstring(xml)
                except Exception as ex:     # pylint:disable=W0703
                    msg = "Could not parse mutated assessment dict {assessment}\n{ex}".format(assessment=mutated_dict, ex=ex)
                    self.fail(msg)
Ejemplo n.º 10
0
    def test_serialize(self, data):
        self.oa_block.title = data['title']
        self.oa_block.prompt = data['prompt']
        self.oa_block.rubric_feedback_prompt = data['rubric_feedback_prompt']
        self.oa_block.start = _parse_date(data['start'])
        self.oa_block.due = _parse_date(data['due'])
        self.oa_block.submission_start = data['submission_start']
        self.oa_block.submission_due = data['submission_due']
        self.oa_block.rubric_criteria = data['criteria']
        self.oa_block.rubric_assessments = data['assessments']
        xml = serialize_content(self.oa_block)

        # Compare the XML with our expected output
        # To make the comparison robust, first parse the actual and expected XML
        # then compare elements/attributes in the tree.
        try:
            parsed_actual = etree.fromstring(xml)
        except (ValueError, etree.XMLSyntaxError):
            self.fail("Could not parse output XML:\n{}".format(xml))

        # Assume that the test data XML is valid; if not, this will raise an error
        # instead of a test failure.
        parsed_expected = etree.fromstring("".join(data['expected_xml']))

        # Pretty-print and reparse the expected XML
        pretty_expected = etree.tostring(parsed_expected, pretty_print=True, encoding='utf-8')
        parsed_expected = etree.fromstring(pretty_expected)

        # Walk both trees, comparing elements and attributes
        actual_elements = [el for el in parsed_actual.getiterator()]
        expected_elements = [el for el in parsed_expected.getiterator()]

        self.assertEqual(
            len(actual_elements), len(expected_elements),
            msg="Incorrect XML output:\nActual: {}\nExpected: {}".format(actual_elements, expected_elements)
        )

        for actual, expected in zip(actual_elements, expected_elements):
            self.assertEqual(actual.tag, expected.tag)
            self.assertEqual(
                actual.text, expected.text,
                msg=u"Incorrect text for {tag}.  Expected '{expected}' but found '{actual}'".format(
                    tag=actual.tag, expected=expected.text, actual=actual.text
                )
            )
            self.assertItemsEqual(
                actual.items(), expected.items(),
                msg=u"Incorrect attributes for {tag}.  Expected {expected} but found {actual}".format(
                    tag=actual.tag, expected=expected.items(), actual=actual.items()
                )
            )
Ejemplo n.º 11
0
    def test_mutated_field(self, field):
        self._configure_xblock({})

        for mutated_value in [0, u"\u9282", None]:
            setattr(self.oa_block, field, mutated_value)
            xml = serialize_content(self.oa_block)

            try:
                etree.fromstring(xml)
            except Exception as ex:  # pylint:disable=W0703
                msg = "Could not parse mutated field {field} with value {value}\n{ex}".format(
                    field=field, value=mutated_value, ex=ex
                )
                self.fail(msg)
Ejemplo n.º 12
0
    def test_serialize(self, data):
        self._configure_xblock(data)
        xml = serialize_content(self.oa_block)

        # Compare the XML with our expected output
        # To make the comparison robust, first parse the actual and expected XML
        # then compare elements/attributes in the tree.
        try:
            parsed_actual = etree.fromstring(xml)
        except (ValueError, etree.XMLSyntaxError):
            self.fail(f"Could not parse output XML:\n{xml}")

        # Assume that the test data XML is valid; if not, this will raise an error
        # instead of a test failure.
        parsed_expected = etree.fromstring("".join(data['expected_xml']))

        # Pretty-print and reparse the expected XML
        pretty_expected = etree.tostring(parsed_expected,
                                         pretty_print=True,
                                         encoding='unicode')
        parsed_expected = etree.fromstring(pretty_expected)

        # Walk both trees, comparing elements and attributes
        actual_elements = list(parsed_actual.getiterator())
        expected_elements = list(parsed_expected.getiterator())
        self.assertEqual(
            len(actual_elements),
            len(expected_elements),
            msg=
            f"Incorrect XML output:\nActual: {xml}\nExpected: {pretty_expected}"
        )

        for actual, expected in zip(actual_elements, expected_elements):
            self.assertEqual(actual.tag, expected.tag)
            self.assertEqual(
                actual.text,
                expected.text,
                msg=
                "Incorrect text for {tag}.  Expected '{expected}' but found '{actual}'"
                .format(tag=actual.tag,
                        expected=expected.text,
                        actual=actual.text))
            self.assertCountEqual(
                list(actual.items()),
                list(expected.items()),
                msg=
                "Incorrect attributes for {tag}.  Expected {expected} but found {actual}"
                .format(tag=actual.tag,
                        expected=list(expected.items()),
                        actual=list(actual.items())))
Ejemplo n.º 13
0
    def test_mutated_assessments_dict(self):
        self.oa_block.title = "Test title"
        self.oa_block.rubric_criteria = self.BASIC_CRITERIA
        self.oa_block.start = None
        self.oa_block.due = None
        self.oa_block.submission_due = None

        for assessment_dict in self.BASIC_ASSESSMENTS:
            for mutated_dict in self._dict_mutations(assessment_dict):
                self.oa_block.rubric_assessments = [mutated_dict]
                xml = serialize_content(self.oa_block)

                try:
                    etree.fromstring(xml)
                except Exception as ex:
                    msg = "Could not parse mutated assessment dict {assessment}\n{ex}".format(assessment=mutated_dict, ex=ex)
                    self.fail(msg)
Ejemplo n.º 14
0
    def test_serialize(self, data):
        self._configure_xblock(data)
        xml = serialize_content(self.oa_block)

        # Compare the XML with our expected output
        # To make the comparison robust, first parse the actual and expected XML
        # then compare elements/attributes in the tree.
        try:
            parsed_actual = etree.fromstring(xml)
        except (ValueError, etree.XMLSyntaxError):
            self.fail("Could not parse output XML:\n{}".format(xml))

        # Assume that the test data XML is valid; if not, this will raise an error
        # instead of a test failure.
        parsed_expected = etree.fromstring("".join(data["expected_xml"]))

        # Pretty-print and reparse the expected XML
        pretty_expected = etree.tostring(parsed_expected, pretty_print=True, encoding="unicode")
        parsed_expected = etree.fromstring(pretty_expected)

        # Walk both trees, comparing elements and attributes
        actual_elements = [el for el in parsed_actual.getiterator()]
        expected_elements = [el for el in parsed_expected.getiterator()]
        self.assertEqual(
            len(actual_elements),
            len(expected_elements),
            msg=u"Incorrect XML output:\nActual: {}\nExpected: {}".format(xml, pretty_expected),
        )

        for actual, expected in zip(actual_elements, expected_elements):
            self.assertEqual(actual.tag, expected.tag)
            self.assertEqual(
                actual.text,
                expected.text,
                msg=u"Incorrect text for {tag}.  Expected '{expected}' but found '{actual}'".format(
                    tag=actual.tag, expected=expected.text, actual=actual.text
                ),
            )
            self.assertItemsEqual(
                actual.items(),
                expected.items(),
                msg=u"Incorrect attributes for {tag}.  Expected {expected} but found {actual}".format(
                    tag=actual.tag, expected=expected.items(), actual=actual.items()
                ),
            )
Ejemplo n.º 15
0
    def test_mutated_field(self, field):
        self.oa_block.rubric_criteria = self.BASIC_CRITERIA
        self.oa_block.rubric_assessments = self.BASIC_ASSESSMENTS
        self.oa_block.start = None
        self.oa_block.due = None
        self.oa_block.submission_start = None
        self.oa_block.submission_due = None

        for mutated_value in [0, u"\u9282", None]:
            setattr(self.oa_block, field, mutated_value)
            xml = serialize_content(self.oa_block)

            try:
                etree.fromstring(xml)
            except Exception as ex:  # pylint:disable=W0703
                msg = "Could not parse mutated field {field} with value {value}\n{ex}".format(
                    field=field, value=mutated_value, ex=ex)
                self.fail(msg)
Ejemplo n.º 16
0
    def test_mutated_assessments_dict(self):
        self.oa_block.title = "Test title"
        self.oa_block.rubric_criteria = self.BASIC_CRITERIA
        self.oa_block.start = None
        self.oa_block.due = None
        self.oa_block.submission_start = None
        self.oa_block.submission_due = None

        for assessment_dict in self.BASIC_ASSESSMENTS:
            for mutated_dict in self._dict_mutations(assessment_dict):
                self.oa_block.rubric_assessments = [mutated_dict]
                xml = serialize_content(self.oa_block)

                try:
                    etree.fromstring(xml)
                except Exception as ex:
                    msg = "Could not parse mutated assessment dict {assessment}\n{ex}".format(assessment=mutated_dict, ex=ex)
                    self.fail(msg)
Ejemplo n.º 17
0
    def test_mutated_field(self, field):
        self.oa_block.rubric_criteria = self.BASIC_CRITERIA
        self.oa_block.rubric_assessments = self.BASIC_ASSESSMENTS
        self.oa_block.start = None
        self.oa_block.due = None
        self.oa_block.submission_due = None

        for mutated_value in [0, u"\u9282", None]:
            setattr(self.oa_block, field, mutated_value)
            xml = serialize_content(self.oa_block)

            try:
                etree.fromstring(xml)
            except Exception as ex:
                msg = "Could not parse mutated field {field} with value {value}\n{ex}".format(
                    field=field, value=mutated_value, ex=ex
                )
                self.fail(msg)
Ejemplo n.º 18
0
    def test_mutated_criteria_dict(self):
        self._configure_xblock({})

        # We have to be really permissive with the data we'll accept.
        # If the data we're retrieving is somehow corrupted,
        # Studio authors should still be able to retrive an XML representation
        # so they can edit and fix the issue.
        # To test this, we systematically mutate a valid rubric dictionary by
        # mutating the dictionary, then asserting that we can parse the generated XML.
        for criteria_dict in self.BASIC_CRITERIA:
            for mutated_dict in self._dict_mutations(criteria_dict):
                self.oa_block.rubric_criteria = mutated_dict
                xml = serialize_content(self.oa_block)

                try:
                    etree.fromstring(xml)
                except Exception as ex:  # pylint:disable=W0703
                    msg = "Could not parse mutated criteria dict {criteria}\n{ex}".format(criteria=mutated_dict, ex=ex)
                    self.fail(msg)
Ejemplo n.º 19
0
    def xml(self, data, suffix=''):
        """
        Retrieve the XBlock's content definition, serialized as XML.

        Args:
            data (dict): Not used

        Kwargs:
            suffix (str): Not used

        Returns:
            dict with keys 'success' (bool), 'message' (unicode), and 'xml' (unicode)
        """
        try:
            xml = serialize_content(self)

        # We do not expect `serialize_content` to raise an exception,
        # but if it does, handle it gracefully.
        except Exception as ex:
            msg = _('An unexpected error occurred while loading the problem: {error}').format(error=ex)
            logger.error(msg)
            return {'success': False, 'msg': msg, 'xml': u''}
        else:
            return {'success': True, 'msg': '', 'xml': xml}