populate root_account_id on calendar_events
closes INTEROP-5844 flag=none test plan: - have existing CalendarEvents without root account id, preferably at least one with each context type (Course, CourseSection, Group, User w/no effective context, User w/effective context, AppointmentGroup) - run `DataFixup::PopulateRootAccountIdOnCalendarEvents.run` - verify all events (except User w/o effective context) have a root_account_id Change-Id: I7d3c3c7221c25b3ae2d8c1b8819307cc66be229e Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/242024 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> QA-Review: Weston Dransfield <wdransfield@instructure.com> Reviewed-by: Cody Cutrer <cody@instructure.com> Reviewed-by: Mysti Lilla <mysti@instructure.com> Product-Review: Xander Moffatt <xmoffatt@instructure.com>
This commit is contained in:
parent
75f7970346
commit
81f3dbad4f
|
@ -0,0 +1,32 @@
|
|||
#
|
||||
# Copyright (C) 2020 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class PopulateRootAccountIdOnCalendarEvents < ActiveRecord::Migration[5.2]
|
||||
tag :postdeploy
|
||||
|
||||
def up
|
||||
CalendarEvent.find_ids_in_ranges(batch_size: 100_000) do |min, max|
|
||||
DataFixup::PopulateRootAccountIdOnCalendarEvents.send_later_if_production_enqueue_args(
|
||||
:run,
|
||||
{:priority => Delayed::LOWER_PRIORITY, :n_strand => ["root_account_id_backfill_strand", Shard.current.database_server.id]},
|
||||
min, max
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def down; end
|
||||
end
|
|
@ -0,0 +1,46 @@
|
|||
#
|
||||
# Copyright (C) 2020 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module DataFixup::PopulateRootAccountIdOnCalendarEvents
|
||||
def self.run(min, max)
|
||||
# CalendarEvents with context of Course, Group, or CourseSection are handled
|
||||
# by PopulateRootAccountIdOnModels.
|
||||
# events with context of AppointmentGroup and User are special cases and
|
||||
# are handled here.
|
||||
|
||||
# effective_context is populated in one of two ways:
|
||||
# 1. as part of an appointment group, which will either be a Course or CourseSection
|
||||
# 2. from a parent event, not part of an appointment group. This will be the parent
|
||||
# event's context, which will be one of Course/CourseSection/Group.
|
||||
effective_context_types = [
|
||||
Course,
|
||||
CourseSection,
|
||||
Group
|
||||
]
|
||||
|
||||
effective_context_types.each do |model|
|
||||
qtn = model.quoted_table_name # to appease the linter on line 41
|
||||
CalendarEvent.find_ids_in_ranges(start_at: min, end_at: max) do |batch_min, batch_max|
|
||||
CalendarEvent.where(id: batch_min..batch_max, context_type: ["AppointmentGroup", "User"]).
|
||||
where("effective_context_code like ?", "#{model.table_name.singularize}%").
|
||||
# pull id from effective context code that looks like `course_1` or `course_section_1`
|
||||
joins("INNER JOIN #{qtn} ON #{qtn}.id = cast(reverse(split_part(reverse(calendar_events.effective_context_code), '_', 1)) as integer)").
|
||||
update_all("root_account_id=#{qtn}.root_account_id")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -63,6 +63,7 @@ module DataFixup::PopulateRootAccountIdOnModels
|
|||
AssignmentGroup => :context,
|
||||
AssignmentOverride => :assignment,
|
||||
AssignmentOverrideStudent => :assignment,
|
||||
CalendarEvent => [:context_course, :context_group, :context_course_section],
|
||||
ContentMigration => [:account, :course, :group],
|
||||
ContentParticipation => :content,
|
||||
ContentParticipationCount => :course,
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
#
|
||||
# Copyright (C) 2020 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe DataFixup::PopulateRootAccountIdOnCalendarEvents do
|
||||
it 'ignores CalendarEvents with Course context' do
|
||||
event = CalendarEvent.create!(context: course_model)
|
||||
event.update_column(:root_account_id, nil)
|
||||
DataFixup::PopulateRootAccountIdOnCalendarEvents.run(event.id, event.id)
|
||||
expect(event.reload.root_account_id).to be_nil
|
||||
end
|
||||
|
||||
it 'ignores CalendarEvents with Group context' do
|
||||
event = CalendarEvent.create!(context: group_model)
|
||||
event.update_column(:root_account_id, nil)
|
||||
DataFixup::PopulateRootAccountIdOnCalendarEvents.run(event.id, event.id)
|
||||
expect(event.reload.root_account_id).to be_nil
|
||||
end
|
||||
|
||||
it 'ignores CalendarEvents with CourseSection context' do
|
||||
section = CourseSection.create!(course: course_model)
|
||||
event = CalendarEvent.create!(context: section)
|
||||
event.update_column(:root_account_id, nil)
|
||||
DataFixup::PopulateRootAccountIdOnCalendarEvents.run(event.id, event.id)
|
||||
expect(event.reload.root_account_id).to be_nil
|
||||
end
|
||||
|
||||
it 'ignores CalendarEvents with User context and no effective context' do
|
||||
event = CalendarEvent.create!(context: user_model)
|
||||
event.update_column(:root_account_id, nil)
|
||||
DataFixup::PopulateRootAccountIdOnCalendarEvents.run(event.id, event.id)
|
||||
expect(event.reload.root_account_id).to be_nil
|
||||
end
|
||||
|
||||
it 'sets root_account_id from effective context for CalendarEvent with User context' do
|
||||
course = course_model
|
||||
event = CalendarEvent.create!(context: user_model, effective_context_code: course.asset_string)
|
||||
event.update_column(:root_account_id, nil)
|
||||
DataFixup::PopulateRootAccountIdOnCalendarEvents.run(event.id, event.id)
|
||||
expect(event.reload.root_account_id).to eq course.root_account_id
|
||||
end
|
||||
|
||||
it 'sets root_account_id from effective context for CalendarEvent with AppointmentGroup context' do
|
||||
course = course_model
|
||||
ag = AppointmentGroup.create!
|
||||
AppointmentGroupContext.create!(appointment_group: ag, context: course)
|
||||
event = CalendarEvent.create!(context: ag.reload)
|
||||
event.update_column(:root_account_id, nil)
|
||||
DataFixup::PopulateRootAccountIdOnCalendarEvents.run(event.id, event.id)
|
||||
expect(event.reload.root_account_id).to eq course.root_account_id
|
||||
end
|
||||
|
||||
it 'sets root_account_id from effective context for child CalendarEvent' do
|
||||
course = course_model
|
||||
parent = CalendarEvent.create!(context: course)
|
||||
event = CalendarEvent.create!(context: user_model, parent_event: parent)
|
||||
event.update_column(:root_account_id, nil)
|
||||
DataFixup::PopulateRootAccountIdOnCalendarEvents.run(event.id, event.id)
|
||||
expect(event.reload.root_account_id).to eq course.root_account_id
|
||||
end
|
||||
|
||||
it 'sets root_account_id from effective context for multiple CalendarEvents' do
|
||||
course = course_model
|
||||
e1 = CalendarEvent.create!(context: user_model, effective_context_code: course.asset_string)
|
||||
ag = AppointmentGroup.create!
|
||||
AppointmentGroupContext.create!(appointment_group: ag, context: course)
|
||||
e2 = CalendarEvent.create!(context: ag.reload)
|
||||
parent = CalendarEvent.create!(context: course)
|
||||
e3 = CalendarEvent.create!(context: user_model, parent_event: parent)
|
||||
events = [e1, e2, e3]
|
||||
|
||||
CalendarEvent.where(id: events.map(&:id)).update_all(root_account_id: nil)
|
||||
DataFixup::PopulateRootAccountIdOnCalendarEvents.run(e1.id, e3.id)
|
||||
events.each do |e|
|
||||
expect(e.reload.root_account_id).to eq course.root_account_id
|
||||
end
|
||||
end
|
||||
end
|
|
@ -142,6 +142,29 @@ describe DataFixup::PopulateRootAccountIdOnModels do
|
|||
expect(@override_student.reload.root_account_id).to eq @course.root_account_id
|
||||
end
|
||||
|
||||
context 'with CalendarEvent' do
|
||||
context 'when context is Course' do
|
||||
it_behaves_like 'a datafixup that populates root_account_id' do
|
||||
let(:record) { CalendarEvent.create!(context: @course) }
|
||||
let(:reference_record) { @course }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when context is Group' do
|
||||
it_behaves_like 'a datafixup that populates root_account_id' do
|
||||
let(:record) { CalendarEvent.create!(context: group_model(context: @course)) }
|
||||
let(:reference_record) { @course }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when context is CourseSection' do
|
||||
it_behaves_like 'a datafixup that populates root_account_id' do
|
||||
let(:record) { CalendarEvent.create!(context: CourseSection.create!(course: @course)) }
|
||||
let(:reference_record) { @course }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with ContextExternalTool' do
|
||||
it_behaves_like 'a datafixup that populates root_account_id' do
|
||||
let(:record) { external_tool_model(context: @course) }
|
||||
|
|
Loading…
Reference in New Issue