From 564b249e50fcfaab8bddd334bb9f2a4045b9e007 Mon Sep 17 00:00:00 2001 From: Sebastian Serth Date: Tue, 12 May 2020 13:53:46 +0200 Subject: [PATCH] Refactor send_score to have access to the submission --- app/controllers/concerns/lti.rb | 22 ++++++++++++---------- app/controllers/exercises_controller.rb | 6 +++++- spec/concerns/lti_spec.rb | 15 ++++++++++----- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/app/controllers/concerns/lti.rb b/app/controllers/concerns/lti.rb index b19f885c..62e2899d 100644 --- a/app/controllers/concerns/lti.rb +++ b/app/controllers/concerns/lti.rb @@ -16,8 +16,8 @@ module Lti private :build_tool_provider - # exercise_id.nil? ==> the user has logged out. All session data is to be destroyed - # exercise_id.exists? ==> the user has submitted the results of an exercise to the consumer. + # @submission.exercise_id.nil? ==> the user has logged out. All session data is to be destroyed + # @submission.exercise_id.exists? ==> the user has submitted the results of an exercise to the consumer. # Only the lti_parameters are deleted. def clear_lti_session_data(exercise_id = nil, user_id = nil, consumer_id = nil) if (exercise_id.nil?) @@ -138,14 +138,14 @@ module Lti private :return_to_consumer - def send_score(exercise_id, score, user_id) - ::NewRelic::Agent.add_custom_attributes({score: score, session: session}) - fail(Error, "Score #{score} must be between 0 and #{MAXIMUM_SCORE}!") unless (0..MAXIMUM_SCORE).include?(score) + def send_score(submission) + ::NewRelic::Agent.add_custom_attributes({score: submission.normalized_score, session: session}) + fail(Error, "Score #{submission.normalized_score} must be between 0 and #{MAXIMUM_SCORE}!") unless (0..MAXIMUM_SCORE).include?(submission.normalized_score) if session[:consumer_id] lti_parameter = LtiParameter.where(consumers_id: session[:consumer_id], - external_users_id: user_id, - exercises_id: exercise_id).last + external_users_id: submission.user_id, + exercises_id: submission.exercise_id).last consumer = Consumer.find_by(id: session[:consumer_id]) provider = build_tool_provider(consumer: consumer, parameters: lti_parameter.lti_parameters) @@ -153,15 +153,17 @@ module Lti if provider.nil? {status: 'error'} + elsif submission.after_late_deadline? + {status: 'too late'} elsif provider.outcome_service? Raven.extra_context({ provider: provider.inspect, - score: score, + score: submission.normalized_score, lti_parameter: lti_parameter.inspect, session: session.to_hash, - exercise_id: exercise_id + exercise_id: submission.exercise_id }) - response = provider.post_replace_result!(score) + response = provider.post_replace_result!(submission.normalized_score) {code: response.response_code, message: response.post_response.body, status: response.code_major} else {status: 'unsupported'} diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index 55afc796..c8c137b9 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -459,10 +459,14 @@ class ExercisesController < ApplicationController def transmit_lti_score ::NewRelic::Agent.add_custom_attributes({submission: @submission.id, normalized_score: @submission.normalized_score}) - response = send_score(@submission.exercise_id, @submission.normalized_score, @submission.user_id) + response = send_score(@submission) if response[:status] == 'success' redirect_after_submit + elsif response[:status] == 'too late' + flash[:warning] = I18n.t('exercises.submit.too_late') + flash.keep(:warning) + redirect_after_submit else respond_to do |format| format.html { redirect_to(implement_exercise_path(@submission.exercise)) } diff --git a/spec/concerns/lti_spec.rb b/spec/concerns/lti_spec.rb index e184539e..ab02327a 100644 --- a/spec/concerns/lti_spec.rb +++ b/spec/concerns/lti_spec.rb @@ -105,7 +105,8 @@ describe Lti do context 'with an invalid score' do it 'raises an exception' do - expect { controller.send(:send_score, submission.exercise_id, Lti::MAXIMUM_SCORE * 2, submission.user_id) }.to raise_error(Lti::Error) + allow(submission).to receive(:normalized_score).and_return Lti::MAXIMUM_SCORE * 2 + expect { controller.send(:send_score, submission) }.to raise_error(Lti::Error) end end @@ -118,7 +119,8 @@ describe Lti do context 'when grading is not supported' do it 'returns a corresponding status' do expect_any_instance_of(IMS::LTI::ToolProvider).to receive(:outcome_service?).and_return(false) - expect(controller.send(:send_score, submission.exercise_id, score, submission.user_id)[:status]).to eq('unsupported') + allow(submission).to receive(:normalized_score).and_return score + expect(controller.send(:send_score, submission)[:status]).to eq('unsupported') end end @@ -135,11 +137,13 @@ describe Lti do end it 'sends the score' do - controller.send(:send_score, submission.exercise_id, score, submission.user_id) + allow(submission).to receive(:normalized_score).and_return score + controller.send(:send_score, submission) end it 'returns code, message, and status' do - result = controller.send(:send_score, submission.exercise_id, score, submission.user_id) + allow(submission).to receive(:normalized_score).and_return score + result = controller.send(:send_score, submission) expect(result[:code]).to eq(response.response_code) expect(result[:message]).to eq(response.body) expect(result[:status]).to eq(response.code_major) @@ -149,7 +153,8 @@ describe Lti do context 'without a tool consumer' do it 'returns a corresponding status' do - expect(controller.send(:send_score, submission.exercise_id, score, submission.user_id)[:status]).to eq('error') + allow(submission).to receive(:normalized_score).and_return score + expect(controller.send(:send_score, submission)[:status]).to eq('error') end end end