From 30e4e63384aafd83c04f7732948b143f61b98559 Mon Sep 17 00:00:00 2001 From: kiragrammel Date: Fri, 25 Aug 2023 16:38:05 +0200 Subject: [PATCH] WIP apply suggestions --- app/controllers/submissions_controller.rb | 57 ++++++++++++++++------- config/locales/de.yml | 2 +- config/locales/en.yml | 6 +-- spec/features/score_spec.rb | 4 +- 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index bbe28d5c8..85a3c9fad 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -74,7 +74,7 @@ def download_file end def finalize - @submission.update(cause: 'submit') + @submission.update!(cause: 'submit') redirect_after_submit end @@ -274,25 +274,12 @@ def score # send_hints(client_socket, StructuredError.where(submission: @submission)) # Submit the score - if @submission.user.external_user? && lti_outcome_service?(@submission.exercise_id, @submission.user.id) - response = send_score(@submission) - - if response[:status] == 'success' - if response[:score_sent] != @submission.normalized_score - # Score has been reduced due to the passed deadline - client_socket&.send_data(JSON.dump({cmd: :status, status: :scoring_too_late, score_sent: response[:score_sent]})) - end - else - client_socket&.send_data(JSON.dump({cmd: :status, status: :scoring_failure})) - end - end - - if @submission.score == @submission.exercise.maximum_score - @url = finalize_submission_path(@submission) - client_socket&.send_data(JSON.dump({cmd: :status, status: :full_score_reached, url: @url})) + if @submission.users.map {|user| lti_outcome_service?(@submission.exercise, user, @submission.study_group_id) }.any? + transmit_lti_score + else + finalize end - kill_client_socket(client_socket) rescue Runner::Error => e extract_durations(e) send_and_store client_socket, {cmd: :status, status: :container_depleted} @@ -300,6 +287,8 @@ def score Sentry.capture_exception(e) @testrun[:passed] = false save_testrun_output 'assess' + ensure + kill_client_socket(client_socket) end def create @@ -490,6 +479,38 @@ def set_testrun } end + def transmit_lti_score + responses = send_scores(@submission) + messages = {} + failed_users = [] + + responses.each do |response| + if Lti::ERROR_STATUS.include? response[:status] + failed_users << response[:user] + elsif response[:score_sent] != @submission.normalized_score # the score was sent successfully, but received too late + messages[:warning] = I18n.t('exercises.submit.too_late') + end + end + + if failed_users.size == responses.size # all submissions failed + messages[:danger] = I18n.t('exercises.submit.failure') + elsif failed_users.size.positive? # at least one submission failed + messages[:warning] = [[messages[:warning]], I18n.t('exercises.submit.warning_not_for_all_users_submitted', user: failed_users.join(', '))].join('

') + messages[:warning] = "#{messages[:warning]}\n\n#{I18n.t('exercises.submit.warning_not_for_all_users_submitted', user: failed_users.join(', '))}".strip + else + messages.each do |type, message_text| + flash.now[type] = message_text + flash.keep(type) + end + return finalize + end + + respond_to do |format| + format.html { redirect_to(implement_exercise_path(@submission.exercise), **messages) } + format.json { render(json: messages) } # We must not change the HTTP status code here, since otherwise the custom message is not displayed. + end + end + def retrieve_message_from_output(data, stream) parsed = JSON.parse(data) if parsed.instance_of?(Hash) && parsed.key?('cmd') diff --git a/config/locales/de.yml b/config/locales/de.yml index d6f12fcae..40f229985 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -553,7 +553,7 @@ de: submit: failure: Die Bewertung wurde erfolgreich durchgeführt, aber beim Übermitteln Ihrer Punktzahl ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut. too_late: Ihre Abgabe wurde erfolgreich gespeichert, ging jedoch nach der Abgabefrist ein, sodass nur %{score_sent} Punkte übertragen wurden. - full_score: Herzlichen Glückwunsch! Sie haben die maximale Punktzahl für diese Aufgabe erreicht. Klicken Sie hier, um die Aufgabe abzuschließen. + full_score: Herzlichen Glückwunsch! Sie haben die maximale Punktzahl für diese Aufgabe erreicht. Klicken Sie hier, um die Aufgabe jetzt abzuschließen. full_score_redirect_to_rfc: Herzlichen Glückwunsch! Sie haben die maximale Punktzahl für diese Aufgabe an den Kurs übertragen. Ein anderer Teilnehmer hat eine Frage zu der von Ihnen gelösten Aufgabe. Er würde sich sicherlich sehr über ihre Hilfe und Kommentare freuen. full_score_redirect_to_own_rfc: Herzlichen Glückwunsch! Sie haben die maximale Punktzahl für diese Aufgabe an den Kurs übertragen. Ihre Frage ist damit wahrscheinlich gelöst? Falls ja, fügen Sie doch den entscheidenden Kniff als Antwort hinzu und markieren die Frage als gelöst, bevor sie das Fenster schließen. warning_not_for_all_users_submitted: "Die Punkteübertragung war nur teilweise erfolgreich. Die Punkte konnten nicht für %{user} übertragen werden. Diese Person(en) sollte die Aufgabe über die e-Learning Platform erneut öffnen und anschließend die Punkte selbst übermitteln." diff --git a/config/locales/en.yml b/config/locales/en.yml index 8dc37e648..5658d059e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -552,8 +552,8 @@ en: finishing_rate: Finishing Rate submit: failure: The scoring was performed successfully but an error occurred while transmitting your score. Please try again later. - too_late: Your submission was saved successfully but was received after the deadline passed so that only %{score_sent} points were transmitted. - full_score: Congratulations! You have achieved the highest possible score for this exercise. Click here to complete the exercise. + too_late: Your submission was saved successfully but was received after the deadline, so that only %{score_sent} points were transmitted. + full_score: Congratulations! You have achieved the highest possible score for this exercise. Please click here to finish the exercise now. full_score_redirect_to_rfc: Congratulations! You achieved and submitted the highest possible score for this exercise. Another participant has a question concerning the exercise you just solved. Your help and comments will be greatly appreciated! full_score_redirect_to_own_rfc: Congratulations! You achieved and submitted the highest possible score for this exercise. Your question concerning the exercise is solved? If so, please share the essential insight with your fellows and mark the question as solved, before you close this window! warning_not_for_all_users_submitted: "The transmission of points was only partially successful. The score was not transmitted for %{user}. The user(s) should reopen the exercise via the e-learning platform and then try to submit the points themselves." @@ -868,7 +868,7 @@ en: failure: Invalid email or password. success: Successfully signed in. create_through_lti: - session_with_outcome: 'By clicking on "Score", your points will automatically be added to your progress.' + session_with_outcome: 'By clicking on "Score", your points will be added automatically to your progress.' session_without_outcome: 'This is a practice session. Your grade will not be transmitted to %{consumer}.' destroy: link: Sign out diff --git a/spec/features/score_spec.rb b/spec/features/score_spec.rb index 73c6fcf33..dd7b0d7a1 100644 --- a/spec/features/score_spec.rb +++ b/spec/features/score_spec.rb @@ -54,7 +54,7 @@ visit(implement_exercise_path(exercise)) allow(Submission).to receive(:find).and_return(submission) allow(submission).to receive_messages(calculate_score: scoring_response, normalized_score:) - allow_any_instance_of(SubmissionsController).to receive(:send_score).and_return(status:, score_sent: score) + allow_any_instance_of(SubmissionsController).to receive(:send_scores).and_return(status:, score_sent: score) click_button(I18n.t('exercises.editor.score')) end @@ -111,7 +111,7 @@ end it 'does not send scores' do - expect_any_instance_of(SubmissionsController).not_to receive(:send_score) + expect_any_instance_of(SubmissionsController).not_to receive(:send_scores) end it 'shows execution environments full notification' do