Handle line item downstream changes in BP syncs
closes LS-3941 flag=blueprint_line_item_support [fsc-max-nodes=18] [fsc-timeout=40] Test-plan: - Set up an LTI tool - Create a BP course with an assignment - Add a line item to the assignemnt - Run a BP Sync - Alter the line item in the child course - Alter the line item in the master course - Run a BP Sync - Check the downstream changes to the downstream line item remain Change-Id: Idd456753173ee86e9c9b20d9bd99dd9832ffb173 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/317932 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Jacob DeWar <jacob.dewar@instructure.com> QA-Review: Jacob DeWar <jacob.dewar@instructure.com> Product-Review: Luis Oliveira <luis.oliveira@instructure.com>
This commit is contained in:
parent
9c779047b6
commit
638901cd13
|
@ -1206,9 +1206,13 @@ class Assignment < ActiveRecord::Base
|
|||
li = line_items.create!(label: title, score_maximum: points_possible, resource_link: rl, coupled: true, resource_id: line_item_resource_id, tag: line_item_tag)
|
||||
create_results_from_prior_grades(li)
|
||||
elsif saved_change_to_title? || saved_change_to_points_possible?
|
||||
line_items
|
||||
.find(&:assignment_line_item?)
|
||||
&.update!(label: title, score_maximum: points_possible || 0, resource_id: line_item_resource_id, tag: line_item_tag)
|
||||
if (li = line_items.find(&:assignment_line_item?))
|
||||
li.label = title
|
||||
li.score_maximum = points_possible || 0
|
||||
li.tag = line_item_tag if line_item_tag
|
||||
li.resource_id = line_item_resource_id if line_item_resource_id
|
||||
li.save!
|
||||
end
|
||||
end
|
||||
|
||||
if lti_1_3_external_tool_tag?(lti_1_3_tool) && !lti_resource_links.empty?
|
||||
|
|
|
@ -507,6 +507,11 @@ module Importers
|
|||
|
||||
params[:client_id] = li[:client_id] unless tool
|
||||
|
||||
if Account.site_admin.feature_enabled?(:blueprint_line_item_support) && primary_line_item
|
||||
params = clear_params_before_overwriting_child_li(params, primary_line_item, migration)
|
||||
primary_line_item.mark_as_importing! migration
|
||||
end
|
||||
|
||||
if primary_line_item&.coupled && (li[:coupled] || !any_coupled_line_items)
|
||||
# Modify the default coupled line item if:
|
||||
# * We are processing a coupled line item (need to replace properties
|
||||
|
@ -544,5 +549,24 @@ module Importers
|
|||
attachment.move_to_bottom if attachment.saved_change_to_folder_id?
|
||||
assignment.annotatable_attachment = attachment
|
||||
end
|
||||
|
||||
def self.clear_params_before_overwriting_child_li(params, primary_line_item, migration)
|
||||
return params unless (child_tag = migration.master_course_subscription.content_tag_for(primary_line_item.assignment))
|
||||
return params unless child_tag.downstream_changes.present?
|
||||
|
||||
primary_line_item.class.base_class.restricted_column_settings.each do |type, columns|
|
||||
changed_columns = params.keys.map(&:to_s) & columns if child_tag.downstream_changes & ["lti_line_items_#{type}"] # changed restricted types
|
||||
|
||||
if changed_columns.any?
|
||||
if primary_line_item.assignment.child_content_restrictions[type] # don't overwrite downstream changes _unless_ it's locked
|
||||
child_tag.downstream_changes -= "lti_line_items_#{type}" # remove them from the downstream changes since we're going to overwrite
|
||||
child_tag.save!
|
||||
else
|
||||
changed_columns.each { |cc| params.delete(cc.to_sym) } # if not locked then we should ignore the params in the category (content or settings)
|
||||
end
|
||||
end
|
||||
end
|
||||
params
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,6 +51,10 @@ class Lti::LineItem < ApplicationRecord
|
|||
AGS_EXT_SUBMISSION_TYPE = "#{AGS_EXT_PREFIX}submission_type"
|
||||
AGS_EXT_LAUNCH_URL = "#{AGS_EXT_PREFIX}launch_url"
|
||||
|
||||
include MasterCourses::CollectionRestrictor
|
||||
self.collection_owner_association = :assignment
|
||||
restrict_columns :content, [:resource_id]
|
||||
|
||||
def assignment_line_item?
|
||||
assignment.line_items.order(:created_at).first.id == id
|
||||
end
|
||||
|
|
|
@ -31,7 +31,7 @@ module MasterCourses::CollectionRestrictor
|
|||
|
||||
klass.cattr_accessor :collection_owner_association # this is the association to find the quiz
|
||||
|
||||
klass.after_update :mark_downstream_changes
|
||||
klass.after_update :mark_downstream_changes, if: -> { klass != Lti::LineItem || Account.site_admin.feature_enabled?(:blueprint_line_item_support) }
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
|
|
|
@ -171,17 +171,20 @@ describe MasterCourses::MasterMigration do
|
|||
before :once do
|
||||
account_admin_user(active_all: true)
|
||||
@copy_from = @course
|
||||
@copy_to = course_factory
|
||||
@sub = @template.add_child_course!(@copy_to)
|
||||
tool = external_tool_model(context: Account.default, opts: { use_1_3: true, developer_key: DeveloperKey.create!(account: Account.default) })
|
||||
@original_assignment = @copy_from.assignments.create!(title: "some assignment", submission_types: "external_tool", points_possible: 10)
|
||||
tag = ContentTag.new(content: tool, url: "http://example.com/original", context: @original_assignment)
|
||||
@original_assignment.update!(external_tool_tag: tag)
|
||||
@original_line_item = @original_assignment.line_items.first
|
||||
@original_line_item.update!(resource_id: "some_resource_id")
|
||||
end
|
||||
|
||||
before do
|
||||
@copy_to = course_factory
|
||||
@sub = @template.add_child_course!(@copy_to)
|
||||
|
||||
@original_assignment = @copy_from.assignments.create!(title: "some assignment", submission_types: "external_tool")
|
||||
@original_assignment.build_external_tool_tag(url: "http://example.com/original", new_tab: true)
|
||||
@original_assignment.save!
|
||||
|
||||
run_master_migration
|
||||
@assignment_copy = @copy_to.assignments.where(migration_id: mig_id(@original_assignment)).first
|
||||
@line_item_copy = @assignment_copy.line_items.last
|
||||
end
|
||||
|
||||
it "copies external tool tag over" do
|
||||
|
@ -199,12 +202,63 @@ describe MasterCourses::MasterMigration do
|
|||
end
|
||||
|
||||
it "does not update associated course's external tool tag on blueprint update if the associated course had an independent update" do
|
||||
@assignment_copy = @copy_to.assignments.where(migration_id: mig_id(@original_assignment)).first
|
||||
@assignment_copy.external_tool_tag.update!(url: "http://example.com/associated_updated", new_tab: true)
|
||||
@original_assignment.touch
|
||||
run_master_migration
|
||||
expect(@assignment_copy.reload.external_tool_tag.url).to eq "http://example.com/associated_updated"
|
||||
end
|
||||
|
||||
context "with blueprint_line_item_support ON" do
|
||||
it "respects line item downstream editing and assignment locking" do
|
||||
Account.site_admin.enable_feature! :blueprint_line_item_support
|
||||
|
||||
@original_line_item.update!(resource_id: "updated_resource_id")
|
||||
@original_assignment.update!(title: "updated assignment title")
|
||||
run_master_migration
|
||||
expect(@line_item_copy.reload.resource_id).to eq("updated_resource_id")
|
||||
|
||||
@line_item_copy.update! resource_id: "downstream_resource_id"
|
||||
@original_line_item.update!(resource_id: "updated_resource_id AGAIN")
|
||||
@original_assignment.update!(title: "updated assignment title AGAIN")
|
||||
@original_assignment.touch
|
||||
run_master_migration
|
||||
|
||||
# The one line item downstream change stops assignment synch as a whole
|
||||
expect(@assignment_copy.reload.title).to eq("updated assignment title")
|
||||
expect(@line_item_copy.reload.label).to eq("updated assignment title")
|
||||
expect(@line_item_copy.reload.resource_id).to eq("downstream_resource_id")
|
||||
|
||||
@template.content_tag_for(@original_assignment).update_attribute(:restrictions, { content: true })
|
||||
run_master_migration
|
||||
|
||||
expect(@assignment_copy.reload.title).to eq("updated assignment title AGAIN")
|
||||
expect(@line_item_copy.reload.label).to eq("updated assignment title AGAIN")
|
||||
expect(@line_item_copy.reload.resource_id).to eq("updated_resource_id AGAIN")
|
||||
end
|
||||
end
|
||||
|
||||
context "with blueprint_line_item_support OFF" do
|
||||
it "respects line item downstream editing and assignment locking" do
|
||||
Account.site_admin.disable_feature! :blueprint_line_item_support
|
||||
|
||||
expect(@original_line_item.resource_id).to eq("some_resource_id")
|
||||
|
||||
@original_line_item.update!(resource_id: "updated_resource_id")
|
||||
@original_assignment.update!(title: "updated assignment title")
|
||||
run_master_migration
|
||||
expect(@line_item_copy.reload.resource_id).to eq("updated_resource_id")
|
||||
|
||||
@line_item_copy.update! resource_id: "downstream_resource_id"
|
||||
@original_line_item.update!(resource_id: "updated_resource_id AGAIN")
|
||||
@original_assignment.update!(title: "updated assignment title AGAIN")
|
||||
@original_assignment.touch
|
||||
run_master_migration
|
||||
|
||||
expect(@assignment_copy.reload.title).to eq("updated assignment title AGAIN")
|
||||
expect(@line_item_copy.reload.label).to eq("updated assignment title AGAIN")
|
||||
expect(@line_item_copy.reload.resource_id).to eq("updated_resource_id AGAIN")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Course pace migration" do
|
||||
|
|
Loading…
Reference in New Issue