add migration_selection lti extension

this commit lets canvas remember that an LTI has this extension.
launching and using LTI for content migrations will happen
separately.

refs LOR-20

test plan:
 - configure an LTI tool with XML that includes the
   migration_selection extension
 - the tool should show up in the tool list with the "Migration
   Selection" tag.

Change-Id: I880125515a32af1b9a39fbd1787617bceae74f50
Reviewed-on: https://gerrit.instructure.com/21442
Reviewed-by: Jake Trent <jaketrent@instructure.com>
Reviewed-by: Bracken Mosbacker <bracken@instructure.com>
Reviewed-by: Brad Humphrey <brad@instructure.com>
QA-Review: Amber Taniuchi <amber@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
Product-Review: Jon Willesen <jonw@instructure.com>
This commit is contained in:
Jon Willesen 2014-04-15 09:37:56 -06:00
parent 5804d857d9
commit 1f4737ed05
8 changed files with 61 additions and 15 deletions

View File

@ -2,6 +2,7 @@ group :development, :test do
gem 'coffee-script', '2.2.0'
gem 'coffee-script-source', '1.6.2' #pinned so everyone's compiled output matches
gem 'execjs', '1.4.0'
gem 'hashdiff', '0.2.0'
gem 'parallel', '0.5.16'
end

View File

@ -22,6 +22,7 @@ define [
{extension_type: 'account_navigation', text: I18n.t 'account_navigation_configured', 'Account navigation configured'}
{extension_type: 'user_navigation', text: I18n.t 'user_navigation_configured', 'User navigation configured'}
{extension_type: 'homework_submission', text: I18n.t 'homework_submission_configured', 'Homework submission configured'}
{extension_type: 'migration_selection', text: I18n.t 'migration_selection_configured', 'Migration selection configured'}
]
json = super

View File

@ -36,7 +36,7 @@ class ContextExternalTool < ActiveRecord::Base
can :read and can :update and can :delete
end
EXTENSION_TYPES = [:user_navigation, :course_navigation, :account_navigation, :resource_selection, :editor_button, :homework_submission]
EXTENSION_TYPES = [:user_navigation, :course_navigation, :account_navigation, :resource_selection, :editor_button, :homework_submission, :migration_selection]
def url_or_domain_is_set
setting_types = EXTENSION_TYPES
# url or domain (or url on canvas lti extension) is required
@ -232,6 +232,14 @@ class ContextExternalTool < ActiveRecord::Base
extension_setting(:homework_submission, setting)
end
def migration_selection=(hash)
tool_setting(:migration_selection, hash, :selection_width, :selection_height, :icon_url)
end
def migration_selection(setting = nil)
extension_setting(:migration_selection, setting)
end
def icon_url=(i_url)
settings[:icon_url] = i_url
end
@ -278,7 +286,7 @@ class ContextExternalTool < ActiveRecord::Base
settings[:selection_width] = settings[:selection_width].to_i if settings[:selection_width]
settings[:selection_height] = settings[:selection_height].to_i if settings[:selection_height]
[:resource_selection, :editor_button, :homework_submission].each do |type|
EXTENSION_TYPES.each do |type|
if settings[type]
settings[type][:selection_width] = settings[type][:selection_width].to_i if settings[type][:selection_width]
settings[type][:selection_height] = settings[type][:selection_height].to_i if settings[type][:selection_height]

View File

@ -0,0 +1,12 @@
class AddMigrationSelectionForExternalTools < ActiveRecord::Migration
tag :predeploy
def self.up
add_column :context_external_tools, :has_migration_selection, :boolean
add_index :context_external_tools, [:context_id, :context_type, :has_migration_selection], :name => "external_tools_migration_selection"
end
def self.down
remove_column :context_external_tools, :has_migration_selection
remove_index :context_external_tools, :name => "external_tools_migration_selection"
end
end

View File

@ -114,6 +114,18 @@ module LtiOutbound
hash['tool_consumer_info_product_family_code'] = 'canvas'
hash['tool_consumer_info_version'] = 'cloud'
tool.set_custom_fields(hash, resource_type)
set_resource_type_keys()
hash['oauth_callback'] = 'about:blank'
variable_substitutor = VariableSubstitutor.new
variable_substitutor.substitute_all!(hash, user, assignment, context, consumer_instance)
self.class.generate_params(hash, url, tool.consumer_key, tool.shared_secret)
end
private
def set_resource_type_keys
if resource_type == 'editor_button'
hash['selection_directive'] = 'embed_content' #backwards compatibility
hash['ext_content_intended_use'] = 'embed'
@ -127,17 +139,14 @@ module LtiOutbound
elsif resource_type == 'homework_submission'
hash['ext_content_intended_use'] = 'homework'
hash['ext_content_return_url'] = return_url
elsif resource_type == 'migration_selection'
hash['ext_content_intended_use'] = 'content_package'
hash['ext_content_return_types'] = 'file'
hash['ext_content_file_extensions'] = 'zip,imscc'
hash['ext_content_return_url'] = return_url
end
hash['oauth_callback'] = 'about:blank'
variable_substitutor = VariableSubstitutor.new
variable_substitutor.substitute_all!(hash, user, assignment, context, consumer_instance)
self.class.generate_params(hash, url, tool.consumer_key, tool.shared_secret)
end
private
def self.generate_params(params, url, key, secret)
uri = URI.parse(url)

View File

@ -133,7 +133,7 @@ describe ExternalToolsController, type: :request do
{:controller => 'external_tools', :action => 'show', :format => 'json',
:"#{type}_id" => context.id.to_s, :external_tool_id => et.id.to_s})
json.diff(example_json(et)).should == {}
HashDiff.diff(json, example_json(et)).should == []
end
def not_found_call(context, type="course")
@ -151,7 +151,7 @@ describe ExternalToolsController, type: :request do
:"#{type}_id" => context.id.to_s})
json.size.should == 1
json.first.diff(example_json(et)).should == {}
HashDiff.diff(json.first, example_json(et)).should == []
end
def search_call(context, type="course")
@ -174,7 +174,7 @@ describe ExternalToolsController, type: :request do
context.context_external_tools.count.should == 1
et = context.context_external_tools.last
json.diff(example_json(et)).should == {}
HashDiff.diff(json, example_json(et)).should == []
end
def update_call(context, type="course")
@ -184,7 +184,7 @@ describe ExternalToolsController, type: :request do
{:controller => 'external_tools', :action => 'update', :format => 'json',
:"#{type}_id" => context.id.to_s, :external_tool_id => et.id.to_s}, post_hash)
et.reload
json.diff(example_json(et)).should == {}
HashDiff.diff(json, example_json(et)).should == []
end
def destroy_call(context, type="course")
@ -258,6 +258,7 @@ describe ExternalToolsController, type: :request do
et.editor_button = {:url=>"http://www.example.com/ims/lti/editor", :icon_url=>"/images/delete.png", :selection_width=>50, :selection_height=>50, :text=>"editor button"}
et.homework_submission = {:url=>"http://www.example.com/ims/lti/editor", :selection_width=>50, :selection_height=>50, :text=>"homework submission"}
et.resource_selection = {:url=>"http://www.example.com/ims/lti/resource", :text => "", :selection_width=>50, :selection_height=>50}
et.migration_selection = {:url=>"http://www.example.com/ims/lti/resource", :text => "migration selection", :selection_width=>42, :selection_height=>24}
et.save!
et
end
@ -319,6 +320,7 @@ describe ExternalToolsController, type: :request do
"url"=>"http://www.example.com/ims/lti",
"id"=>et ? et.id : nil,
"workflow_state"=>"public",
"vendor_help_link"=>nil,
"resource_selection"=>
{"text"=>"",
"url"=>"http://www.example.com/ims/lti/resource",
@ -361,6 +363,12 @@ describe ExternalToolsController, type: :request do
"custom_fields"=>{"key"=>"value"},
"label"=>"Account nav",
"selection_height"=>400,
"selection_width"=>800}}
"selection_width"=>800},
"migration_selection"=>
{"text"=>"migration selection",
"label"=>"migration selection",
"url"=>"http://www.example.com/ims/lti/resource",
"selection_height"=>24,
"selection_width"=>42}}
end
end

View File

@ -48,6 +48,7 @@ define [
"label": "Khan Academy"
},
"homework_submission": null,
"migration_selection": null,
"icon_url": "https://www.edu-apps.org/tools/khan_academy/icon.png"
}
)

View File

@ -154,6 +154,12 @@ shared_examples_for "external tools tests" do
<lticm:property name="url">https://example.com/attendance</lticm:property>
<lticm:property name="text">Attendance</lticm:property>
</lticm:options>
<lticm:options name="migration_selection">
<lticm:property name="url">https://example.com/wiki</lticm:property>
<lticm:property name="text">Build/Link to Wiki Page</lticm:property>
<lticm:property name="selection_width">500</lticm:property>
<lticm:property name="selection_height">300</lticm:property>
</lticm:options>
XML
f("#external_tool_config_xml").send_keys <<-XML
<lticm:options name="user_navigation">