diff --git a/lti_consumer/outcomes.py b/lti_consumer/outcomes.py index 88c804b43ca574d87f500da6671d3ce2c5b388dd..049742aa9eb46520c88da534ae74fc5ab852370e 100644 --- a/lti_consumer/outcomes.py +++ b/lti_consumer/outcomes.py @@ -162,15 +162,16 @@ class OutcomeService(object): # pylint: disable=bad-option-value, useless-objec 'imsx_messageIdentifier': 'unknown', 'response': '' } + request_body = request.body.decode('utf-8') if not self.xblock.accept_grades_past_due and self.xblock.is_past_due: failure_values['imsx_description'] = "Grade is past due" return response_xml_template.format(**failure_values) try: - imsx_message_identifier, sourced_id, score, action = parse_grade_xml_body(request.body) + imsx_message_identifier, sourced_id, score, action = parse_grade_xml_body(request_body) except LtiError as ex: # pylint: disable=no-member - body = escape(request.body) if request.body else '' + body = escape(request_body) if request_body else '' error_message = "Request body XML parsing error: {} {}".format(str(ex), body) log.debug("[LTI]: %s", error_message) failure_values['imsx_description'] = error_message diff --git a/lti_consumer/tests/unit/test_outcomes.py b/lti_consumer/tests/unit/test_outcomes.py index 1ebb538ae2b419a7a33ab3fd52ff219da93d4509..56dd099643a59c9631971a78aa937538c3455aaa 100644 --- a/lti_consumer/tests/unit/test_outcomes.py +++ b/lti_consumer/tests/unit/test_outcomes.py @@ -370,6 +370,20 @@ class TestOutcomeService(TestLtiConsumerXBlock): self.assertIn('failure', response) self.assertIn('Grade is past due', response) + @patch('lti_consumer.outcomes.parse_grade_xml_body') + def test_lti_error_not_raises_type_error(self, mock_parse): + """ + Test XML parsing LtiError exception doesn't raise TypeError exception + while escaping the request body. + """ + request = make_request('test_string') + + mock_parse.side_effect = LtiError + response = self.outcome_servce.handle_request(request) + self.assertNotIn('TypeError', response) + self.assertNotIn('a bytes-like object is required', response) + self.assertIn('Request body XML parsing error', response) + @patch('lti_consumer.outcomes.parse_grade_xml_body') def test_xml_parse_lti_error(self, mock_parse): """