53 lines
2.6 KiB
Ruby
53 lines
2.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module ScoringChecks
|
|
def check_submission(submit_info)
|
|
lti_check = check_lti_transmission(submit_info[:users])
|
|
# If we got a `:scoring_failure` from the LTI check, we want to display this message exclusively.
|
|
return [lti_check] if lti_check.present? && lti_check[:status] == :scoring_failure
|
|
|
|
# Otherwise, the score was sent successfully for the current user,
|
|
# or it was not attempted for any user (i.e., no `lis_outcome_service` was available).
|
|
# In any way, we want to check for further conditions and return all messages.
|
|
[
|
|
lti_check,
|
|
check_scoring_too_late(submit_info),
|
|
check_full_score,
|
|
]
|
|
end
|
|
|
|
private
|
|
|
|
def check_full_score
|
|
# The submission was not scored with the full score, hence the exercise is not finished yet.
|
|
return unless @submission.full_score?
|
|
|
|
{status: :exercise_finished, url: finalize_submission_path(@submission)}
|
|
end
|
|
|
|
def check_lti_transmission(scored_users)
|
|
if scored_users[:all] == scored_users[:error] || scored_users[:error].include?(current_user)
|
|
# The score was not sent for any user or sending the score for the current user failed.
|
|
# In the latter case, we want to encourage the current user to reopen the exercise through the LMS.
|
|
# Hence, we always display the most severe error message.
|
|
{status: :scoring_failure}
|
|
elsif scored_users[:all] != scored_users[:success] && scored_users[:success].include?(current_user)
|
|
# The score was sent successfully for current user.
|
|
# However, at the same time, the transmission failed for some other users.
|
|
# This could either be due to a temporary network error, which is unlikely, or a more "permanent" error.
|
|
# Permanent errors would be that the deadline has passed on the LMS (which would then not provide a `lis_outcome_service`),
|
|
# working together with an internal user, or with someone who has never opened the exercise before.
|
|
{status: :not_for_all_users_submitted, failed_users: scored_users[:error].map(&:displayname).join(', ')}
|
|
end
|
|
end
|
|
|
|
def check_scoring_too_late(submit_info)
|
|
# The submission was either performed before any deadline or no deadline was configured at all for the current exercise.
|
|
return if %i[within_grace_period after_late_deadline].exclude? submit_info[:deadline]
|
|
# The `lis_outcome_service` was not provided by the LMS, hence we were not able to send any score.
|
|
return if submit_info[:users][:unsupported].include?(current_user)
|
|
|
|
{status: :scoring_too_late, score_sent: (submit_info[:score][:sent] * 100).to_i}
|
|
end
|
|
end
|