示例#1
0
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
示例#2
0
    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 }
示例#3
0
    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}
示例#4
0
    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 }
示例#5
0
    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'
                }]
            }
        })
示例#6
0
def send_lrs_statements(statements):
    XAPI._send_lrs_statements(statements)