def test_send_scores(self): from pylti1p3.contrib.django import DjangoMessageLaunch tool_conf = get_test_tool_conf() with patch.object(DjangoMessageLaunch, "_get_jwt_body", autospec=True) as get_jwt_body: message_launch = DjangoMessageLaunch(DjangoFakeRequest(), tool_conf) get_jwt_body.side_effect = lambda x: self._get_jwt_body() with patch('socket.gethostbyname', return_value="127.0.0.1"): with requests_mock.Mocker() as m: m.post(self._get_auth_token_url(), text=json.dumps(self._get_auth_token_response())) m.get( 'http://canvas.docker/api/lti/courses/1/line_items', text=json.dumps([{ 'scoreMaximum': 100.0, 'tag': 'score', 'id': 'http://canvas.docker/api/lti/courses/1/line_items/1', 'label': 'Score' }])) expected_result = { 'resultUrl': 'http://canvas.docker/api/lti/courses/1/line_items/1/results/4' } m.post( 'http://canvas.docker/api/lti/courses/1/line_items/1/scores', text=json.dumps(expected_result)) ags = message_launch.validate_registration().get_ags() sub = message_launch.get_launch_data().get('sub') timestamp = datetime.datetime.utcnow().strftime( '%Y-%m-%dT%H:%M:%S+0000') sc = Grade() sc.set_score_given(5) \ .set_score_maximum(100) \ .set_timestamp(timestamp) \ .set_activity_progress('Completed') \ .set_grading_progress('FullyGraded') \ .set_user_id(sub) sc_line_item = LineItem() sc_line_item.set_tag('score') \ .set_score_maximum(100) \ .set_label('Score') resp = ags.put_grade(sc, sc_line_item) self.assertEqual(expected_result, resp['body'])
def score(launch_id, earned_score, time_spent): tool_conf = ToolConfJsonFile(get_lti_config_path()) flask_request = FlaskRequest() launch_data_storage = get_launch_data_storage() message_launch = ExtendedFlaskMessageLaunch.from_cache( launch_id, flask_request, tool_conf, launch_data_storage=launch_data_storage) resource_link_id = message_launch.get_launch_data() \ .get('https://purl.imsglobal.org/spec/lti/claim/resource_link', {}).get('id') if not message_launch.has_ags(): raise Forbidden("Don't have grades!") sub = message_launch.get_launch_data().get('sub') timestamp = datetime.datetime.utcnow().isoformat() + 'Z' earned_score = int(earned_score) time_spent = int(time_spent) grades = message_launch.get_ags() sc = Grade() sc.set_score_given(earned_score) \ .set_score_maximum(100) \ .set_timestamp(timestamp) \ .set_activity_progress('Completed') \ .set_grading_progress('FullyGraded') \ .set_user_id(sub) sc_line_item = LineItem() sc_line_item.set_tag('score') \ .set_score_maximum(100) \ .set_label('Score') if resource_link_id: sc_line_item.set_resource_id(resource_link_id) grades.put_grade(sc, sc_line_item) tm = Grade() tm.set_score_given(time_spent) \ .set_score_maximum(999) \ .set_timestamp(timestamp) \ .set_activity_progress('Completed') \ .set_grading_progress('FullyGraded') \ .set_user_id(sub) tm_line_item = LineItem() tm_line_item.set_tag('time') \ .set_score_maximum(999) \ .set_label('Time Taken') if resource_link_id: tm_line_item.set_resource_id(resource_link_id) result = grades.put_grade(tm, tm_line_item) return jsonify({'success': True, 'result': result.get('body')})
def score(request, launch_id, earned_score, time_spent): tool_conf = ToolConfJsonFile(get_lti_config_path()) message_launch = ExtendedDjangoMessageLaunch.from_cache( launch_id, request, tool_conf) if not message_launch.has_ags(): return HttpResponseForbidden("Don't have grades!") sub = message_launch.get_launch_data().get('sub') timestamp = datetime.datetime.utcnow().isoformat() earned_score = int(earned_score) time_spent = int(time_spent) grades = message_launch.get_ags() sc = Grade() sc.set_score_given(earned_score)\ .set_score_maximum(100)\ .set_timestamp(timestamp)\ .set_activity_progress('Completed')\ .set_grading_progress('FullyGraded')\ .set_user_id(sub) sc_line_item = LineItem() sc_line_item.set_tag('score')\ .set_score_maximum(100)\ .set_label('Score') grades.put_grade(sc, sc_line_item) tm = Grade() tm.set_score_given(time_spent)\ .set_score_maximum(999)\ .set_timestamp(timestamp)\ .set_activity_progress('Completed')\ .set_grading_progress('FullyGraded')\ .set_user_id(sub) tm_line_item = LineItem() tm_line_item.set_tag('time')\ .set_score_maximum(999)\ .set_label('Time Taken') result = grades.put_grade(tm, tm_line_item) return JsonResponse({'success': True, 'result': result.get('body')})
def update_score(self, weighted_earned, weighted_possible, timestamp): """ Use LTI's score service to update the LTI platform's gradebook. This method synchronously send a request to the LTI platform to update the assignment score. """ launch_data = { 'iss': self.profile.platform_id, 'aud': self.profile.client_id, 'https://purl.imsglobal.org/spec/lti-ags/claim/endpoint': { 'lineitem': self.ags_lineitem, 'scope': { 'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem', 'https://purl.imsglobal.org/spec/lti-ags/scope/score', } } } tool_config = DjangoDbToolConf() ags = (DjangoMessageLaunch( request=None, tool_config=tool_config).set_auto_validation(enable=False).set_jwt( { 'body': launch_data }).set_restored().validate_registration().get_ags()) if weighted_possible == 0: weighted_score = 0 else: weighted_score = float(weighted_earned) / float(weighted_possible) ags.put_grade(Grade().set_score_given( weighted_score).set_score_maximum(1).set_timestamp( timestamp.isoformat()).set_activity_progress('Submitted'). set_grading_progress('FullyGraded').set_user_id( self.profile.subject_id))