destroy LORs when a quiz changes from an assignment
closes OUT-4286 flag=none test-plan: - create a question & question bank with an outcome aligned to it - align the question bank to a new quiz and publish the quiz - take the quiz as a student - verify you have a learning outcome result record for the student - edit the quiz type to be a "practice quiz" - verify the learning outcome result was soft deleted - verify the result doesn't appear in the SLMGB - change the quiz type back to assignment - verify the result appears in the SLMGB Change-Id: Ia17360a1ac4508590a19154e824f60194972eff6 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/263504 Product-Review: Augusto Callejas <acallejas@instructure.com> Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> QA-Review: Brian Watson <bwatson@instructure.com> Reviewed-by: Augusto Callejas <acallejas@instructure.com>
This commit is contained in:
parent
b4eede0022
commit
9ffa3b5452
|
@ -75,7 +75,10 @@ class Quizzes::Quiz < ActiveRecord::Base
|
|||
after_save :clear_availability_cache
|
||||
after_save :touch_context
|
||||
after_save :regrade_if_published
|
||||
|
||||
# We currently only create LORs for quizzes that are assignments. If we change the quiz_type,
|
||||
# we should destroy or restore the results appropriately
|
||||
after_save :destroy_learning_outcome_results, if: -> { saved_change_to_quiz_type?(from: 'assignment') }
|
||||
after_save :restore_learning_outcome_results, if: -> { saved_change_to_quiz_type?(to: 'assignment') }
|
||||
serialize :quiz_data
|
||||
|
||||
simply_versioned
|
||||
|
@ -407,6 +410,18 @@ class Quizzes::Quiz < ActiveRecord::Base
|
|||
self.quiz_submissions.each { |s| s.save! }
|
||||
end
|
||||
|
||||
def update_learning_outcome_results(state)
|
||||
LearningOutcomeResult.for_associated_asset(self).update_all(workflow_state: state, updated_at: Time.zone.now)
|
||||
end
|
||||
|
||||
def destroy_learning_outcome_results
|
||||
delay_if_production.update_learning_outcome_results('deleted')
|
||||
end
|
||||
|
||||
def restore_learning_outcome_results
|
||||
delay_if_production.update_learning_outcome_results('active')
|
||||
end
|
||||
|
||||
def destroy_related_submissions
|
||||
self.quiz_submissions.each do |qs|
|
||||
submission = qs.submission
|
||||
|
|
|
@ -200,7 +200,7 @@ module Factories
|
|||
"id"=>2159
|
||||
}
|
||||
],
|
||||
"question_text"=>"<p>there's no such thing as a _____ question</p>",
|
||||
"question_text"=>"<p>there's no such thing as a _____ question</p>",
|
||||
"id" => 1
|
||||
}.with_indifferent_access
|
||||
end
|
||||
|
@ -472,4 +472,39 @@ module Factories
|
|||
@quiz.save!
|
||||
@quiz
|
||||
end
|
||||
|
||||
def question_data(reset=false, data={})
|
||||
@qdc = reset || !@qdc ? 1 : @qdc + 1
|
||||
{
|
||||
:name => "question #{@qdc}", :points_possible => 1, 'question_type' => 'multiple_choice_question', 'answers' =>
|
||||
[{'answer_text' => '1', 'answer_weight' => '100'}, {'answer_text' => '2'}, {'answer_text' => '3'}, {'answer_text' => '4'}]
|
||||
}.merge(data)
|
||||
end
|
||||
|
||||
def find_the_answer_from_a_question(question)
|
||||
question.question_data[:answers].detect{|a| a[:weight] == 100 }[:id]
|
||||
end
|
||||
|
||||
def answer_a_question(question, submission, correct: true)
|
||||
return if question.question_data['answers'] == []
|
||||
|
||||
q_id = question.data[:id]
|
||||
answer = if correct
|
||||
find_the_answer_from_a_question(question)
|
||||
else
|
||||
find_the_answer_from_a_question(question) + 1
|
||||
end
|
||||
submission.submission_data["question_#{q_id}"] = answer
|
||||
end
|
||||
|
||||
def build_course_quiz_questions_and_a_bank(data={}, opts={})
|
||||
scoring_policy = opts[:scoring_policy] || "keep_highest"
|
||||
course_with_student(:active_all => true)
|
||||
@quiz = @course.quizzes.create!(:title => "new quiz", :shuffle_answers => true, :quiz_type => "assignment", scoring_policy: scoring_policy)
|
||||
@q1 = @quiz.quiz_questions.create!(:question_data => question_data(true, data[:q1] || data))
|
||||
@q2 = @quiz.quiz_questions.create!(:question_data => question_data(false, data[:q2] || data))
|
||||
@outcome = @course.created_learning_outcomes.create!(:short_description => 'new outcome')
|
||||
@bank = @q1.assessment_question.assessment_question_bank
|
||||
@outcome.align(@bank, @bank.context, :mastery_score => 0.7)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,39 +21,6 @@
|
|||
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper.rb')
|
||||
|
||||
describe Quizzes::QuizOutcomeResultBuilder do
|
||||
def question_data(reset=false, data={})
|
||||
@qdc = (reset || !@qdc) ? 1 : @qdc + 1
|
||||
{:name => "question #{@qdc}", :points_possible => 1, 'question_type' => 'multiple_choice_question', 'answers' =>
|
||||
[{'answer_text' => '1', 'answer_weight' => '100'}, {'answer_text' => '2'}, {'answer_text' => '3'}, {'answer_text' => '4'}]
|
||||
}.merge(data)
|
||||
end
|
||||
|
||||
def build_course_quiz_questions_and_a_bank(data={}, opts={})
|
||||
scoring_policy = opts[:scoring_policy] || "keep_highest"
|
||||
course_with_student(:active_all => true)
|
||||
@quiz = @course.quizzes.create!(:title => "new quiz", :shuffle_answers => true, :quiz_type => "assignment", scoring_policy: scoring_policy)
|
||||
@q1 = @quiz.quiz_questions.create!(:question_data => question_data(true, data[:q1] || data))
|
||||
@q2 = @quiz.quiz_questions.create!(:question_data => question_data(false, data[:q2] || data))
|
||||
@outcome = @course.created_learning_outcomes.create!(:short_description => 'new outcome')
|
||||
@bank = @q1.assessment_question.assessment_question_bank
|
||||
@outcome.align(@bank, @bank.context, :mastery_score => 0.7)
|
||||
end
|
||||
|
||||
def find_the_answer_from_a_question(question)
|
||||
question.question_data[:answers].detect{|a| a[:weight] == 100 }[:id]
|
||||
end
|
||||
|
||||
def answer_a_question(question, submission, correct: true)
|
||||
return if question.question_data['answers'] == []
|
||||
q_id = question.data[:id]
|
||||
answer = if correct
|
||||
find_the_answer_from_a_question(question)
|
||||
else
|
||||
find_the_answer_from_a_question(question) + 1
|
||||
end
|
||||
submission.submission_data["question_#{q_id}"] = answer
|
||||
end
|
||||
|
||||
describe "quiz level learning outcome results" do
|
||||
before :once do
|
||||
build_course_quiz_questions_and_a_bank
|
||||
|
@ -139,7 +106,7 @@ describe Quizzes::QuizOutcomeResultBuilder do
|
|||
Quizzes::SubmissionGrader.new(@sub).grade_submission
|
||||
@outcome.reload
|
||||
@outcome2.reload
|
||||
@quiz_results = LearningOutcomeResult.where(user_id: @user).to_a
|
||||
@quiz_results = LearningOutcomeResult.where(user_id: @user).sort_by(&:learning_outcome_id).to_a
|
||||
@question_results = @quiz_results.map(&:learning_outcome_question_results)
|
||||
end
|
||||
it "has valid bank data" do
|
||||
|
|
|
@ -715,6 +715,35 @@ describe Quizzes::Quiz do
|
|||
expect(possible).to eq 9.9
|
||||
end
|
||||
|
||||
describe "learning outcome results" do
|
||||
before :once do
|
||||
build_course_quiz_questions_and_a_bank
|
||||
@quiz.generate_quiz_data(persist: true)
|
||||
@sub = @quiz.generate_submission(@user)
|
||||
@sub.submission_data = {}
|
||||
answer_a_question(@q1, @sub)
|
||||
answer_a_question(@q2, @sub, correct: false)
|
||||
Quizzes::SubmissionGrader.new(@sub).grade_submission
|
||||
@quiz.reload
|
||||
end
|
||||
|
||||
it "should destroy results if the quiz_type becomes practice_quiz" do
|
||||
@quiz.quiz_type = "practice_quiz"
|
||||
expect {
|
||||
@quiz.save!
|
||||
}.to change { LearningOutcomeResult.active.count }.by(-1)
|
||||
end
|
||||
|
||||
it "should restore results if the quiz_type changes from practice_quiz" do
|
||||
@quiz.quiz_type = "practice_quiz"
|
||||
@quiz.save!
|
||||
@quiz.quiz_type = "assignment"
|
||||
expect {
|
||||
@quiz.save!
|
||||
}.to change { LearningOutcomeResult.active.count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#generate_submission" do
|
||||
it "should generate a valid submission for a given user" do
|
||||
u = User.create!(:name => "some user")
|
||||
|
|
Loading…
Reference in New Issue