create method to find active tool_proxies for a context

fixes PLAT-640

test-plan:
specs should pass

Change-Id: Ia958982b1ff786dbafbaa88e3c080a4b61627d04
Reviewed-on: https://gerrit.instructure.com/40969
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Brad Humphrey <brad@instructure.com>
QA-Review: Nathan Mills <nathanm@instructure.com>
Product-Review: Nathan Mills <nathanm@instructure.com>
This commit is contained in:
Nathan Mills 2014-09-11 13:25:12 -06:00
parent fb5ae7db75
commit 910ad0ca7d
4 changed files with 125 additions and 6 deletions

View File

@ -34,5 +34,17 @@ module Lti
validates_uniqueness_of :guid
validates_inclusion_of :workflow_state, in: ['active', 'deleted', 'disabled']
def self.find_active_proxies_for_context(context)
account_ids = context.account_chain.map { |a| a.id }
account_sql_string = account_ids.each_with_index.map { |x, i| "('Account',#{x},#{i})" }.unshift("('#{context.class.name}',#{context.id},#{0})").join(',')
subquery = ToolProxyBinding.select('DISTINCT ON (lti_tool_proxies.id) lti_tool_proxy_bindings.*').joins(:tool_proxy).where('lti_tool_proxies.workflow_state = ?', 'active').
joins("INNER JOIN ( VALUES #{account_sql_string}) as x(context_type, context_id, ordering) ON lti_tool_proxy_bindings.context_type = x.context_type AND lti_tool_proxy_bindings.context_id = x.context_id").
where('(lti_tool_proxy_bindings.context_type = ? AND lti_tool_proxy_bindings.context_id = ?) OR (lti_tool_proxy_bindings.context_type = ? AND lti_tool_proxy_bindings.context_id IN (?))', context.class.name, context.id, 'Account', account_ids).
order('lti_tool_proxies.id, x.ordering').to_sql
ToolProxy.joins("JOIN (#{subquery}) bindings on lti_tool_proxies.id = bindings.tool_proxy_id").where('bindings.enabled = true')
end
end
end

View File

@ -25,7 +25,7 @@ module Lti
belongs_to :context, :polymorphic => true
has_many :links, :class_name => 'Lti::LtiLink', foreign_key: 'tool_proxy_binding_id'
validates_presence_of :tool_proxy, :context, :enabled
validates_presence_of :tool_proxy, :context
validates_inclusion_of :context_type, :allow_nil => true, :in => ['Course', 'Account']
end

View File

@ -975,6 +975,16 @@ describe Account do
@account3.account_chain.should == [@account3, @account2, @account1]
end
end
it "returns parent accounts in order up the tree" do
account1 = Account.create!
account2 = account1.sub_accounts.create!
account3 = account2.sub_accounts.create!
account4 = account3.sub_accounts.create!
account4.account_chain.should == [account4, account3, account2, account1]
end
end
describe "#can_see_admin_tools_tab?" do

View File

@ -20,9 +20,9 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper.rb')
module Lti
describe ToolProxy do
let (:account) {Account.create}
let (:product_family) {ProductFamily.create(vendor_code: '123', product_code:'abc', vendor_name:'acme', root_account:account)}
let (:resource_handler) {ResourceHandler.new}
let (:account) { Account.create }
let (:product_family) { ProductFamily.create(vendor_code: '123', product_code: 'abc', vendor_name: 'acme', root_account: account) }
let (:resource_handler) { ResourceHandler.new }
describe 'validations' do
@ -40,14 +40,14 @@ module Lti
it 'requires a shared_secret' do
subject.shared_secret = nil
subject.save
error = subject.errors.find {|e| e == [:shared_secret, "can't be blank"]}
error = subject.errors.find { |e| e == [:shared_secret, "can't be blank"] }
error.should_not == nil
end
it 'requires a guid' do
subject.guid = nil
subject.save
error = subject.errors.find {|e| e == [:guid, "can't be blank"]}
error = subject.errors.find { |e| e == [:guid, "can't be blank"] }
error.should_not == nil
end
@ -102,6 +102,103 @@ module Lti
subject.errors[:raw_data].should include("can't be blank")
end
describe "#find_active_proxies_for_context" do
let(:root_account) { Account.create }
let(:sub_account_1_1) { Account.create(parent_account: root_account) }
let(:sub_account_1_2) { Account.create(parent_account: root_account) }
let(:sub_account_2_1) { Account.create(parent_account: sub_account_1_1) }
it 'finds a tool_proxy' do
tool_proxy = create_tool_proxy(context: sub_account_2_1)
tool_proxy.bindings.create!(context: sub_account_2_1)
proxies = described_class.find_active_proxies_for_context(sub_account_2_1)
proxies.count.should == 1
proxies.first.should == tool_proxy
end
it 'finds a tool_proxy for a parent account' do
tool_proxy = create_tool_proxy(context: sub_account_1_1)
tool_proxy.bindings.create!(context: sub_account_1_1)
proxies = described_class.find_active_proxies_for_context(sub_account_2_1)
proxies.count.should == 1
proxies.first.should == tool_proxy
end
it 'finds a tool_proxy for a course binding' do
course = Course.create!(account: sub_account_2_1)
tool_proxy = create_tool_proxy(context: course)
tool_proxy.bindings.create!(context: course)
proxies = described_class.find_active_proxies_for_context(course)
proxies.count.should == 1
proxies.first.should == tool_proxy
end
it "doesn't return tool_proxies that are disabled" do
tool_proxy = create_tool_proxy(context: sub_account_2_1, workflow_state: 'disabled')
tool_proxy.bindings.create!(context: sub_account_2_1)
proxies = described_class.find_active_proxies_for_context(sub_account_2_1)
proxies.count.should == 0
end
it "doesn't return tool_proxies that are deleted" 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_active_proxies_for_context(sub_account_2_1)
proxies.count.should == 0
end
it "doesn't return tool_proxies when closest ancestor is disabled" do
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_active_proxies_for_context(sub_account_2_1)
proxies.count.should == 0
end
it 'handles multiple tool_proxies' do
tool_proxy1 = create_tool_proxy(context: sub_account_2_1)
tool_proxy1.bindings.create!(context: sub_account_2_1)
tool_proxy2 = create_tool_proxy(context: sub_account_1_1)
tool_proxy2.bindings.create!(context: sub_account_1_1)
proxies = described_class.find_active_proxies_for_context(sub_account_2_1)
proxies.count.should == 2
proxies.should include(tool_proxy1)
proxies.should include(tool_proxy2)
end
it 'handles multiple bindings' do
tool_proxy = create_tool_proxy(context: sub_account_1_1)
tool_proxy.bindings.create!(context: sub_account_1_1)
tool_proxy.bindings.create!(context: sub_account_2_1)
proxies = described_class.find_active_proxies_for_context(sub_account_2_1)
proxies.count.should == 1
proxies.first.should == tool_proxy
end
it "doesn't return tool proxies that are enabled at a higher binding and disabled at a lower binding" do
tool_proxy = create_tool_proxy(context: sub_account_1_1)
tool_proxy.bindings.create!(context: sub_account_1_1)
tool_proxy.bindings.create!(context: sub_account_2_1, enabled: false)
proxies = described_class.find_active_proxies_for_context(sub_account_2_1)
proxies.count.should == 0
end
end
end
def create_tool_proxy(opts = {})
default_opts = {
shared_secret: 'shared_secret',
guid: SecureRandom.uuid,
product_version: '1.0beta',
lti_version: 'LTI-2p0',
product_family: product_family,
workflow_state: 'active',
raw_data: 'some raw data'
}
ToolProxy.create(default_opts.merge(opts))
end
end