Skip to content

Commit 28fa95e

Browse files
committed
fix problems with lti2 and assignments
fixes PLAT-1371 test plan: create an LTI 2 assignment it should launch create and LTI 2 assignment that is a module item it should launch Change-Id: I9cb77477a5d8eec7742c90e5a3c501fc9b6cdce6 Reviewed-on: https://gerrit.instructure.com/76300 Tested-by: Jenkins Reviewed-by: Matthew Wheeler <mwheeler@instructure.com> QA-Review: Benjamin Christian Nelson <bcnelson@instructure.com> Product-Review: Nathan Mills <nathanm@instructure.com>
1 parent 3d9a24d commit 28fa95e

11 files changed

Lines changed: 150 additions & 77 deletions

app/controllers/application_controller.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,6 +1327,7 @@ def content_tag_redirect(context, tag, error_redirect_symbol, tag_type=nil)
13271327
elsif tag.content_type == 'Rubric'
13281328
redirect_to named_context_url(context, :context_rubric_url, tag.content_id, url_params)
13291329
elsif tag.content_type == 'Lti::MessageHandler'
1330+
url_params[:module_item_id] = params[:module_item_id] if params[:module_item_id]
13301331
url_params[:resource_link_fragment] = "ContentTag:#{tag.id}"
13311332
redirect_to named_context_url(context, :context_basic_lti_launch_request_url, tag.content_id, url_params)
13321333
elsif tag.content_type == 'ExternalUrl'

app/controllers/lti/message_controller.rb

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,11 @@ def basic_lti_launch_request
100100
@lti_launch.link_text = resource_handler.name
101101
@lti_launch.launch_type = message.launch_presentation_document_target
102102

103-
module_sequence(message_handler)
104-
tool_setting_ids = prep_tool_settings(message_handler.parameters, tool_proxy, message.resource_link_id)
105-
message.add_custom_params(custom_params(message_handler.parameters, tool_setting_ids.merge(tool: tool_proxy)))
103+
tag = find_tag
104+
module_sequence(tag) if tag
105+
custom_param_opts = prep_tool_settings(message_handler.parameters, tool_proxy, message.resource_link_id)
106+
custom_param_opts[:content_tag] = tag if tag
107+
message.add_custom_params(custom_params(message_handler.parameters, custom_param_opts.merge(tool: tool_proxy)))
106108
message.add_custom_params(ToolSetting.custom_settings(tool_proxy.id, @context, message.resource_link_id))
107109
@lti_launch.params = message.signed_post_params(tool_proxy.shared_secret)
108110

@@ -127,21 +129,19 @@ def registration_return
127129

128130
private
129131

130-
def module_sequence(message_handler)
132+
def module_sequence(tag)
131133
env_hash = {}
132-
if params[:module_item_id]
133-
@tag = ContextModuleItem.find_tag_with_preferred([message_handler], params[:module_item_id])
134-
@lti_launch.launch_type = 'window' if @tag.new_tab
135-
@tag.context_module_action(@current_user, :read)
136-
sequence_asset = @tag.try(:content)
137-
if sequence_asset
138-
env_hash[:SEQUENCE] = {
139-
:ASSET_ID => sequence_asset.id,
140-
:COURSE_ID => @context.id,
141-
}
142-
js_hash = {:LTI => env_hash}
143-
js_env(js_hash)
144-
end
134+
tag = @context.context_module_tags.not_deleted.find(params[:module_item_id])
135+
@lti_launch.launch_type = 'window' if tag.new_tab
136+
tag.context_module_action(@current_user, :read)
137+
sequence_asset = tag.try(:content)
138+
if sequence_asset
139+
env_hash[:SEQUENCE] = {
140+
:ASSET_ID => sequence_asset.id,
141+
:COURSE_ID => @context.id,
142+
}
143+
js_hash = {:LTI => env_hash}
144+
js_env(js_hash)
145145
end
146146
end
147147

@@ -172,7 +172,6 @@ def create_variable_expander(opts = {})
172172
default_opts = {
173173
current_user: @current_user,
174174
current_pseudonym: @current_pseudonym,
175-
content_tag: @tag,
176175
assignment: nil
177176
}
178177
VariableExpander.new(@domain_root_account, @context, self, default_opts.merge(opts))
@@ -212,5 +211,9 @@ def prep_tool_settings(parameters, tool_proxy, resource_link_id)
212211
end
213212
end
214213

214+
def find_tag
215+
@context.context_module_tags.not_deleted.where(id: params[:module_item_id]).first if params[:module_item_id]
216+
end
217+
215218
end
216219
end

app/models/assignment.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ class Assignment < ActiveRecord::Base
8282
# only accept the url, content_type, content_id, and new_tab params, the other accessible
8383
# params don't apply to an content tag being used as an external_tool_tag
8484
content = case attrs['content_type']
85-
when 'Lti::MessageHandler'
86-
Lti::MessageHandler.find(attrs['content_id'].to_i)
87-
when 'ContextExternalTool'
88-
ContextExternalTool.find(attrs['content_id'].to_i)
85+
when 'Lti::MessageHandler', 'lti/message_handler'
86+
Lti::MessageHandler.find(attrs['content_id'].to_i)
87+
when 'ContextExternalTool', 'context_external_tool'
88+
ContextExternalTool.find(attrs['content_id'].to_i)
8989
end
9090
attrs[:content] = content if content
9191
attrs.slice!(:url, :new_tab, :content)

spec/apis/lti/lti_app_api_spec.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@
1717
#
1818

1919
require File.expand_path(File.dirname(__FILE__) + '/../api_spec_helper')
20-
require File.expand_path(File.dirname(__FILE__) + '/../../lti_spec_helper.rb')
2120

2221
module Lti
23-
describe LtiAppsController, type: :request do
22+
describe LtiAppsController, :include_lti_spec_helpers, type: :request do
2423

25-
let (:account) { Account.create }
24+
let(:account) { Account.create }
2625
describe '#launch_definitions' do
2726

2827
before do

spec/apis/lti/tool_proxy_api_spec.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@
1717
#
1818

1919
require File.expand_path(File.dirname(__FILE__) + '/../api_spec_helper')
20-
require File.expand_path(File.dirname(__FILE__) + '/../../lti_spec_helper.rb')
2120
require 'webmock'
2221
WebMock.allow_net_connect!
2322

2423
module Lti
25-
describe ToolProxyController, type: :request do
24+
describe ToolProxyController, :include_lti_spec_helpers, type: :request do
2625

2726
let(:account) { Account.create }
2827

spec/apis/v1/assignments_api_spec.rb

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
require File.expand_path(File.dirname(__FILE__) + '/../locked_spec')
2121
require File.expand_path(File.dirname(__FILE__) + '/../../sharding_spec_helper')
2222

23-
describe AssignmentsApiController, type: :request do
23+
describe AssignmentsApiController, :include_lti_spec_helpers, type: :request do
2424
include Api
2525
include Api::V1::Assignment
2626
include Api::V1::Submission
@@ -2556,6 +2556,49 @@ def visibility_api_request(assignment)
25562556
@assignment = @course.assignments.create!(:title => "some assignment")
25572557
end
25582558

2559+
it 'updates the external tool content_id' do
2560+
mh = create_message_handler(create_resource_handler(create_tool_proxy))
2561+
tool_tag = ContentTag.new(url: 'http://www.example.com', new_tab: false, tag_type: 'context_module')
2562+
tool_tag.context = @assignment
2563+
tool_tag.save!
2564+
params = {
2565+
"submission_types" => ["external_tool"],
2566+
"external_tool_tag_attributes" => {
2567+
"url" => "https://testvmserver.test.com/canvas/test/",
2568+
"content_type" => "lti/message_handler",
2569+
"content_id" => mh.id,
2570+
"new_tab" => "0"
2571+
}
2572+
}
2573+
assignment = update_from_params(@assignment, params, @user)
2574+
tag = assignment.external_tool_tag
2575+
expect(tag.content_id).to eq mh.id
2576+
expect(tag.content_type).to eq "Lti::MessageHandler"
2577+
end
2578+
2579+
it 'sets the context external tool type' do
2580+
tool = ContextExternalTool.new( name: 'test tool', consumer_key:'test',
2581+
shared_secret: 'shh', url: 'http://www.example.com')
2582+
tool.context = @course
2583+
tool.save!
2584+
tool_tag = ContentTag.new(url: 'http://www.example.com', new_tab: false, tag_type: 'context_module')
2585+
tool_tag.context = @assignment
2586+
tool_tag.save!
2587+
params = {
2588+
"submission_types" => ["external_tool"],
2589+
"external_tool_tag_attributes" => {
2590+
"url" => "https://testvmserver.test.com/canvas/test/",
2591+
"content_type" => "context_external_tool",
2592+
"content_id" => tool.id,
2593+
"new_tab" => "0"
2594+
}
2595+
}
2596+
assignment = update_from_params(@assignment, params, @user)
2597+
tag = assignment.external_tool_tag
2598+
expect(tag.content_id).to eq tool.id
2599+
expect(tag.content_type).to eq "ContextExternalTool"
2600+
end
2601+
25592602
it "does not update integration_data when lacking permission" do
25602603
json = %{{"key": "value"}}
25612604
params = {"integration_data" => json}

spec/controllers/lti/message_controller_spec.rb

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,17 @@ module Lti
222222
expect(params[:oauth_signature]).not_to be_empty
223223
end
224224

225+
it 'launches gracefully if it can not find the content_tag for the given module_item_id' do
226+
course = Course.create!
227+
tag = course.context_module_tags.create!(context: account, tag_type: 'context_module')
228+
tag.context_module = ContextModule.create!(context: course)
229+
tag.save!
230+
tag.delete
231+
get 'basic_lti_launch_request', course_id: course.id, message_handler_id: message_handler.id,
232+
module_item_id: tag.id, params: {tool_launch_context: 'my_custom_context' }
233+
expect(response.code).to eq "200"
234+
end
235+
225236
it 'sets the active tab' do
226237
get 'basic_lti_launch_request', account_id: account.id, message_handler_id: message_handler.id
227238
expect(response.code).to eq "200"
@@ -257,17 +268,18 @@ module Lti
257268
end
258269

259270
it 'adds module item substitutions' do
271+
course = Course.create!
260272
parameters = %w( Canvas.module.id Canvas.moduleItem.id ).map do |key|
261273
IMS::LTI::Models::Parameter.new(name: key.underscore, variable: key )
262274
end
263275
message_handler.parameters = parameters.as_json
264276
message_handler.save
265277

266-
tag = message_handler.context_module_tags.create!(context: account, tag_type: 'context_module')
267-
tag.context_module = ContextModule.create!(context: Course.create!)
278+
tag = message_handler.context_module_tags.create!(context: course, tag_type: 'context_module')
279+
tag.context_module = ContextModule.create!(context: course)
268280
tag.save!
269281

270-
get 'basic_lti_launch_request', account_id: account.id, message_handler_id: message_handler.id,
282+
get 'basic_lti_launch_request', course_id: course.id, message_handler_id: message_handler.id,
271283
module_item_id: tag.id, params: {tool_launch_context: 'my_custom_context' }
272284
expect(response.code).to eq "200"
273285

@@ -277,10 +289,11 @@ module Lti
277289
end
278290

279291
it 'sets the launch to window' do
280-
tag = message_handler.context_module_tags.create!(context: account, tag_type: 'context_module', new_tab: true)
281-
tag.context_module = ContextModule.create!(context: Course.create!)
292+
course = Course.create!
293+
tag = message_handler.context_module_tags.create!(context: course, tag_type: 'context_module', new_tab: true)
294+
tag.context_module = ContextModule.create!(context: course)
282295
tag.save!
283-
get 'basic_lti_launch_request', account_id: account.id, message_handler_id: message_handler.id,
296+
get 'basic_lti_launch_request', course_id: course.id, message_handler_id: message_handler.id,
284297
module_item_id: tag.id, params: {tool_launch_context: 'my_custom_context' }
285298
expect(response.code).to eq "200"
286299
expect(assigns[:lti_launch].launch_type).to eq 'window'

spec/lti_spec_helper.rb

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -15,43 +15,56 @@
1515
# You should have received a copy of the GNU Affero General Public License along
1616
# with this program. If not, see <http://www.gnu.org/licenses/>.
1717
#
18+
module LtiSpecHelper
19+
def create_tool_proxy(opts = {})
1820

19-
def create_tool_proxy(opts = {})
20-
default_opts = {
21-
context: account,
22-
shared_secret: 'shared_secret',
23-
guid: SecureRandom.uuid,
24-
product_version: '1.0beta',
25-
lti_version: 'LTI-2p0',
26-
product_family: find_or_create_product_family,
27-
workflow_state: 'active',
28-
raw_data: 'some raw data',
29-
name: (0...8).map { (65 + rand(26)).chr }.join,
30-
}
31-
Lti::ToolProxy.create!(default_opts.merge(opts))
32-
end
21+
default_opts = {
22+
shared_secret: 'shared_secret',
23+
guid: SecureRandom.uuid,
24+
product_version: '1.0beta',
25+
lti_version: 'LTI-2p0',
26+
product_family: find_or_create_product_family,
27+
workflow_state: 'active',
28+
raw_data: 'some raw data',
29+
name: (0...8).map { (65 + rand(26)).chr }.join,
30+
}
31+
combined_opts = default_opts.merge(opts)
32+
combined_opts[:context] = Account.create!(name: 'Test Account') unless combined_opts.has_key?(:context)
33+
combined_opts[:product_family] = find_or_create_product_family(combined_opts[:context]) unless combined_opts.has_key?(:product_family)
34+
Lti::ToolProxy.create!(combined_opts)
35+
end
3336

34-
def find_or_create_product_family(opts = {})
35-
default_opts = {vendor_code: '123', product_code: 'abc', vendor_name: 'acme', root_account_id: account.id}
36-
Lti::ProductFamily.where(default_opts.merge(opts)).first_or_create
37-
end
37+
def find_or_create_product_family(opts = {})
38+
default_opts = {vendor_code: '123', product_code: 'abc', vendor_name: 'acme'}
39+
default_opts[:root_account_id] = Account.create!(name: 'Test Account') unless opts.has_key?(:root_account_id)
40+
Lti::ProductFamily.where(default_opts.merge(opts)).first_or_create
41+
end
3842

39-
def create_resource_handler(tool_proxy, opts = {})
40-
default_opts = {resource_type_code: 'code', name: (0...8).map { (65 + rand(26)).chr }.join, tool_proxy: tool_proxy}
41-
Lti::ResourceHandler.create(default_opts.merge(opts))
42-
end
43+
def create_resource_handler(tool_proxy, opts = {})
44+
default_opts = {resource_type_code: 'code', name: (0...8).map { (65 + rand(26)).chr }.join, tool_proxy: tool_proxy}
45+
Lti::ResourceHandler.create(default_opts.merge(opts))
46+
end
4347

44-
def create_message_handler(resource_handler, opts = {})
45-
default_ops = {message_type: 'basic-lti-launch-request', launch_path: 'https://samplelaunch/blti', resource_handler: resource_handler}
46-
Lti::MessageHandler.create(default_ops.merge(opts))
47-
end
48+
def create_message_handler(resource_handler, opts = {})
49+
default_ops = {
50+
message_type: 'basic-lti-launch-request',
51+
launch_path: 'https://samplelaunch/blti',
52+
resource_handler: resource_handler
53+
}
54+
Lti::MessageHandler.create(default_ops.merge(opts))
55+
end
4856

49-
def new_valid_external_tool(context, resource_selection = false)
50-
tool = context.context_external_tools.new(:name => (0...8).map { (65 + rand(26)).chr }.join,
51-
:consumer_key => "key",
52-
:shared_secret => "secret")
53-
tool.url = "http://www.example.com/basic_lti"
54-
tool.resource_selection = {:url => "http://example.com/selection_test", :selection_width => 400, :selection_height => 400} if resource_selection
55-
tool.save!
56-
tool
57+
def new_valid_external_tool(context, resource_selection = false)
58+
tool = context.context_external_tools.new(:name => (0...8).map { (65 + rand(26)).chr }.join,
59+
:consumer_key => "key",
60+
:shared_secret => "secret")
61+
tool.url = "http://www.example.com/basic_lti"
62+
tool.resource_selection = {
63+
:url => "http://example.com/selection_test",
64+
:selection_width => 400,
65+
:selection_height => 400
66+
} if resource_selection
67+
tool.save!
68+
tool
69+
end
5770
end

spec/models/lti/app_collator_spec.rb

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616
#
1717

1818
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper.rb')
19-
require File.expand_path(File.dirname(__FILE__) + '/../../lti_spec_helper.rb')
2019

2120
module Lti
22-
describe AppCollator do
21+
describe AppCollator, :include_lti_spec_helpers do
2322

2423
subject { described_class.new(account, mock_reregistration_url_builder)}
2524
let(:account) { Account.create }
@@ -46,7 +45,7 @@ module Lti
4645
describe "#app_definitions" do
4746

4847
it 'returns tool_proxy app definitions' do
49-
tool_proxy = create_tool_proxy
48+
tool_proxy = create_tool_proxy(context: account)
5049
tool_proxy.bindings.create(context: account)
5150
tools_collection = subject.bookmarked_collection.paginate(per_page: 100).to_a
5251
definitions = subject.app_definitions(tools_collection)
@@ -137,7 +136,7 @@ module Lti
137136
it 'has_update set to false for tool proxies without an update_payload' do
138137
account.root_account.enable_feature!(:lti2_rereg)
139138

140-
tool_proxy = create_tool_proxy
139+
tool_proxy = create_tool_proxy(context: account)
141140
tool_proxy.bindings.create(context: account)
142141

143142
tools_collection = subject.bookmarked_collection.paginate(per_page: 100).to_a
@@ -162,7 +161,7 @@ module Lti
162161
it 'has_update set to true for tool proxies with an update_payload' do
163162
account.root_account.enable_feature!(:lti2_rereg)
164163

165-
tool_proxy = create_tool_proxy
164+
tool_proxy = create_tool_proxy(context: account)
166165
tool_proxy.bindings.create(context: account)
167166
tool_proxy.update_payload = {one: 2}
168167
tool_proxy.save!

spec/models/lti/app_launch_collator_spec.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
#
1818

1919
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper.rb')
20-
require File.expand_path(File.dirname(__FILE__) + '/../../lti_spec_helper.rb')
2120

2221
module Lti
23-
describe AppLaunchCollator do
24-
let (:account) { Account.create }
25-
let (:resource_handler) { ResourceHandler.create(resource_type_code: 'code', name: 'resource name', tool_proxy: tool_proxy) }
22+
describe AppLaunchCollator, :include_lti_spec_helpers do
23+
let(:account) { Account.create }
24+
let(:resource_handler) do
25+
ResourceHandler.create(resource_type_code: 'code', name: 'resource name', tool_proxy: tool_proxy)
26+
end
2627

2728
describe "#launch_definitions" do
2829

0 commit comments

Comments
 (0)