Fixes event rebuild tools, optimization for event_aggregator
This should make event rebuilding equivalent with versions rebuilding in the most substantial ways (doesn't cause bug in quiz showing with unsupported question types). Refs CNVS-20069 Test Plan: - contact Ryan for DB migration script - Run custom migration - Delete a single quiz submission with raw SQL query - Rebuild that quiz_submission from the events log - Confirm that the quiz is viewable, contains the same questions, and is properly graded. Change-Id: Ia66a3f15e86e5dffd8ba2eff1ce5ff1ce663ad9b Reviewed-on: https://gerrit.instructure.com/55164 Tested-by: Cameron Sutter <csutter@instructure.com> Reviewed-by: Brian Finney <bfinney@instructure.com> QA-Review: Robert Lamb <rlamb@instructure.com> Product-Review: Ryan Taylor <rtaylor@instructure.com>
This commit is contained in:
parent
46f31b42fb
commit
6ebff05c4a
|
@ -85,7 +85,7 @@ module Quizzes::LogAuditing
|
|||
def build_submission_data_from_answers(answers)
|
||||
submission_data = {}
|
||||
answers.each do |question_id, answer|
|
||||
question = quiz.quiz_questions.find { |qq| qq.id == question_id }
|
||||
question = quiz.quiz_questions.find { |qq| qq.id == question_id.to_i }
|
||||
question = Quizzes::QuizQuestion.where(id: question_id).first unless question
|
||||
if question.question_data["question_type"] != "text_only_question"
|
||||
serializer = Quizzes::QuizQuestion::AnswerSerializers.serializer_for(question)
|
||||
|
|
|
@ -114,6 +114,74 @@ module DataFixup::RebuildQuizSubmissionsFromQuizSubmissionEvents
|
|||
qs
|
||||
end
|
||||
|
||||
def self.pick_questions(qs, seen_question_ids)
|
||||
# Parsing all the deets from events can do it though
|
||||
quiz_group_picks = Hash.new {|h, k| h[k] = []}
|
||||
quiz_group_pick_counts = {}
|
||||
picked_questions = qs.quiz.stored_questions.select do |question|
|
||||
if question["entry_type"] == "quiz_group"
|
||||
group_name = question["id"]
|
||||
quiz_group_pick_counts[group_name] = question["pick_count"]
|
||||
matching_questions = question["questions"].select {|q| seen_question_ids.include? q["id"].to_s}
|
||||
matching_questions.each {|q| q["points_possible"] = question["question_points"]}
|
||||
quiz_group_picks[group_name] += matching_questions
|
||||
false
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
quiz_group_picks.each do |k,v|
|
||||
qs.quiz.stored_questions.select {|q| q["id"] == k }.map do |question|
|
||||
question["questions"].shuffle.each do |q|
|
||||
break if v.count == quiz_group_pick_counts[k]
|
||||
q["points_possible"] = question["question_points"]
|
||||
v << q unless v.include? q
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
picked_questions += quiz_group_picks.values.flatten
|
||||
if qs.quiz.question_count != picked_questions.size
|
||||
Rails.logger.error LOG_PREFIX + "#{qs.id} doesn't match it's question count"
|
||||
end
|
||||
picked_questions
|
||||
end
|
||||
|
||||
# Because we can't regenerate quiz data without getting a different set of questions,
|
||||
# we need to select the quiz_questions from the questions we can know the student has
|
||||
# seen.
|
||||
def self.aggregate_quiz_data_from_events(qs, events)
|
||||
question_events = events.select {|e| ["question_answered", "question_viewed", "question_flagged"].include?(e.event_type)}
|
||||
seen_question_ids = []
|
||||
question_events.each do |event|
|
||||
if event.event_type == "question_viewed"
|
||||
seen_question_ids << event.answers
|
||||
else
|
||||
seen_question_ids << event.answers.flatten.map {|h| h["quiz_question_id"]}
|
||||
end
|
||||
end
|
||||
seen_question_ids = seen_question_ids.flatten.uniq
|
||||
|
||||
builder = Quizzes::QuizQuestionBuilder.new({
|
||||
shuffle_answers: qs.quiz.shuffle_answers
|
||||
})
|
||||
|
||||
if seen_question_ids.count > 0
|
||||
picked_questions = pick_questions(qs, seen_question_ids)
|
||||
|
||||
raw_data = builder.shuffle_quiz_data!(picked_questions)
|
||||
raw_data.each_with_index do |question, index|
|
||||
Quizzes::QuizQuestionBuilder.decorate_question_for_submission(question, index)
|
||||
end
|
||||
else
|
||||
submission.quiz_data = begin
|
||||
qs.quiz.stored_questions = nil
|
||||
builder.build_submission_questions(qs.quiz.id, qs.quiz.stored_questions)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.build_new_submission_from_quiz_submission_events(submission)
|
||||
if submission.submission_type != "online_quiz"
|
||||
Rails.logger.warn LOG_PREFIX + "Skipping because this isn't a quiz!\tsubmission_id: #{submission.id}"
|
||||
|
@ -160,14 +228,13 @@ module DataFixup::RebuildQuizSubmissionsFromQuizSubmissionEvents
|
|||
|
||||
# This is sad because assumptions
|
||||
qs.quiz_version = qs.versions.map {|v| v.model.quiz_version}.sort.last
|
||||
qs.quiz_data = aggregate_quiz_data_from_events(qs, events)
|
||||
|
||||
# Set reasonable timestamps
|
||||
qs.created_at = submission.created_at
|
||||
qs.started_at = times.first
|
||||
qs.finished_at = submission.submitted_at
|
||||
|
||||
# Set internal data for grading
|
||||
qs.quiz_data = submission.assignment.quiz.quiz_data
|
||||
qs.submission_data = submission_data_hash
|
||||
qs.save!
|
||||
|
||||
|
|
Loading…
Reference in New Issue