diff --git a/app/observers/live_events_observer.rb b/app/observers/live_events_observer.rb index eab4298248bb0..9486004a48860 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", "MasterCourses::MasterTemplate", "MasterCourses::MasterMigration", "MasterCourses::ChildSubscription", diff --git a/lib/canvas/live_events.rb b/lib/canvas/live_events.rb index b3c4c6592bdca..28756451c6881 100644 --- a/lib/canvas/live_events.rb +++ b/lib/canvas/live_events.rb @@ -337,6 +337,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 e531b773edbbc..93587087cfae3 100644 --- a/lib/canvas/live_events_callbacks.rb +++ b/lib/canvas/live_events_callbacks.rb @@ -46,8 +46,19 @@ 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 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 @@ -130,13 +141,24 @@ def self.after_update(obj, changes) when GroupMembership Canvas::LiveEvents.group_membership_updated(obj) when WikiPage - if changes["title"] || changes["body"] + if changes["title"] || changes["body"] || changes["workflow_state"] Canvas::LiveEvents.wiki_page_updated(obj, 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 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 be5205990fa9b..b87c1c572fbc7 100644 --- a/spec/lib/canvas/live_events_spec.rb +++ b/spec/lib/canvas/live_events_spec.rb @@ -1317,6 +1317,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 e69696ba42858..cd9f9e19b2117 100644 --- a/spec/observers/live_events_observer_spec.rb +++ b/spec/observers/live_events_observer_spec.rb @@ -106,6 +106,18 @@ expect(Canvas::LiveEvents).to receive(:wiki_page_deleted).once @page.destroy_permanently! end + + it "posts update event when page is published" do + wiki_page_model(workflow_state: "unpublished") + expect(Canvas::LiveEvents).to receive(:wiki_page_updated).with(@page, nil, nil).once + @page.publish! + end + + it "posts update event when page is unpublished" do + wiki_page_model + expect(Canvas::LiveEvents).to receive(:wiki_page_updated).with(@page, nil, nil).once + @page.unpublish! + end end describe "attachment" do @@ -247,6 +259,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 @@ -433,6 +485,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