add live events for outcome_proficiency

closes OUT-3867
flag=none

test-plan:
- ensure live events are running locally (see live_events.md)
- verify that when making changes (including soft deleting) or
 creating an outcome proficiency that live events are emitted
- verify that ratings information is included in the proficiency payload

(cherry picked from commit 0f0edc8cbe)

Change-Id: Iee0a98666354fc6e375757d63a1bbf22cdff973e
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/245081
Reviewed-by: Michael Brewer-Davis <mbd@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Michael Brewer-Davis <mbd@instructure.com>
Product-Review: Michael Brewer-Davis <mbd@instructure.com>
This commit is contained in:
Pat Renner 2020-08-11 14:53:29 -05:00
parent 4403eb3c2a
commit 618899e064
6 changed files with 114 additions and 2 deletions

View File

@ -21,6 +21,10 @@ class OutcomeProficiency < ApplicationRecord
include Canvas::SoftDeletable
self.ignored_columns = %i[account_id]
def self.emit_live_events_on_any_update?
true
end
has_many :outcome_proficiency_ratings, -> { order 'points DESC, id ASC' },
dependent: :destroy, inverse_of: :outcome_proficiency, autosave: true
belongs_to :context, polymorphic: %i[account], required: true

View File

@ -45,12 +45,13 @@ class LiveEventsObserver < ActiveRecord::Observer
:learning_outcome_result,
:learning_outcome,
:learning_outcome_group,
:sis_batch
:sis_batch,
:outcome_proficiency
NOP_UPDATE_FIELDS = [ "updated_at", "sis_batch_id" ].freeze
def after_update(obj)
changes = obj.saved_changes
return nil if changes.except(*NOP_UPDATE_FIELDS).empty?
return nil unless changes.except(*NOP_UPDATE_FIELDS).any? || obj.class.try(:emit_live_events_on_any_update?)
obj.class.connection.after_transaction_commit do
Canvas::LiveEventsCallbacks.after_update(obj, changes)

View File

@ -844,4 +844,36 @@ module Canvas::LiveEvents
def self.sis_batch_updated(batch)
post_event_stringified('sis_batch_updated', sis_batch_payload(batch))
end
def self.outcome_proficiency_created(proficiency)
post_event_stringified('outcome_proficiency_created', get_outcome_proficiency_data(proficiency))
end
def self.outcome_proficiency_updated(proficiency)
post_event_stringified('outcome_proficiency_updated', get_outcome_proficiency_data(proficiency).merge(updated_at: proficiency.updated_at))
end
def self.get_outcome_proficiency_data(proficiency)
ratings = proficiency.outcome_proficiency_ratings.map do |rating|
get_outcome_proficiency_rating_data(rating)
end
{
outcome_proficiency_id: proficiency.id,
context_type: proficiency.context_type,
context_id: proficiency.context_id,
workflow_state: proficiency.workflow_state,
outcome_proficiency_ratings: ratings
}
end
def self.get_outcome_proficiency_rating_data(rating)
{
outcome_proficiency_rating_id: rating.id,
description: rating.description,
points: rating.points,
mastery: rating.mastery,
color: rating.color,
workflow_state: rating.workflow_state
}
end
end

View File

@ -81,6 +81,8 @@ module Canvas::LiveEventsCallbacks
Canvas::LiveEvents.learning_outcome_group_created(obj)
when SisBatch
Canvas::LiveEvents.sis_batch_created(obj)
when OutcomeProficiency
Canvas::LiveEvents.outcome_proficiency_created(obj)
end
end
@ -177,6 +179,8 @@ module Canvas::LiveEventsCallbacks
if changes[:workflow_state].present?
Canvas::LiveEvents.sis_batch_updated(obj)
end
when OutcomeProficiency
Canvas::LiveEvents.outcome_proficiency_updated(obj)
end
end

View File

@ -1655,6 +1655,56 @@ describe Canvas::LiveEvents do
end
end
describe 'outcome_proficiency' do
before do
@account = account_model
@rating1 = OutcomeProficiencyRating.new(description: 'best', points: 10, mastery: true, color: '00ff00')
rating2 = OutcomeProficiencyRating.new(description: 'worst', points: 0, mastery: false, color: 'ff0000')
@proficiency = OutcomeProficiency.create!(outcome_proficiency_ratings: [@rating1, rating2], context: @account)
end
def rating_event(rating)
{
outcome_proficiency_rating_id: rating.id.to_s,
description: rating.description,
points: rating.points,
mastery: rating.mastery,
color: rating.color,
workflow_state: rating.workflow_state
}
end
context 'created' do
it 'should trigger an outcome_proficiency_created live event' do
expect_event('outcome_proficiency_created', {
outcome_proficiency_id: @proficiency.id.to_s,
context_id: @proficiency.context_id.to_s,
context_type: @proficiency.context_type,
workflow_state: @proficiency.workflow_state,
outcome_proficiency_ratings: @proficiency.outcome_proficiency_ratings.map {|rating| rating_event(rating)}
}.compact).once
Canvas::LiveEvents.outcome_proficiency_created(@proficiency)
end
end
context 'updated' do
it 'should trigger an outcome_proficiency_updated live event' do
@proficiency.outcome_proficiency_ratings = [@rating1]
@proficiency.save!
expect_event('outcome_proficiency_updated', {
outcome_proficiency_id: @proficiency.id.to_s,
context_id: @proficiency.context_id.to_s,
context_type: @proficiency.context_type,
workflow_state: @proficiency.workflow_state,
updated_at: @proficiency.updated_at,
outcome_proficiency_ratings: @proficiency.outcome_proficiency_ratings.map {|rating| rating_event(rating)}
}.compact).once
Canvas::LiveEvents.outcome_proficiency_updated(@proficiency)
end
end
end
describe 'grade_override' do
it 'does not send event when score does not change' do
course_model

View File

@ -508,4 +508,25 @@ describe LiveEventsObserver do
link.destroy!
end
end
describe "outcome_proficiency" do
it "posts create events" do
expect(Canvas::LiveEvents).to receive(:outcome_proficiency_created).once
outcome_proficiency_model(account_model)
end
it "posts updated events when ratings are changed" do
proficiency = outcome_proficiency_model(account_model)
expect(Canvas::LiveEvents).to receive(:outcome_proficiency_updated).once
rating = OutcomeProficiencyRating.new(description: 'new_rating', points: 5, mastery: true, color: 'ff0000')
proficiency.outcome_proficiency_ratings = [rating]
proficiency.save!
end
it "posts updated events when proficiencies are destroyed" do
proficiency = outcome_proficiency_model(account_model)
expect(Canvas::LiveEvents).to receive(:outcome_proficiency_updated).once
proficiency.destroy
end
end
end