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:
parent
5804d857d9
commit
1f4737ed05
|
@ -2,6 +2,7 @@ group :development, :test do
|
||||||
gem 'coffee-script', '2.2.0'
|
gem 'coffee-script', '2.2.0'
|
||||||
gem 'coffee-script-source', '1.6.2' #pinned so everyone's compiled output matches
|
gem 'coffee-script-source', '1.6.2' #pinned so everyone's compiled output matches
|
||||||
gem 'execjs', '1.4.0'
|
gem 'execjs', '1.4.0'
|
||||||
|
gem 'hashdiff', '0.2.0'
|
||||||
gem 'parallel', '0.5.16'
|
gem 'parallel', '0.5.16'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ define [
|
||||||
{extension_type: 'account_navigation', text: I18n.t 'account_navigation_configured', 'Account navigation configured'}
|
{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: '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: '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
|
json = super
|
||||||
|
|
|
@ -36,7 +36,7 @@ class ContextExternalTool < ActiveRecord::Base
|
||||||
can :read and can :update and can :delete
|
can :read and can :update and can :delete
|
||||||
end
|
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
|
def url_or_domain_is_set
|
||||||
setting_types = EXTENSION_TYPES
|
setting_types = EXTENSION_TYPES
|
||||||
# url or domain (or url on canvas lti extension) is required
|
# url or domain (or url on canvas lti extension) is required
|
||||||
|
@ -232,6 +232,14 @@ class ContextExternalTool < ActiveRecord::Base
|
||||||
extension_setting(:homework_submission, setting)
|
extension_setting(:homework_submission, setting)
|
||||||
end
|
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)
|
def icon_url=(i_url)
|
||||||
settings[:icon_url] = i_url
|
settings[:icon_url] = i_url
|
||||||
end
|
end
|
||||||
|
@ -278,7 +286,7 @@ class ContextExternalTool < ActiveRecord::Base
|
||||||
settings[:selection_width] = settings[:selection_width].to_i if settings[:selection_width]
|
settings[:selection_width] = settings[:selection_width].to_i if settings[:selection_width]
|
||||||
settings[:selection_height] = settings[:selection_height].to_i if settings[:selection_height]
|
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]
|
if settings[type]
|
||||||
settings[type][:selection_width] = settings[type][:selection_width].to_i if settings[type][:selection_width]
|
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]
|
settings[type][:selection_height] = settings[type][:selection_height].to_i if settings[type][:selection_height]
|
||||||
|
|
|
@ -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
|
|
@ -114,6 +114,18 @@ module LtiOutbound
|
||||||
hash['tool_consumer_info_product_family_code'] = 'canvas'
|
hash['tool_consumer_info_product_family_code'] = 'canvas'
|
||||||
hash['tool_consumer_info_version'] = 'cloud'
|
hash['tool_consumer_info_version'] = 'cloud'
|
||||||
tool.set_custom_fields(hash, resource_type)
|
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'
|
if resource_type == 'editor_button'
|
||||||
hash['selection_directive'] = 'embed_content' #backwards compatibility
|
hash['selection_directive'] = 'embed_content' #backwards compatibility
|
||||||
hash['ext_content_intended_use'] = 'embed'
|
hash['ext_content_intended_use'] = 'embed'
|
||||||
|
@ -127,17 +139,14 @@ module LtiOutbound
|
||||||
elsif resource_type == 'homework_submission'
|
elsif resource_type == 'homework_submission'
|
||||||
hash['ext_content_intended_use'] = 'homework'
|
hash['ext_content_intended_use'] = 'homework'
|
||||||
hash['ext_content_return_url'] = return_url
|
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
|
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
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def self.generate_params(params, url, key, secret)
|
def self.generate_params(params, url, key, secret)
|
||||||
uri = URI.parse(url)
|
uri = URI.parse(url)
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,7 @@ describe ExternalToolsController, type: :request do
|
||||||
{:controller => 'external_tools', :action => 'show', :format => 'json',
|
{:controller => 'external_tools', :action => 'show', :format => 'json',
|
||||||
:"#{type}_id" => context.id.to_s, :external_tool_id => et.id.to_s})
|
:"#{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
|
end
|
||||||
|
|
||||||
def not_found_call(context, type="course")
|
def not_found_call(context, type="course")
|
||||||
|
@ -151,7 +151,7 @@ describe ExternalToolsController, type: :request do
|
||||||
:"#{type}_id" => context.id.to_s})
|
:"#{type}_id" => context.id.to_s})
|
||||||
|
|
||||||
json.size.should == 1
|
json.size.should == 1
|
||||||
json.first.diff(example_json(et)).should == {}
|
HashDiff.diff(json.first, example_json(et)).should == []
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_call(context, type="course")
|
def search_call(context, type="course")
|
||||||
|
@ -174,7 +174,7 @@ describe ExternalToolsController, type: :request do
|
||||||
context.context_external_tools.count.should == 1
|
context.context_external_tools.count.should == 1
|
||||||
|
|
||||||
et = context.context_external_tools.last
|
et = context.context_external_tools.last
|
||||||
json.diff(example_json(et)).should == {}
|
HashDiff.diff(json, example_json(et)).should == []
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_call(context, type="course")
|
def update_call(context, type="course")
|
||||||
|
@ -184,7 +184,7 @@ describe ExternalToolsController, type: :request do
|
||||||
{:controller => 'external_tools', :action => 'update', :format => 'json',
|
{:controller => 'external_tools', :action => 'update', :format => 'json',
|
||||||
:"#{type}_id" => context.id.to_s, :external_tool_id => et.id.to_s}, post_hash)
|
:"#{type}_id" => context.id.to_s, :external_tool_id => et.id.to_s}, post_hash)
|
||||||
et.reload
|
et.reload
|
||||||
json.diff(example_json(et)).should == {}
|
HashDiff.diff(json, example_json(et)).should == []
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy_call(context, type="course")
|
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.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.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.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.save!
|
||||||
et
|
et
|
||||||
end
|
end
|
||||||
|
@ -319,6 +320,7 @@ describe ExternalToolsController, type: :request do
|
||||||
"url"=>"http://www.example.com/ims/lti",
|
"url"=>"http://www.example.com/ims/lti",
|
||||||
"id"=>et ? et.id : nil,
|
"id"=>et ? et.id : nil,
|
||||||
"workflow_state"=>"public",
|
"workflow_state"=>"public",
|
||||||
|
"vendor_help_link"=>nil,
|
||||||
"resource_selection"=>
|
"resource_selection"=>
|
||||||
{"text"=>"",
|
{"text"=>"",
|
||||||
"url"=>"http://www.example.com/ims/lti/resource",
|
"url"=>"http://www.example.com/ims/lti/resource",
|
||||||
|
@ -361,6 +363,12 @@ describe ExternalToolsController, type: :request do
|
||||||
"custom_fields"=>{"key"=>"value"},
|
"custom_fields"=>{"key"=>"value"},
|
||||||
"label"=>"Account nav",
|
"label"=>"Account nav",
|
||||||
"selection_height"=>400,
|
"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
|
||||||
end
|
end
|
||||||
|
|
|
@ -48,6 +48,7 @@ define [
|
||||||
"label": "Khan Academy"
|
"label": "Khan Academy"
|
||||||
},
|
},
|
||||||
"homework_submission": null,
|
"homework_submission": null,
|
||||||
|
"migration_selection": null,
|
||||||
"icon_url": "https://www.edu-apps.org/tools/khan_academy/icon.png"
|
"icon_url": "https://www.edu-apps.org/tools/khan_academy/icon.png"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -154,6 +154,12 @@ shared_examples_for "external tools tests" do
|
||||||
<lticm:property name="url">https://example.com/attendance</lticm:property>
|
<lticm:property name="url">https://example.com/attendance</lticm:property>
|
||||||
<lticm:property name="text">Attendance</lticm:property>
|
<lticm:property name="text">Attendance</lticm:property>
|
||||||
</lticm:options>
|
</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
|
XML
|
||||||
f("#external_tool_config_xml").send_keys <<-XML
|
f("#external_tool_config_xml").send_keys <<-XML
|
||||||
<lticm:options name="user_navigation">
|
<lticm:options name="user_navigation">
|
||||||
|
|
Loading…
Reference in New Issue