speedgrader: support multiple quiz attempts

fixes CNVS-1614

Test plan:
  * make a quiz that allows multiple attempts
  * make multiple attempts on the quiz with a student
  * view the quiz in speedgrader
  * you should be able to view any of the attempts (just like
    assignments with multiple submissions)

Change-Id: Ib10a4e0579538cf0d92247393c039a78b155474b
Reviewed-on: https://gerrit.instructure.com/24170
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Simon Williams <simon@instructure.com>
QA-Review: Amber Taniuchi <amber@instructure.com>
Product-Review: Cameron Matheson <cameron@instructure.com>
This commit is contained in:
Cameron Matheson 2013-09-06 17:08:58 -06:00
parent 0cc9bcf1be
commit 8a069215d8
6 changed files with 77 additions and 19 deletions

View File

@ -153,9 +153,7 @@ class SubmissionsController < ApplicationController
respond_to do |format|
json_handled = false
if params[:preview]
# this if was put it by ryan, it makes it so if they pass a ?preview=true&version=2 in the url that it will load the second version in the
# submission_history of that submission
if params[:version]
if params[:version] && !@assignment.quiz
@submission = @submission.submission_history[params[:version].to_i]
end
@ -163,7 +161,16 @@ class SubmissionsController < ApplicationController
if @assignment.quiz && @context.is_a?(Course) && @context.user_is_student?(@current_user) && !@context.user_is_instructor?(@current_user)
format.html { redirect_to(named_context_url(@context, :context_quiz_url, @assignment.quiz.id, :headless => 1)) }
elsif @submission.submission_type == "online_quiz" && @submission.quiz_submission_version
format.html { redirect_to(named_context_url(@context, :context_quiz_history_url, @assignment.quiz.id, :user_id => @submission.user_id, :headless => 1, :version => @submission.quiz_submission_version)) }
format.html {
quiz_params = {
headless: 1,
user_id: @submission.user_id,
version: params[:version] || @submission.quiz_submission_version
}
redirect_to named_context_url(@context,
:context_quiz_history_url,
@assignment.quiz.id, quiz_params)
}
else
format.html { render :action => "show_preview" }
end

View File

@ -1148,7 +1148,7 @@ class Assignment < ActiveRecord::Base
:methods => [:scribdable?, :scribd_doc, :submission_history, :late],
:only => submission_fields
)
if json['submission_history']
if json['submission_history'] && quiz.nil?
json['submission_history'].map! do |version|
version.as_json(
:include => {
@ -1167,6 +1167,18 @@ class Assignment < ActiveRecord::Base
end
end
end
elsif quiz
quiz_submission_versions = sub.quiz_submission.versions.reverse
json['submission_history'] = quiz_submission_versions.map do |v|
qs = v.model
{submission: {
grade: qs.score,
show_grade_in_dropdown: true,
submitted_at: qs.finished_at,
late: qs.overdue?,
version: v.number,
}}
end
end
json
}

View File

@ -537,7 +537,6 @@ class Quiz < ActiveRecord::Base
# Generates a submission for the specified user on this quiz, based
# on the SAVED version of the quiz. Does not consider permissions.
def generate_submission(user, preview=false)
submission = nil
submission = self.find_or_create_submission(user, preview)
submission.retake
submission.attempt = (submission.attempt + 1) rescue 1

View File

@ -17,6 +17,7 @@
*/
define([
'underscore',
'INST' /* INST */,
'i18n!gradebook',
'jquery' /* $ */,
@ -47,7 +48,7 @@ define([
'vendor/scribd.view' /* scribd */,
'vendor/spin' /* new Spinner */,
'vendor/ui.selectmenu' /* /\.selectmenu/ */
], function(INST, I18n, $, userSettings, htmlEscape, rubricAssessment, turnitinInfoTemplate, turnitinScoreTemplate) {
], function(_, INST, I18n, $, userSettings, htmlEscape, rubricAssessment, turnitinInfoTemplate, turnitinScoreTemplate) {
// fire off the request to get the jsonData
window.jsonData = {};
@ -1176,26 +1177,31 @@ define([
refreshSubmissionsToView: function(){
var innerHTML = "";
if (this.currentStudent.submission.submission_history.length > 0) {
submissionToSelect = this.currentStudent.submission.submission_history[this.currentStudent.submission.submission_history.length - 1].submission;
var s = this.currentStudent.submission;
var submissionHistory;
$.each(this.currentStudent.submission.submission_history, function(i, s){
s = s.submission;
var submittedAt = s.submitted_at && $.parseFromISO(s.submitted_at),
late = s['late'];
if ((submissionHistory = s.submission_history).length > 0) {
var submissionToSelect = _(submissionHistory).last();
innerHTML += "<option " + (late ? "class='late'" : "") + " value='" + i + "' " +
(s == submissionToSelect ? "selected='selected'" : "") + ">" +
_(submissionHistory).each(function(o, i) {
var s = o.submission;
submittedAt = s.submitted_at && $.parseFromISO(s.submitted_at),
late = s.late,
value = s.version || i;
innerHTML += "<option " + (late ? "class='late'" : "") + " value='" + value + "' " +
(o == submissionToSelect ? "selected='selected'" : "") + ">" +
(submittedAt ? submittedAt.datetime_formatted : I18n.t('no_submission_time', 'no submission time')) +
(late ? " " + I18n.t('loud_late', "LATE") : "") +
(s.grade && s.grade_matches_current_submission ? " (" + I18n.t('grade', "grade: %{grade}", {'grade': s.grade}) + ')' : "") +
(s.grade && (s.grade_matches_current_submission || s.show_grade_in_dropdown) ? " (" + I18n.t('grade', "grade: %{grade}", {'grade': s.grade}) + ')' : "") +
"</option>";
});
}
$submission_to_view.html(innerHTML);
//if there are multiple submissions
if (this.currentStudent && this.currentStudent.submission && this.currentStudent.submission.submission_history && this.currentStudent.submission.submission_history.length > 1 ) {
if (submissionHistory.length > 1) {
$multiple_submissions.show();
$single_submission.hide();
}

View File

@ -251,7 +251,7 @@ describe "course people" do
student_in_course :course => @course
e = course_with_observer(:course => @course, :role_name => "custom observer")
expect_new_page_load { go_to_people_page }
go_to_people_page
use_link_dialog(@observer) do
select_from_auto_complete(@student.name, 'student_input')

View File

@ -46,7 +46,10 @@ describe "speed grader" do
@assignment.save!
@quiz = Quiz.find_by_assignment_id(@assignment.id)
@quiz.update_attribute(:anonymous_submissions, true)
student_submission
student_in_course
qs = @quiz.generate_submission(@student)
qs.start_grading
qs.complete
get "/courses/#{@course.id}/gradebook/speed_grader?assignment_id=#{@assignment.id}"
keep_trying_until {
fj('#this_student_has_a_submission').should be_displayed
@ -115,6 +118,37 @@ describe "speed grader" do
end
end
it "lets you view previous quiz submissions" do
@assignment.update_attributes! points_possible: 10,
submission_types: 'online_quiz',
title: "Quiz"
@quiz = Quiz.find_by_assignment_id(@assignment.id)
student_in_course
2.times do |i|
qs = @quiz.generate_submission(@student)
opts = i == 0 ? {finished_at: Date.today - 7} : {}
qs.grade_submission(opts)
end
get "/courses/#{@course.id}/gradebook/speed_grader?assignment_id=#{@assignment.id}"
submission_dropdown = f("#submission_to_view")
submission_dropdown.should be_displayed
submissions = submission_dropdown.find_elements(:css, "option")
submissions.size.should == 2
submissions.each do |s|
s.click
submission_date = s.text
in_frame('speedgrader_iframe') do
wait_for_ajaximations
f('.quiz-submission').text.should include submission_date
end
end
end
it "should display discussion entries for only one student" do
#make assignment a discussion assignment
@assignment.points_possible = 5