Live events - Attachments

test plan:
  * create attachments by uploading course files
  * update display name of course files
  * delete some course files
  * delete a course wiki page
  * ensure appropriate messages are in the kinesis queue

Change-Id: I3036a3079abef5a5ae3b51b71c325e0fe2cbae05
Reviewed-on: https://gerrit.instructure.com/88703
Reviewed-by: Simon Williams <simon@instructure.com>
QA-Review: Simon Williams <simon@instructure.com>
Tested-by: Jenkins
Reviewed-by: Rob Orton <rob@instructure.com>
Product-Review: Simon Williams <simon@instructure.com>
This commit is contained in:
Simon Gaeremynck 2016-08-25 20:47:37 -06:00 committed by Simon Williams
parent 3f93d55a39
commit af60de97bb
4 changed files with 186 additions and 9 deletions

View File

@ -10,6 +10,7 @@ class LiveEventsObserver < ActiveRecord::Observer
:wiki_page,
:assignment,
:submission,
:attachment,
:user_account_association
def after_update(obj)
@ -26,9 +27,21 @@ class LiveEventsObserver < ActiveRecord::Observer
if obj.title_changed? || obj.body_changed?
Canvas::LiveEvents.wiki_page_updated(obj, obj.title_changed? ? obj.title_was : nil,
obj.body_changed? ? obj.body_was : nil)
elsif obj.workflow_state_changed? && obj.workflow_state == 'deleted'
# Wiki pages are often soft deleted rather than destroyed
Canvas::LiveEvents.wiki_page_deleted(obj)
end
when Assignment
Canvas::LiveEvents.assignment_updated(obj)
when Attachment
if attachment_eligible?(obj)
if obj.display_name_changed?
Canvas::LiveEvents.attachment_updated(obj, obj.display_name_was)
elsif obj.file_state_changed? && obj.file_state == 'deleted'
# Attachments are often soft deleted rather than destroyed
Canvas::LiveEvents.attachment_deleted(obj)
end
end
when Submission
Canvas::LiveEvents.submission_updated(obj)
end
@ -58,16 +71,31 @@ class LiveEventsObserver < ActiveRecord::Observer
Canvas::LiveEvents.submission_created(obj)
when UserAccountAssociation
Canvas::LiveEvents.user_account_association_created(obj)
when Attachment
if attachment_eligible?(obj)
Canvas::LiveEvents.attachment_created(obj)
end
end
end
def after_save(obj)
end
def after_destroy(obj)
case obj
when Attachment
if attachment_eligible?(obj)
Canvas::LiveEvents.attachment_deleted(obj)
end
when WikiPage
Canvas::LiveEvents.wiki_page_deleted(obj)
end
end
private
ELIGIBLE_ATTACHMENT_CONTEXTS = [ 'Course', 'Group', 'User' ].freeze
def attachment_eligible?(attachment)
# We only send live events for attachments that would show up in Files
# sections of Canvas.
ELIGIBLE_ATTACHMENT_CONTEXTS.include?(attachment.context_type) &&
attachment.folder_id.present?
end
end

View File

@ -361,4 +361,52 @@ by `asset_type` and `asset_id`.
| `account_id` | The Canvas id of the account for this association. |
| `created_at` | The time at which this association was created. |
| `updated_at` | The time at which this association was last modified. |
| `roles ` | The roles the user has in the account. |
| `roles` | The roles the user has in the account. |
#### `attachment_created`
| Field | Description |
| ----- | ----------- |
| `user_id` | The Canvas id of the user associated with the attachment. |
| `attachment_id` | The Canvas id of the attachment. |
| `display_name` | The display name of the attachment (possibly truncated). |
| `filename` | The file name of the attachment (possibly truncated). |
| `unlock_at` | The unlock date (attachment is unlocked after this date) |
| `lock_at` | The lock date (attachment is locked after this date) |
| `updated_at` | The time at which this attachment was last modified in any way |
| `context_type` | The type of context the attachment is used in. |
| `context_id` | The id of the context the attachment is used in. |
| `content_type` | The content type of the attachment. |
#### `attachment_updated`
`attachment_updated` events are triggered when an attachment's `display_name` is updated.
| Field | Description |
| ----- | ----------- |
| `user_id` | The Canvas id of the user associated with the attachment. |
| `attachment_id` | The Canvas id of the attachment. |
| `display_name` | The display name of the attachment (possibly truncated). |
| `old_display_name` | The old display name of the attachment (possibly truncated). |
| `filename` | The file name of the attachment (possibly truncated). |
| `unlock_at` | The unlock date (attachment is unlocked after this date) |
| `lock_at` | The lock date (attachment is locked after this date) |
| `updated_at` | The time at which this attachment was last modified in any way |
| `context_type` | The type of context the attachment is used in. |
| `context_id` | The id of the context the attachment is used in. |
| `content_type` | The content type of the attachment. |
#### `attachment_deleted`
| Field | Description |
| ----- | ----------- |
| `user_id` | The Canvas id of the user associated with the attachment. |
| `attachment_id` | The Canvas id of the attachment. |
| `display_name` | The display name of the attachment (possibly truncated). |
| `filename` | The file name of the attachment (possibly truncated). |
| `unlock_at` | The unlock date |
| `lock_at` | The lock date |
| `updated_at` | The time at which this attachment was last modified in any way |
| `context_type` | The type of context the attachment is used in. |
| `context_id` | The id of the context the attachment is used in. |
| `content_type` | The content type of the attachment. |

View File

@ -101,6 +101,22 @@ module Canvas::LiveEvents
}
end
def self.get_attachment_data(attachment)
{
attachment_id: attachment.global_id,
user_id: attachment.global_user_id,
display_name: LiveEvents.truncate(attachment.display_name),
filename: LiveEvents.truncate(attachment.filename),
context_type: attachment.context_type,
context_id: attachment.global_context_id,
content_type: attachment.content_type,
folder_id: attachment.global_folder_id,
unlock_at: attachment.unlock_at,
lock_at: attachment.lock_at,
updated_at: attachment.updated_at
}
end
def self.submission_created(submission)
post_event_stringified('submission_created', get_submission_data(submission))
end
@ -220,6 +236,23 @@ module Canvas::LiveEvents
})
end
def self.attachment_created(attachment)
post_event_stringified('attachment_created', get_attachment_data(attachment))
end
def self.attachment_updated(attachment, old_display_name)
payload = get_attachment_data(attachment)
if old_display_name
payload[:old_display_name] = LiveEvents.truncate(old_display_name)
end
post_event_stringified('attachment_updated', payload)
end
def self.attachment_deleted(attachment)
post_event_stringified('attachment_deleted', get_attachment_data(attachment))
end
def self.grade_changed(submission, old_submission=nil, old_assignment=submission.assignment)
grader_id = nil
if submission.grader_id && !submission.autograded?

View File

@ -19,13 +19,81 @@
require File.expand_path(File.dirname(__FILE__) + '/../sharding_spec_helper')
describe LiveEvents do
before :once do
user_with_pseudonym(:username => 'jtfrd@instructure.com', :active_all => 1, :password => 'qwerty')
end
it "should trigger a live event on login" do
it 'should trigger a live event on login' do
Canvas::LiveEvents.expects(:logged_in).once
post '/login', { :pseudonym_session => { :unique_id => 'jtfrd@instructure.com', :password => 'qwerty' } }
user_with_pseudonym(:username => 'jtfrd@instructure.com', :active_user => true, :password => 'qwerty')
post '/login', :pseudonym_session => { :unique_id => 'jtfrd@instructure.com', :password => 'qwerty'}
expect(response).to be_redirect
end
context 'Courses' do
before do
course_with_teacher_logged_in(:active_all => true)
end
context 'Wiki Pages' do
def create_page(attrs)
page = @course.wiki.wiki_pages.create!(attrs)
page.publish! if page.unpublished?
page
end
it 'should trigger a live event on page creation' do
Canvas::LiveEvents.expects(:wiki_page_created).once
create_page :title => 'a-page', :body => 'body'
end
it 'should trigger a live event on page update' do
Canvas::LiveEvents.expects(:wiki_page_updated).twice
page = create_page :title => 'a-page', :body => 'body'
# Updating the page body should trigger a live event
put "/api/v1/courses/#{@course.id}/pages/#{page.url}", :wiki_page => {body: 'UPDATED'}
expect(response.code).to eq '200'
# Updating the page title should trigger a live event
put "/api/v1/courses/#{@course.id}/pages/#{page.url}", :wiki_page => {title: 'UPDATED'}
expect(response.code).to eq '200'
end
it 'should trigger a live event on page delete' do
Canvas::LiveEvents.expects(:wiki_page_deleted).once
page = create_page :title => 'a-page', :body => 'body'
# Updating the page body should trigger a live event
delete "/api/v1/courses/#{@course.id}/pages/#{page.url}"
expect(response.code).to eq '200'
end
end
context 'Files' do
def course_file
data = fixture_file_upload('scribd_docs/doc.doc', 'application/msword', true)
factory_with_protected_attributes(@course.attachments, :uploaded_data => data)
end
it 'should trigger a live event on files being added to the course' do
Canvas::LiveEvents.expects(:attachment_created).once
course_file
end
it 'should trigger a live event on file updates' do
Canvas::LiveEvents.expects(:attachment_updated).once
file = course_file
put "/api/v1/files/#{file.id}", :name => 'UPDATED'
expect(response.code).to eq '200'
end
it 'should trigger a live event on file deletes' do
Canvas::LiveEvents.expects(:attachment_deleted).once
file = course_file
delete "/api/v1/files/#{file.id}"
expect(response.code).to eq '200'
end
end
end
end