Consider resource type code when sending tool events
Fixes INTEROP-6252 flag=none Test Plan: - Install multiple plagiarism detection tools in the same account with _different_ resource type codes. Each tool should also have a different endpoint - Associate an assignment with one of the tools - Submit and verify an event is sent to the tool with the matching resource type code - Verify events were not sent to the other tools Change-Id: I5892451c2ac3af64254881319d6f1143703a5cb6 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/249776 Reviewed-by: Mysti Lilla <mysti@instructure.com> QA-Review: Tucker Mcknight <tmcknight@instructure.com> Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Product-Review: Weston Dransfield <wdransfield@instructure.com>
This commit is contained in:
parent
cbcaafb773
commit
2e96e905b2
|
@ -69,7 +69,7 @@ module Lti
|
|||
ToolProxy.joins("JOIN (#{subquery}) bindings on lti_tool_proxies.id = bindings.tool_proxy_id").where('bindings.enabled = true')
|
||||
end
|
||||
|
||||
def self.find_all_proxies_for_context_by_context_order_by_vendor_product_code(context:, vendor_code:, product_code:)
|
||||
def self.proxies_in_order_by_codes(context:, vendor_code:, product_code:, resource_type_code:)
|
||||
account_ids = context.account_chain.map { |a| a.id }
|
||||
|
||||
# Added i+1 on this to ensure that the x.ordering later doesn't have 2 0's
|
||||
|
@ -89,12 +89,13 @@ module Lti
|
|||
select('lti_tool_proxies.*, bindings.enabled AS binding_enabled').
|
||||
# changed this from eager_load, because eager_load likes to wipe out custom select attributes
|
||||
joins(:product_family).
|
||||
preload(:product_family).
|
||||
joins(:resources).
|
||||
# changed the order to go from the special ordering set up (to make sure we're going from the course to the
|
||||
# root account in order of parent accounts) and then takes the most recently installed tool
|
||||
order('ordering, lti_tool_proxies.id DESC').
|
||||
where('lti_tool_proxies.workflow_state = ?', 'active').
|
||||
where('lti_product_families.vendor_code = ? AND lti_product_families.product_code = ?', vendor_code, product_code)
|
||||
where('lti_product_families.vendor_code = ? AND lti_product_families.product_code = ?', vendor_code, product_code).
|
||||
where('lti_resource_handlers.resource_type_code = ?', resource_type_code)
|
||||
# You can disable a tool_binding somewhere in the account chain, and anything below that that reenables it should be
|
||||
# available, but nothing above it, so we're getting rid of anything that is disabled and above
|
||||
tools.split{|tool| !tool.binding_enabled}.first
|
||||
|
|
|
@ -240,10 +240,11 @@ module Canvas::LiveEvents
|
|||
domain = assignment.root_account&.domain(ApplicationController.test_cluster_name)
|
||||
event[:domain] = domain if domain
|
||||
if actl
|
||||
if (tool_proxy = Lti::ToolProxy.find_all_proxies_for_context_by_context_order_by_vendor_product_code(
|
||||
if (tool_proxy = Lti::ToolProxy.proxies_in_order_by_codes(
|
||||
context: assignment.course,
|
||||
vendor_code: actl.tool_vendor_code,
|
||||
product_code: actl.tool_product_code
|
||||
product_code: actl.tool_product_code,
|
||||
resource_type_code: actl.tool_resource_type_code
|
||||
).first)
|
||||
event[:associated_integration_id] = [actl.tool_vendor_code, actl.tool_product_code, tool_proxy.event_endpoint].join('_')
|
||||
end
|
||||
|
@ -344,10 +345,11 @@ module Canvas::LiveEvents
|
|||
}
|
||||
actl = submission.assignment.assignment_configuration_tool_lookups.take
|
||||
if actl
|
||||
if (tool_proxy = Lti::ToolProxy.find_all_proxies_for_context_by_context_order_by_vendor_product_code(
|
||||
if (tool_proxy = Lti::ToolProxy.proxies_in_order_by_codes(
|
||||
context: submission.course,
|
||||
vendor_code: actl.tool_vendor_code,
|
||||
product_code: actl.tool_product_code
|
||||
product_code: actl.tool_product_code,
|
||||
resource_type_code: actl.tool_resource_type_code
|
||||
).first)
|
||||
event[:associated_integration_id] = [actl.tool_vendor_code, actl.tool_product_code, tool_proxy.event_endpoint].join('_')
|
||||
end
|
||||
|
|
|
@ -591,12 +591,23 @@ describe Canvas::LiveEvents do
|
|||
end
|
||||
|
||||
it 'should include the associated_integration_id if there is an installed tool proxy with that id' do
|
||||
submission.assignment.assignment_configuration_tool_lookups.create!(tool_product_code: 'turnitin-lti',
|
||||
tool_vendor_code: 'turnitin.com', tool_type: 'Lti::MessageHandler')
|
||||
submission.assignment.assignment_configuration_tool_lookups.create!(
|
||||
tool_product_code: 'turnitin-lti',
|
||||
tool_vendor_code: 'turnitin.com',
|
||||
tool_resource_type_code: 'resource-type-code',
|
||||
tool_type: 'Lti::MessageHandler'
|
||||
)
|
||||
|
||||
tool_proxy = create_tool_proxy(submission.assignment.course)
|
||||
tool_proxy[:raw_data]['tool_profile'] = {'service_offered' => [submission_event_service]}
|
||||
tool_proxy.save!
|
||||
|
||||
Lti::ResourceHandler.create!(
|
||||
tool_proxy: tool_proxy,
|
||||
name: 'resource_handler',
|
||||
resource_type_code: 'resource-type-code'
|
||||
)
|
||||
|
||||
expect_event('submission_created',
|
||||
hash_including(
|
||||
associated_integration_id: "turnitin.com_turnitin-lti_test.com/submission"
|
||||
|
@ -680,12 +691,23 @@ describe Canvas::LiveEvents do
|
|||
end
|
||||
|
||||
it 'should include the associated_integration_id if there is an installed tool proxy with that id' do
|
||||
submission.assignment.assignment_configuration_tool_lookups.create!(tool_product_code: 'turnitin-lti',
|
||||
tool_vendor_code: 'turnitin.com', tool_type: 'Lti::MessageHandler')
|
||||
submission.assignment.assignment_configuration_tool_lookups.create!(
|
||||
tool_product_code: 'turnitin-lti',
|
||||
tool_vendor_code: 'turnitin.com',
|
||||
tool_resource_type_code: 'resource-type-code',
|
||||
tool_type: 'Lti::MessageHandler'
|
||||
)
|
||||
|
||||
tool_proxy = create_tool_proxy(submission.assignment.course)
|
||||
tool_proxy[:raw_data]['tool_profile'] = {'service_offered' => [submission_event_service]}
|
||||
tool_proxy.save!
|
||||
|
||||
Lti::ResourceHandler.create!(
|
||||
tool_proxy: tool_proxy,
|
||||
name: 'resource_handler',
|
||||
resource_type_code: 'resource-type-code'
|
||||
)
|
||||
|
||||
expect_event('submission_updated',
|
||||
hash_including(
|
||||
associated_integration_id: "turnitin.com_turnitin-lti_test.com/submission"
|
||||
|
@ -803,12 +825,23 @@ describe Canvas::LiveEvents do
|
|||
end
|
||||
|
||||
it 'should include the associated_integration_id if there is an installed tool proxy with that id' do
|
||||
submission.assignment.assignment_configuration_tool_lookups.create!(tool_product_code: 'turnitin-lti',
|
||||
tool_vendor_code: 'turnitin.com', tool_type: 'Lti::MessageHandler')
|
||||
submission.assignment.assignment_configuration_tool_lookups.create!(
|
||||
tool_product_code: 'turnitin-lti',
|
||||
tool_vendor_code: 'turnitin.com',
|
||||
tool_resource_type_code: 'resource-type-code',
|
||||
tool_type: 'Lti::MessageHandler'
|
||||
)
|
||||
|
||||
tool_proxy = create_tool_proxy(submission.assignment.course)
|
||||
tool_proxy[:raw_data]['tool_profile'] = {'service_offered' => [submission_event_service]}
|
||||
tool_proxy.save!
|
||||
|
||||
Lti::ResourceHandler.create!(
|
||||
tool_proxy: tool_proxy,
|
||||
name: 'resource_handler',
|
||||
resource_type_code: 'resource-type-code'
|
||||
)
|
||||
|
||||
expect_event('plagiarism_resubmit',
|
||||
hash_including(
|
||||
associated_integration_id: "turnitin.com_turnitin-lti_test.com/submission"
|
||||
|
@ -987,12 +1020,22 @@ describe Canvas::LiveEvents do
|
|||
end
|
||||
|
||||
it 'should include the associated_integration_id if there is an installed tool proxy with that id' do
|
||||
@assignment.assignment_configuration_tool_lookups.create!(tool_product_code: 'turnitin-lti',
|
||||
tool_vendor_code: 'turnitin.com', tool_type: 'Lti::MessageHandler')
|
||||
@assignment.assignment_configuration_tool_lookups.create!(
|
||||
tool_product_code: 'turnitin-lti',
|
||||
tool_vendor_code: 'turnitin.com',
|
||||
tool_resource_type_code: 'resource-type-code',
|
||||
tool_type: 'Lti::MessageHandler'
|
||||
)
|
||||
tool_proxy = create_tool_proxy(@assignment.course)
|
||||
tool_proxy[:raw_data]['tool_profile'] = {'service_offered' => [submission_event_service]}
|
||||
tool_proxy.save!
|
||||
|
||||
Lti::ResourceHandler.create!(
|
||||
tool_proxy: tool_proxy,
|
||||
name: 'resource_handler',
|
||||
resource_type_code: 'resource-type-code'
|
||||
)
|
||||
|
||||
expect_event('assignment_created',
|
||||
hash_including(
|
||||
associated_integration_id: "turnitin.com_turnitin-lti_test.com/submission"
|
||||
|
@ -1001,8 +1044,12 @@ describe Canvas::LiveEvents do
|
|||
end
|
||||
|
||||
it 'should not include the associated_integration_id if there is no longer an installed tool with that id' do
|
||||
@assignment.assignment_configuration_tool_lookups.create!(tool_product_code: 'turnitin-lti',
|
||||
tool_vendor_code: 'turnitin.com', tool_type: 'Lti::MessageHandler')
|
||||
@assignment.assignment_configuration_tool_lookups.create!(
|
||||
tool_product_code: 'turnitin-lti',
|
||||
tool_vendor_code: 'turnitin.com',
|
||||
tool_resource_type_code: 'resource-type-code',
|
||||
tool_type: 'Lti::MessageHandler'
|
||||
)
|
||||
|
||||
expect_event('assignment_created',
|
||||
hash_not_including(
|
||||
|
@ -1056,12 +1103,23 @@ describe Canvas::LiveEvents do
|
|||
end
|
||||
|
||||
it 'should include the associated_integration_id if there is an installed tool proxy with that id' do
|
||||
@assignment.assignment_configuration_tool_lookups.create!(tool_product_code: 'turnitin-lti',
|
||||
tool_vendor_code: 'turnitin.com', tool_type: 'Lti::MessageHandler')
|
||||
@assignment.assignment_configuration_tool_lookups.create!(
|
||||
tool_product_code: 'turnitin-lti',
|
||||
tool_vendor_code: 'turnitin.com',
|
||||
tool_resource_type_code: 'resource-type-code',
|
||||
tool_type: 'Lti::MessageHandler'
|
||||
)
|
||||
|
||||
tool_proxy = create_tool_proxy(@assignment.course)
|
||||
tool_proxy[:raw_data]['tool_profile'] = {'service_offered' => [submission_event_service]}
|
||||
tool_proxy.save!
|
||||
|
||||
Lti::ResourceHandler.create!(
|
||||
tool_proxy: tool_proxy,
|
||||
name: 'resource_handler',
|
||||
resource_type_code: 'resource-type-code'
|
||||
)
|
||||
|
||||
expect_event('assignment_updated',
|
||||
hash_including(
|
||||
associated_integration_id: "turnitin.com_turnitin-lti_test.com/submission"
|
||||
|
|
|
@ -108,6 +108,7 @@ RSpec.shared_context "lti2_spec_helper", :shared_context => :metadata do
|
|||
},
|
||||
lti_version: '1'
|
||||
)
|
||||
|
||||
Lti::ToolProxyBinding.where(context_id: context.id, context_type: context.class.to_s,
|
||||
tool_proxy_id: tp).first_or_create!
|
||||
tp
|
||||
|
|
|
@ -195,7 +195,7 @@ module Lti
|
|||
end
|
||||
end
|
||||
|
||||
describe '#find_all_proxies_for_context_by_context_order_by_vendor_product_code' do
|
||||
describe '#proxies_in_order_by_codes' do
|
||||
let(:course) { course_model(account: sub_account_2_1) }
|
||||
|
||||
it 'returns tool proxies in context hierarchy order' do
|
||||
|
@ -206,7 +206,12 @@ module Lti
|
|||
tool_proxy3 = create_tool_proxy(context: course)
|
||||
tool_proxy3.bindings.create!(context: course)
|
||||
|
||||
tools = described_class.find_all_proxies_for_context_by_context_order_by_vendor_product_code(context: course, vendor_code: '123', product_code: 'abc')
|
||||
tools = described_class.proxies_in_order_by_codes(
|
||||
context: course,
|
||||
vendor_code: '123',
|
||||
product_code: 'abc',
|
||||
resource_type_code: 'resource-type-code'
|
||||
)
|
||||
expect(tools.map(&:id)).to eq([tool_proxy3.id, tool_proxy2.id, tool_proxy1.id])
|
||||
end
|
||||
|
||||
|
@ -220,7 +225,12 @@ module Lti
|
|||
tool_proxy4 = create_tool_proxy(context: course)
|
||||
tool_proxy4.bindings.create!(context: course)
|
||||
|
||||
tools = described_class.find_all_proxies_for_context_by_context_order_by_vendor_product_code(context: course, vendor_code: '123', product_code: 'abc')
|
||||
tools = described_class.proxies_in_order_by_codes(
|
||||
context: course,
|
||||
vendor_code: '123',
|
||||
product_code: 'abc',
|
||||
resource_type_code: 'resource-type-code'
|
||||
)
|
||||
expect(tools.map(&:id)).to eq([tool_proxy4.id, tool_proxy3.id, tool_proxy2.id, tool_proxy1.id])
|
||||
end
|
||||
|
||||
|
@ -228,16 +238,47 @@ module Lti
|
|||
tool_proxy = create_tool_proxy(context: sub_account_2_1)
|
||||
tool_proxy.bindings.create!(context: sub_account_2_1, enabled: false)
|
||||
tool_proxy.bindings.create!(context: sub_account_1_1)
|
||||
proxies = described_class.find_all_proxies_for_context_by_context_order_by_vendor_product_code(context: sub_account_2_1, vendor_code: '123', product_code: 'abc')
|
||||
proxies = described_class.proxies_in_order_by_codes(
|
||||
context: sub_account_2_1,
|
||||
vendor_code: '123',
|
||||
product_code: 'abc',
|
||||
resource_type_code: 'resource-type-code'
|
||||
)
|
||||
expect(proxies.count).to eq 0
|
||||
end
|
||||
|
||||
it "doesn't return deleted tool proxies" do
|
||||
tool_proxy = create_tool_proxy(context: sub_account_2_1, workflow_state: 'deleted')
|
||||
tool_proxy.bindings.create!(context: sub_account_2_1)
|
||||
proxies = described_class.find_all_proxies_for_context_by_context_order_by_vendor_product_code(context: sub_account_2_1, vendor_code: '123', product_code: 'abc')
|
||||
proxies = described_class.proxies_in_order_by_codes(
|
||||
context: sub_account_2_1,
|
||||
vendor_code: '123',
|
||||
product_code: 'abc',
|
||||
resource_type_code: 'resource-type-code'
|
||||
)
|
||||
expect(proxies.count).to eq 0
|
||||
end
|
||||
|
||||
it "does not return tools with mismatched resource type codes" do
|
||||
tool_proxy1 = create_tool_proxy(context: root_account)
|
||||
tool_proxy1.bindings.create!(context: root_account)
|
||||
tool_proxy2 = create_tool_proxy(context: root_account)
|
||||
tool_proxy2.bindings.create!(context: root_account)
|
||||
tool_proxy3 = create_tool_proxy(context: course)
|
||||
tool_proxy3.bindings.create!(context: course)
|
||||
tool_proxy4 = create_tool_proxy(context: course)
|
||||
tool_proxy4.bindings.create!(context: course)
|
||||
|
||||
tool_proxy4.resources.first.update!(resource_type_code: 'changed!')
|
||||
|
||||
tools = described_class.proxies_in_order_by_codes(
|
||||
context: course,
|
||||
vendor_code: '123',
|
||||
product_code: 'abc',
|
||||
resource_type_code: 'resource-type-code'
|
||||
)
|
||||
expect(tools.map(&:id)).to eq([tool_proxy3.id, tool_proxy2.id, tool_proxy1.id])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#find_active_proxies_for_context_by_vendor_code_and_product_code" do
|
||||
|
@ -318,7 +359,19 @@ module Lti
|
|||
workflow_state: 'active',
|
||||
raw_data: 'some raw data'
|
||||
}
|
||||
ToolProxy.create(default_opts.merge(opts))
|
||||
|
||||
tp = ToolProxy.create(default_opts.merge(opts))
|
||||
create_resource_handler(tp)
|
||||
tp
|
||||
end
|
||||
|
||||
def create_resource_handler(tool_proxy)
|
||||
return unless tool_proxy.persisted?
|
||||
Lti::ResourceHandler.create!(
|
||||
tool_proxy: tool_proxy,
|
||||
name: 'resource_handler',
|
||||
resource_type_code: 'resource-type-code'
|
||||
)
|
||||
end
|
||||
|
||||
context "singleton message handlers" do
|
||||
|
|
Loading…
Reference in New Issue