diff --git a/app/observers/live_events_observer.rb b/app/observers/live_events_observer.rb index 2c78326519f6b..65b3a7af639e8 100644 --- a/app/observers/live_events_observer.rb +++ b/app/observers/live_events_observer.rb @@ -53,6 +53,8 @@ class LiveEventsObserver < ActiveRecord::Observer :user_account_association, :user, :wiki_page, + "Quizzes::Quiz", + "Quizzes::QuizQuestion", "Lti::ResourceLink", "MasterCourses::MasterTemplate", "MasterCourses::MasterMigration", diff --git a/lib/canvas/live_events.rb b/lib/canvas/live_events.rb index 7c1bfba8189bf..9050404b99b33 100644 --- a/lib/canvas/live_events.rb +++ b/lib/canvas/live_events.rb @@ -345,6 +345,34 @@ def self.assignment_updated(assignment) post_event_stringified("assignment_updated", get_assignment_data(assignment)) end + def self.get_quiz_data(quiz) + { + assignment_group_id: quiz.global_assignment_group_id, + context_id: quiz.global_context_id, + context_type: "Course", + context_uuid: quiz.context.uuid, + description: LiveEvents.truncate(quiz.description), + due_at: quiz.due_at, + lock_at: quiz.lock_at, + points_possible: quiz.points_possible, + quiz_id: quiz.global_id, + quiz_type: quiz.quiz_type, + submission_types: "online_quiz", + title: LiveEvents.truncate(quiz.title), + unlock_at: quiz.unlock_at, + updated_at: quiz.updated_at, + workflow_state: quiz.workflow_state + } + end + + def self.quiz_created(quiz) + post_event_stringified("quiz_created", get_quiz_data(quiz)) + end + + def self.quiz_updated(quiz) + post_event_stringified("quiz_updated", get_quiz_data(quiz)) + end + def self.assignment_group_created(assignment_group) post_event_stringified("assignment_group_created", get_assignment_group_data(assignment_group)) end diff --git a/lib/canvas/live_events_callbacks.rb b/lib/canvas/live_events_callbacks.rb index b7c5c400582ce..f368afde1ff2e 100644 --- a/lib/canvas/live_events_callbacks.rb +++ b/lib/canvas/live_events_callbacks.rb @@ -46,10 +46,21 @@ def self.after_create(obj) Canvas::LiveEvents.group_membership_created(obj) when WikiPage Canvas::LiveEvents.wiki_page_created(obj) + when Quizzes::QuizQuestion + quiz = obj.quiz + if quiz + if quiz.assignment + Canvas::LiveEvents.assignment_updated(quiz.assignment) + else + Canvas::LiveEvents.quiz_updated(quiz) + end + end when Lti::ResourceLink Canvas::LiveEvents.lti_resource_link_created(obj) when Assignment Canvas::LiveEvents.assignment_created(obj) + when Quizzes::Quiz + Canvas::LiveEvents.quiz_created(obj) if obj.assignment_id.nil? when AssignmentGroup Canvas::LiveEvents.assignment_group_created(obj) when AssignmentOverride @@ -143,10 +154,21 @@ def self.after_update(obj, changes) changes["title"]&.first, changes["body"]&.first) end + when Quizzes::QuizQuestion + quiz = obj.quiz + if quiz + if quiz.assignment + Canvas::LiveEvents.assignment_updated(quiz.assignment) + else + Canvas::LiveEvents.quiz_updated(quiz) + end + end when Lti::ResourceLink Canvas::LiveEvents.lti_resource_link_updated(obj) when Assignment Canvas::LiveEvents.assignment_updated(obj) + when Quizzes::Quiz + Canvas::LiveEvents.quiz_updated(obj) if obj.assignment_id.nil? when AssignmentGroup Canvas::LiveEvents.assignment_group_updated(obj) when AssignmentOverride diff --git a/spec/lib/canvas/live_events_spec.rb b/spec/lib/canvas/live_events_spec.rb index 7cecb9225d32a..53f5a57b4464e 100644 --- a/spec/lib/canvas/live_events_spec.rb +++ b/spec/lib/canvas/live_events_spec.rb @@ -1376,6 +1376,59 @@ def wiki_page_updated end end + describe ".quiz_created" do + before do + course_factory + @quiz = @course.quizzes.create!( + title: "Practice Quiz", + quiz_type: "practice_quiz", + workflow_state: "available" + ) + end + + it "triggers quiz_created event with quiz details" do + expect_event("quiz_created", + hash_including({ + quiz_id: @quiz.global_id.to_s, + quiz_type: "practice_quiz", + context_id: @course.global_id.to_s, + context_type: "Course", + context_uuid: @course.uuid, + workflow_state: @quiz.workflow_state, + title: @quiz.title, + submission_types: "online_quiz" + })).once + + Canvas::LiveEvents.quiz_created(@quiz) + end + end + + describe ".quiz_updated" do + before do + course_factory + @quiz = @course.quizzes.create!( + title: "Practice Quiz", + quiz_type: "practice_quiz", + workflow_state: "available" + ) + end + + it "triggers quiz_updated event with quiz details" do + expect_event("quiz_updated", + hash_including({ + quiz_id: @quiz.global_id.to_s, + quiz_type: "practice_quiz", + context_id: @course.global_id.to_s, + context_type: "Course", + workflow_state: @quiz.workflow_state, + title: @quiz.title, + submission_types: "online_quiz" + })).once + + Canvas::LiveEvents.quiz_updated(@quiz) + end + end + describe "assignment_group_updated" do let(:course) do course_with_student_submissions diff --git a/spec/observers/live_events_observer_spec.rb b/spec/observers/live_events_observer_spec.rb index 5335e348cade5..b9b0dadfee2fb 100644 --- a/spec/observers/live_events_observer_spec.rb +++ b/spec/observers/live_events_observer_spec.rb @@ -325,6 +325,46 @@ end end + describe "quiz" do + before { course_factory } + + it "posts quiz_created when creating a practice_quiz" do + expect(Canvas::LiveEvents).to receive(:quiz_created).once + @course.quizzes.create!(title: "Practice Quiz", quiz_type: "practice_quiz") + end + + it "posts quiz_created when creating an ungraded survey" do + expect(Canvas::LiveEvents).to receive(:quiz_created).once + @course.quizzes.create!(title: "Survey", quiz_type: "survey") + end + + it "posts quiz_updated when updating a practice_quiz" do + quiz = @course.quizzes.create!(title: "Practice Quiz", quiz_type: "practice_quiz") + expect(Canvas::LiveEvents).to receive(:quiz_updated).once + quiz.title = "Updated Title" + quiz.save! + end + + it "posts quiz_updated when updating an ungraded survey" do + quiz = @course.quizzes.create!(title: "Survey", quiz_type: "survey") + expect(Canvas::LiveEvents).to receive(:quiz_updated).once + quiz.title = "Updated Title" + quiz.save! + end + + it "does not post quiz_created or quiz_updated for a graded quiz" do + expect(Canvas::LiveEvents).not_to receive(:quiz_created) + expect(Canvas::LiveEvents).not_to receive(:quiz_updated) + @course.quizzes.create!(title: "Graded Quiz", quiz_type: "assignment") + end + + it "does not post quiz_created or quiz_updated for a graded survey" do + expect(Canvas::LiveEvents).not_to receive(:quiz_created) + expect(Canvas::LiveEvents).not_to receive(:quiz_updated) + @course.quizzes.create!(title: "Graded Survey", quiz_type: "graded_survey") + end + end + describe "assignment overrides" do it "posts create events" do expect(Canvas::LiveEvents).to receive(:assignment_override_created).once @@ -511,6 +551,57 @@ def enable_quizzes_next(course) end end + describe "quiz_question" do + context "quiz with assignment" do + it "posts assignment_updated when a question is created" do + allow(Canvas::LiveEvents).to receive(:assignment_updated) + quiz_model(quiz_type: "assignment") + assignment = @quiz.reload.assignment + expect(Canvas::LiveEvents).to receive(:assignment_updated).with(assignment) + @quiz.quiz_questions.create!(question_data: { name: "Q1", question_type: "true_false_question", points_possible: 1 }) + end + + it "posts assignment_updated when a question is updated" do + allow(Canvas::LiveEvents).to receive(:assignment_updated) + quiz_model(quiz_type: "assignment") + question = @quiz.quiz_questions.create!(question_data: { name: "Q1", question_type: "true_false_question", points_possible: 1 }) + assignment = @quiz.reload.assignment + expect(Canvas::LiveEvents).to receive(:assignment_updated).with(assignment) + question.update!(question_data: { name: "Q1 updated", question_type: "true_false_question", points_possible: 1 }) + end + end + + context "quiz without assignment (practice_quiz)" do + before { course_factory } + + it "posts quiz_updated when a question is created" do + allow(Canvas::LiveEvents).to receive(:quiz_updated) + quiz = @course.quizzes.create!(title: "Practice Quiz", quiz_type: "practice_quiz") + expect(Canvas::LiveEvents).to receive(:quiz_updated).with(quiz) + quiz.quiz_questions.create!(question_data: { name: "Q1", question_type: "true_false_question", points_possible: 1 }) + end + + it "posts quiz_updated when a question is updated" do + allow(Canvas::LiveEvents).to receive(:quiz_updated) + quiz = @course.quizzes.create!(title: "Practice Quiz", quiz_type: "practice_quiz") + question = quiz.quiz_questions.create!(question_data: { name: "Q1", question_type: "true_false_question", points_possible: 1 }) + expect(Canvas::LiveEvents).to receive(:quiz_updated).with(quiz) + question.update!(question_data: { name: "Q1 updated", question_type: "true_false_question", points_possible: 1 }) + end + end + + context "quiz without assignment (survey)" do + before { course_factory } + + it "posts quiz_updated when a question is created" do + allow(Canvas::LiveEvents).to receive(:quiz_updated) + quiz = @course.quizzes.create!(title: "Survey", quiz_type: "survey") + expect(Canvas::LiveEvents).to receive(:quiz_updated).with(quiz) + quiz.quiz_questions.create!(question_data: { name: "Q1", question_type: "true_false_question", points_possible: 1 }) + end + end + end + describe "content_migration_completed" do it "posts update events" do expect(Canvas::LiveEvents).to receive(:content_migration_completed).once