def send_lrs_statement(self, statement_string): try: XAPI._send_lrs_statement(json.loads(statement_string)) except socket.error as error: # don't raise connection refused error when in eager mode if error.errno != socket.errno.ECONNREFUSED: return raise error
def post(self): if not XAPI.enabled: return 404 params = statement_parser.parse_args() statement = XAPIStatement.generate_from_params(current_user, params) XAPI.send_statement(statement) return { 'success': True }
def post(self): if not XAPI.enabled(): # this should silently fail abort(404) params = statement_parser.parse_args() statement = XAPIStatement.generate_from_params(current_user, params) XAPI.send_statement(statement) return {'success': True}
def post(self): if not XAPI.enabled(): # this should silently fail abort(404) params = statement_parser.parse_args() statement = XAPIStatement.generate_from_params(current_user, params) XAPI.send_statement(statement) return { 'success': True }
def test_send_remote_statement(self, mocked_save_statement): def save_statement_override(statement): self.sent_statement = json.loads(statement.to_json(XAPI._version)) return LRSResponse( success=True, request=None, response=None, data=json.dumps(["123"]), ) mocked_save_statement.side_effect = save_statement_override # test with answer normal content statement = XAPIStatement.generate( user=self.user, verb=XAPIVerb.generate('submitted'), object=XAPIObject.answer(self.answer), context=XAPIContext.answer(self.answer), result=XAPIResult.answer(self.answer, includeAttachment=True, success=True) ) XAPI._send_lrs_statement(json.loads(statement.to_json(XAPI._version))) self._validate_and_cleanup_statement(self.sent_statement) self.assertEqual(self.sent_statement['actor'], self.get_compair_actor(self.user)) self.assertEqual(self.sent_statement['verb'], { 'id': 'http://activitystrea.ms/schema/1.0/submit', 'display': {'en-US': 'submitted'} }) self.assertEqual(self.sent_statement['object'], { 'id': 'https://localhost:8888/app/xapi/answer/'+self.answer.uuid, 'definition': {'type': 'http://id.tincanapi.com/activitytype/solution', 'name': {'en-US': 'Assignment answer'}}, 'objectType': 'Activity' }) self.assertEqual(self.sent_statement['result'], { 'extensions': { 'http://xapi.learninganalytics.ubc.ca/extension/character-count': len(self.answer.content), 'http://xapi.learninganalytics.ubc.ca/extension/word-count': len(self.answer.content.split(" ")) }, 'response': self.answer.content, 'success': True }) self.assertEqual(self.sent_statement['context'], { 'contextActivities': { 'grouping': [{ 'id': 'https://localhost:8888/app/xapi/course/'+self.course.uuid, 'objectType': 'Activity' },{ 'id': 'https://localhost:8888/app/xapi/assignment/'+self.assignment.uuid, 'objectType': 'Activity' }], 'parent': [{ 'id': 'https://localhost:8888/app/xapi/assignment/'+self.assignment.uuid+'/question', 'objectType': 'Activity' }] } }) # test with extremely long answer content # content should be ~ LRS_USER_INPUT_FIELD_SIZE_LIMIT bytes long + 100 characters content = "c" * (self.character_limit + 100) # expected_result_response should be <= LRS_USER_INPUT_FIELD_SIZE_LIMIT bytes long + " [TEXT TRIMMED]..." expected_result_response = ("c" * self.character_limit) + " [TEXT TRIMMED]..." self.answer.content = content db.session.commit() statement = XAPIStatement.generate( user=self.user, verb=XAPIVerb.generate('submitted'), object=XAPIObject.answer(self.answer), context=XAPIContext.answer(self.answer), result=XAPIResult.answer(self.answer, includeAttachment=True, success=True) ) XAPI._send_lrs_statement(json.loads(statement.to_json(XAPI._version))) self._validate_and_cleanup_statement(self.sent_statement) self.assertEqual(self.sent_statement['actor'], self.get_compair_actor(self.user)) self.assertEqual(self.sent_statement['verb'], { 'id': 'http://activitystrea.ms/schema/1.0/submit', 'display': {'en-US': 'submitted'} }) self.assertEqual(self.sent_statement['object'], { 'id': 'https://localhost:8888/app/xapi/answer/'+self.answer.uuid, 'definition': {'type': 'http://id.tincanapi.com/activitytype/solution', 'name': {'en-US': 'Assignment answer'}}, 'objectType': 'Activity' }) self.assertEqual(self.sent_statement['result'], { 'extensions': { 'http://xapi.learninganalytics.ubc.ca/extension/character-count': len(self.answer.content), 'http://xapi.learninganalytics.ubc.ca/extension/word-count': len(self.answer.content.split(" ")) }, 'response': expected_result_response, 'success': True }) self.assertEqual(self.sent_statement['context'], { 'contextActivities': { 'grouping': [{ 'id': 'https://localhost:8888/app/xapi/course/'+self.course.uuid, 'objectType': 'Activity' },{ 'id': 'https://localhost:8888/app/xapi/assignment/'+self.assignment.uuid, 'objectType': 'Activity' },], 'parent': [{ 'id': 'https://localhost:8888/app/xapi/assignment/'+self.assignment.uuid+'/question', 'objectType': 'Activity' }] } }) # test with assignment normal content statement = XAPIStatement.generate( user=self.user, verb=XAPIVerb.generate('updated'), object=XAPIObject.assignment(self.assignment), context=XAPIContext.assignment(self.assignment) ) XAPI._send_lrs_statement(json.loads(statement.to_json(XAPI._version))) self._validate_and_cleanup_statement(self.sent_statement) self.assertEqual(self.sent_statement['actor'], self.get_compair_actor(self.user)) self.assertEqual(self.sent_statement['verb'], { 'id': 'http://activitystrea.ms/schema/1.0/update', 'display': {'en-US': 'updated'} }) self.assertEqual(self.sent_statement['object'], { 'id': 'https://localhost:8888/app/xapi/assignment/'+self.assignment.uuid, 'definition': { 'type': 'http://adlnet.gov/expapi/activities/assessment', 'name': {'en-US': self.assignment.name }, 'description': {'en-US': self.assignment.description } }, 'objectType': 'Activity' }) self.assertNotIn('result', self.sent_statement) self.assertEqual(self.sent_statement['context'], { 'contextActivities': { 'parent': [{ 'id': 'https://localhost:8888/app/xapi/course/'+self.course.uuid, 'objectType': 'Activity' }] } }) # test with extremely long answer content # content should be ~ LRS_USER_INPUT_FIELD_SIZE_LIMIT bytes long + 100 characters name = "a" * (self.character_limit + 100) description = "b" * (self.character_limit + 100) # expected_result_response should be <= LRS_USER_INPUT_FIELD_SIZE_LIMIT bytes long + " [TEXT TRIMMED]..." expected_object_name = ("a" * self.character_limit) + " [TEXT TRIMMED]..." expected_object_description = ("b" * self.character_limit) + " [TEXT TRIMMED]..." self.assignment.name = name self.assignment.description = description db.session.commit() statement = XAPIStatement.generate( user=self.user, verb=XAPIVerb.generate('updated'), object=XAPIObject.assignment(self.assignment), context=XAPIContext.assignment(self.assignment) ) XAPI._send_lrs_statement(json.loads(statement.to_json(XAPI._version))) self._validate_and_cleanup_statement(self.sent_statement) self.assertEqual(self.sent_statement['actor'], self.get_compair_actor(self.user)) self.assertEqual(self.sent_statement['verb'], { 'id': 'http://activitystrea.ms/schema/1.0/update', 'display': {'en-US': 'updated'} }) self.assertEqual(self.sent_statement['object'], { 'id': 'https://localhost:8888/app/xapi/assignment/'+self.assignment.uuid, 'definition': { 'type': 'http://adlnet.gov/expapi/activities/assessment', 'name': {'en-US': expected_object_name }, 'description': {'en-US': expected_object_description } }, 'objectType': 'Activity' }) self.assertNotIn('result', self.sent_statement) self.assertEqual(self.sent_statement['context'], { 'contextActivities': { 'parent': [{ 'id': 'https://localhost:8888/app/xapi/course/'+self.course.uuid, 'objectType': 'Activity' }] } })
def send_lrs_statements(statements): XAPI._send_lrs_statements(statements)