Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions app/models/quizzes/quiz.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,32 @@ class Quizzes::Quiz < ApplicationRecord

self.table_name = "quizzes"

# Fields that trigger a quiz_updated live event when changed.
# Includes quiz-specific settings and availability dates.
QUIZ_EVENT_FIELDS = %w[
access_code
allowed_attempts
anonymous_submissions
cant_go_back
disable_timer_autosubmission
due_at
hide_correct_answers_at
hide_results
ip_filter
lock_at
one_question_at_a_time
one_time_results
require_lockdown_browser
require_lockdown_browser_for_results
scoring_policy
show_correct_answers
show_correct_answers_at
show_correct_answers_last_attempt
shuffle_answers
time_limit
unlock_at
].freeze

include Workflow
include HasContentTags
include CopyAuthorizedLinks
Expand Down Expand Up @@ -75,6 +101,8 @@ class Quizzes::Quiz < ApplicationRecord
before_save :build_assignment
before_save :set_defaults
after_save :update_assignment
after_save :fire_quiz_created_event
after_save :fire_quiz_updated_event
before_save :check_if_needs_availability_cache_clear
after_save :clear_availability_cache
after_save :touch_context
Expand Down Expand Up @@ -531,6 +559,29 @@ def update_assignment

protected :update_assignment

def fire_quiz_created_event
return unless saved_changes.key?("id") # new record only
return if saved_by == :migration

self.class.connection.after_transaction_commit do
Canvas::LiveEvents.quiz_created(self)
end
end

private :fire_quiz_created_event

def fire_quiz_updated_event
return if saved_changes.key?("id") # new record
return if saved_by == :migration
return unless (saved_changes.keys & QUIZ_EVENT_FIELDS).any?

self.class.connection.after_transaction_commit do
Canvas::LiveEvents.quiz_updated(self)
end
end

private :fire_quiz_updated_event

attr_reader :should_clear_availability_cache

def check_if_needs_availability_cache_clear
Expand Down
2 changes: 2 additions & 0 deletions doc/api/data_services/data_services_events_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class DataServicesEventsLoader
"doc/api/data_services/json/canvas/event-types/outcome_proficiency_created.json" => "learning",
"doc/api/data_services/json/canvas/event-types/outcome_proficiency_updated.json" => "learning",
"doc/api/data_services/json/caliper/event-types/quiz_submitted.json" => "assessment",
"doc/api/data_services/json/caliper/event-types/quiz_created.json" => "basic",
"doc/api/data_services/json/caliper/event-types/quiz_updated.json" => "basic",
"doc/api/data_services/json/caliper/event-types/assignment_created.json" => "basic",
"doc/api/data_services/json/caliper/event-types/assignment_updated.json" => "basic",
"doc/api/data_services/json/caliper/event-types/assignment_override_created.json" => "basic",
Expand Down
114 changes: 114 additions & 0 deletions doc/api/data_services/json/caliper/event-types/quiz_created.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
{
"name": "quiz_created",
"definition": "The event is emitted anytime a new classic quiz is created by an end user or API request.",
"trigger": "Triggered when a new classic quiz [old quizzes] is created in a course.",
"schema": {
"data[0].group.extensions[\"com.instructure.canvas\"]": {
"context_type": "Canvas context type where the action took place e.g context_type = Course.",
"entity_id": "Canvas context ID"
},
"data[0].object.extensions[\"com.instructure.canvas\"]": {
"entity_id": "Canvas global ID of the object affected by the event",
"quiz_type": "The type of quiz (assignment, practice_quiz, graded_survey, survey).",
"time_limit": "The time limit for taking the quiz, in minutes.",
"access_code": "Whether the quiz requires an access code (boolean).",
"workflow_state": "Workflow state of the quiz (created, edited, available, unpublished, deleted)."
},
"data[0].object": {
"type": "Assessment"
}
},
"examples": [
{
"payload": {
"sensor": "http://oxana.instructure.com/",
"sendTime": "2019-11-16T02:08:59.579Z",
"dataVersion": "http://purl.imsglobal.org/ctx/caliper/v1p1",
"data": [
{
"@context": "http://purl.imsglobal.org/ctx/caliper/v1p1",
"id": "urn:uuid:3f672715-6aa8-4293-b62a-3b3319ff5701",
"type": "Event",
"actor": {
"id": "urn:instructure:canvas:user:21070000000000001",
"type": "Person",
"extensions": {
"com.instructure.canvas": {
"user_login": "oxana@example.com",
"user_sis_id": "456-T45",
"root_account_id": "21070000000000001",
"root_account_lti_guid": "VicYj3cu5BIFpoZhDVU4DZumnlBrWi1grgJEzADs.oxana.instructure.com",
"root_account_uuid": "VicYj3cu5BIFpoZhDVU4DZumnlBrWi1grgJEzADs",
"entity_id": "21070000000000001"
}
}
},
"action": "Created",
"object": {
"id": "urn:instructure:canvas:quiz:21070000002030605",
"type": "Assessment",
"name": "Chapter 5 Quiz",
"dateCreated": "2019-11-01T19:11:11.323Z",
"extensions": {
"com.instructure.canvas": {
"quiz_type": "assignment",
"time_limit": 30,
"access_code": true,
"workflow_state": "created",
"entity_id": "21070000002030605"
}
},
"dateToShow": "2019-11-01T00:00:00.000Z",
"dateToSubmit": "2019-11-05T13:38:00.218Z",
"maxScore": 100
},
"eventTime": "2019-11-01T19:11:11.323Z",
"edApp": {
"id": "http://oxana.instructure.com/",
"type": "SoftwareApplication"
},
"group": {
"id": "urn:instructure:canvas:course:21070000001279362",
"type": "CourseOffering",
"extensions": {
"com.instructure.canvas": {
"context_type": "Course",
"entity_id": "21070000001279362"
}
}
},
"membership": {
"id": "urn:instructure:canvas:course:21070000001279362:Instructor:21070000000000001",
"type": "Membership",
"member": {
"id": "urn:instructure:canvas:user:21070000000000001",
"type": "Person"
},
"organization": {
"id": "urn:instructure:canvas:course:21070000001279362",
"type": "CourseOffering"
},
"roles": [
"Instructor"
]
},
"session": {
"id": "urn:instructure:canvas:session:ef686f8ed684abf78cbfa1f6a58112b5",
"type": "Session"
},
"extensions": {
"com.instructure.canvas": {
"hostname": "oxana.instructure.com",
"request_id": "1dd9dc6f-2fb0-4c19-a6c5-7ee1bf3ed295",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36",
"client_ip": "93.184.216.34",
"request_url": "https://oxana.instructure.com/api/v1/courses/1279362/quizzes",
"version": "1.0.0"
}
}
}
]
}
}
]
}
114 changes: 114 additions & 0 deletions doc/api/data_services/json/caliper/event-types/quiz_updated.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
{
"name": "quiz_updated",
"definition": "The event is emitted anytime a classic quiz's settings are updated by an end user or API request. This covers quiz-specific fields such as access_code, time_limit, ip_filter, and other settings that are not reflected on the associated assignment.",
"trigger": "Triggered when a classic quiz [old quizzes] has been modified and quiz-specific settings have changed.",
"schema": {
"data[0].group.extensions[\"com.instructure.canvas\"]": {
"context_type": "Canvas context type where the action took place e.g context_type = Course.",
"entity_id": "Canvas context ID"
},
"data[0].object.extensions[\"com.instructure.canvas\"]": {
"entity_id": "Canvas global ID of the object affected by the event",
"quiz_type": "The type of quiz (assignment, practice_quiz, graded_survey, survey).",
"time_limit": "The time limit for taking the quiz, in minutes.",
"access_code": "Whether the quiz requires an access code (boolean).",
"workflow_state": "Workflow state of the quiz (created, edited, available, unpublished, deleted)."
},
"data[0].object": {
"type": "Assessment"
}
},
"examples": [
{
"payload": {
"sensor": "http://oxana.instructure.com/",
"sendTime": "2019-11-16T02:09:00.554Z",
"dataVersion": "http://purl.imsglobal.org/ctx/caliper/v1p1",
"data": [
{
"@context": "http://purl.imsglobal.org/ctx/caliper/v1p1",
"id": "urn:uuid:0a2a8c4d-0ebc-4200-ab6f-095b3b16852d",
"type": "Event",
"actor": {
"id": "urn:instructure:canvas:user:21070000000000001",
"type": "Person",
"extensions": {
"com.instructure.canvas": {
"user_login": "oxana@example.com",
"user_sis_id": "456-T45",
"root_account_id": "21070000000000001",
"root_account_lti_guid": "VicYj3cu5BIFpoZhDVU4DZumnlBrWi1grgJEzADs.oxana.instructure.com",
"root_account_uuid": "VicYj3cu5BIFpoZhDVU4DZumnlBrWi1grgJEzADs",
"entity_id": "21070000000000001"
}
}
},
"action": "Modified",
"object": {
"id": "urn:instructure:canvas:quiz:21070000002030605",
"type": "Assessment",
"name": "Chapter 5 Quiz",
"dateModified": "2019-11-05T13:38:00.218Z",
"extensions": {
"com.instructure.canvas": {
"quiz_type": "assignment",
"time_limit": 30,
"access_code": true,
"workflow_state": "available",
"entity_id": "21070000002030605"
}
},
"dateToShow": "2019-11-01T00:00:00.000Z",
"dateToSubmit": "2019-11-05T13:38:00.218Z",
"maxScore": 100
},
"eventTime": "2019-11-01T19:11:14.005Z",
"edApp": {
"id": "http://oxana.instructure.com/",
"type": "SoftwareApplication"
},
"group": {
"id": "urn:instructure:canvas:course:21070000001279362",
"type": "CourseOffering",
"extensions": {
"com.instructure.canvas": {
"context_type": "Course",
"entity_id": "21070000001279362"
}
}
},
"membership": {
"id": "urn:instructure:canvas:course:21070000001279362:Instructor:21070000000000001",
"type": "Membership",
"member": {
"id": "urn:instructure:canvas:user:21070000000000001",
"type": "Person"
},
"organization": {
"id": "urn:instructure:canvas:course:21070000001279362",
"type": "CourseOffering"
},
"roles": [
"Instructor"
]
},
"session": {
"id": "urn:instructure:canvas:session:ef686f8ed684abf78cbfa1f6a58112b5",
"type": "Session"
},
"extensions": {
"com.instructure.canvas": {
"hostname": "oxana.instructure.com",
"request_id": "1dd9dc6f-2fb0-4c19-a6c5-7ee1bf3ed295",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36",
"client_ip": "93.184.216.34",
"request_url": "https://oxana.instructure.com/api/v1/courses/1279362/quizzes/2030605",
"version": "1.0.0"
}
}
}
]
}
}
]
}
Loading