add tool_id and icon url to context_external_tools
tool_id can be used to associate multiple context_external_tools with a single third party tool (i.e. to see how many installs there are of the youtube tool). When tools are launched Canvas will also track a custom ganalytics event with this tool id. icon_url is an attribute that can be set in standard LTI config that we were ignoring before. In the future this may be added to the UI when picking external tools. test plan: - find an external tool with tool_id and icon configs (there are some examples on lti-examples.heroku.com) - configure an external tool using this xml - confirm that tool_id and icon_url were correctly set (tool.tool_id and tool.settings[:icon_url]) - launch an external tool from within a course - make sure that nothing breaks Change-Id: If8d6386e8a919fa70eacd46b4fa6b68ade4b5c7b Reviewed-on: https://gerrit.instructure.com/10568 Reviewed-by: Brian Whitmer <brian@instructure.com> Tested-by: Jenkins <jenkins@instructure.com>
This commit is contained in:
parent
375b3ea32a
commit
363fb4c9df
|
@ -7,7 +7,7 @@ class ContextExternalTool < ActiveRecord::Base
|
|||
:name, :description, :custom_fields, :custom_fields_string,
|
||||
:course_navigation, :account_navigation, :user_navigation,
|
||||
:resource_selection, :editor_button,
|
||||
:config_type, :config_url, :config_xml
|
||||
:config_type, :config_url, :config_xml, :tool_id
|
||||
validates_presence_of :name
|
||||
validates_presence_of :consumer_key
|
||||
validates_presence_of :shared_secret
|
||||
|
@ -197,6 +197,7 @@ class ContextExternalTool < ActiveRecord::Base
|
|||
settings.delete(:account_navigation) if settings[:account_navigation] && (!settings[:account_navigation][:url])
|
||||
settings.delete(:resource_selection) if settings[:resource_selection] && (!settings[:resource_selection][:url] || !settings[:resource_selection][:selection_width] || !settings[:resource_selection][:selection_height])
|
||||
settings.delete(:editor_button) if settings[:editor_button] && (!settings[:editor_button][:url] || !settings[:editor_button][:icon_url])
|
||||
settings[:icon_url] ||= settings[:editor_button][:icon_url] if settings[:editor_button] && settings[:editor_button][:icon_url]
|
||||
[:resource_selection, :editor_button].each do |type|
|
||||
if settings[type]
|
||||
settings[type][:selection_width] = settings[type][:selection_width].to_i
|
||||
|
@ -413,6 +414,7 @@ class ContextExternalTool < ActiveRecord::Base
|
|||
item.migration_id = hash[:migration_id]
|
||||
item.name = hash[:title]
|
||||
item.description = hash[:description]
|
||||
item.tool_id = hash[:tool_id]
|
||||
item.url = hash[:url] unless hash[:url].blank?
|
||||
item.domain = hash[:domain] unless hash[:domain].blank?
|
||||
item.privacy_level = hash[:privacy_level] || 'name_only'
|
||||
|
|
|
@ -21,6 +21,7 @@ class DeveloperKey < ActiveRecord::Base
|
|||
belongs_to :account
|
||||
has_many :page_views
|
||||
has_many :access_tokens
|
||||
has_many :context_external_tools, :primary_key => 'tool_id', :foreign_key => 'tool_id'
|
||||
|
||||
attr_accessible :api_key, :name, :user, :account
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</script>
|
||||
<% end %>
|
||||
|
||||
<form action="<%= @resource_url %>" method="POST" <%= raw("target='#{@target || 'tool_content'}'") unless @self_target %> id="tool_form" class="<%= 'new_tab' if @tag.try(:new_tab) %>">
|
||||
<form action="<%= @resource_url %>" method="POST" <%= raw("target='#{@target || 'tool_content'}'") unless @self_target %> id="tool_form" class="<%= 'new_tab' if @tag.try(:new_tab) %>" data-tool-id="<%= @tool.tool_id || 'unknown' %>">
|
||||
<% @tool_settings.each do |key, value| %>
|
||||
<%= hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
class AddToolIdToExternalTools < ActiveRecord::Migration
|
||||
tag :predeploy
|
||||
def self.up
|
||||
# using tool_id instead of developer_key.id lets us
|
||||
# use the same keys as lti-examples.heroku.com for
|
||||
# tying multiple context_external_tools to the
|
||||
# same third-party tool
|
||||
add_column :context_external_tools, :tool_id, :string
|
||||
add_index :context_external_tools, [:tool_id]
|
||||
add_column :developer_keys, :tool_id, :string
|
||||
add_index :developer_keys, [:tool_id], :unique => true
|
||||
end
|
||||
|
||||
def self.down
|
||||
remove_column :context_external_tools, :tool_id
|
||||
remove_index :context_external_tools, [:tool_id]
|
||||
remove_column :developer_keys, :tool_id
|
||||
remove_index :developer_keys, [:tool_id]
|
||||
end
|
||||
end
|
|
@ -61,6 +61,7 @@ module CC
|
|||
elsif tool.url =~ %r{https://}
|
||||
blti_node.blti :secure_launch_url, tool.url
|
||||
end
|
||||
blti_node.blti(:icon, tool.settings[:icon_url]) if tool.settings[:icon_url]
|
||||
blti_node.blti :vendor do |v_node|
|
||||
v_node.lticp :code, 'unknown'
|
||||
v_node.lticp :name, 'unknown'
|
||||
|
@ -75,6 +76,7 @@ module CC
|
|||
end
|
||||
|
||||
blti_node.blti(:extensions, :platform => CC::CCHelper::CANVAS_PLATFORM) do |ext_node|
|
||||
ext_node.lticm(:property, tool.tool_id, 'name' => 'tool_id') if tool.tool_id
|
||||
ext_node.lticm :property, tool.workflow_state, 'name' => 'privacy_level'
|
||||
ext_node.lticm(:property, tool.domain, 'name' => 'domain') unless tool.domain.blank?
|
||||
if for_course_copy
|
||||
|
|
|
@ -79,12 +79,16 @@ module CC::Importer
|
|||
tool[:domain] = ext[:custom_fields].delete 'domain'
|
||||
tool[:consumer_key] = ext[:custom_fields].delete 'consumer_key'
|
||||
tool[:shared_secret] = ext[:custom_fields].delete 'shared_secret'
|
||||
|
||||
tool[:tool_id] = ext[:custom_fields].delete 'tool_id'
|
||||
tool[:settings] = ext[:custom_fields]
|
||||
else
|
||||
tool[:extensions] << ext
|
||||
end
|
||||
end
|
||||
if icon = get_node_val(doc, "#{blti}|icon")
|
||||
tool[:settings] ||= {}
|
||||
tool[:settings][:icon_url] = icon
|
||||
end
|
||||
tool
|
||||
end
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
define(['jquery'], function($) {
|
||||
define(['jquery', 'jquery.google-analytics'], function($) {
|
||||
|
||||
if(!$("#tool_form").hasClass('new_tab')) {
|
||||
$("#content").addClass('padless');
|
||||
|
@ -32,6 +32,10 @@ if(!$("#tool_form").hasClass('new_tab')) {
|
|||
$(this).find(".load_tab,.tab_loaded").toggle();
|
||||
});
|
||||
}
|
||||
|
||||
var toolName = $("#tool_form").attr('data-tool-id') || "unknown";
|
||||
$.trackEvent('tool_launch', toolName);
|
||||
|
||||
$("#tool_form:not(.new_tab)").submit().hide();
|
||||
$(document).ready(function() {
|
||||
if($("#tool_content").length) {
|
||||
|
|
|
@ -146,12 +146,14 @@ describe "Canvas Cartridge importing" do
|
|||
tool1.privacy_level = 'name_only'
|
||||
tool1.consumer_key = 'haha'
|
||||
tool1.shared_secret = "don't share me"
|
||||
tool1.tool_id = "test_tool"
|
||||
tool1.settings[:custom_fields] = {"key1" => "value1", "key2" => "value2"}
|
||||
tool1.settings[:user_navigation] = {:url => "http://www.example.com", :text => "hello", :labels => {'en' => 'hello', 'es' => 'hola'}, :extra => 'extra'}
|
||||
tool1.settings[:course_navigation] = {:url => "http://www.example.com", :text => "hello", :labels => {'en' => 'hello', 'es' => 'hola'}, :default => 'disabled', :visibility => 'members', :extra => 'extra'}
|
||||
tool1.settings[:account_navigation] = {:url => "http://www.example.com", :text => "hello", :labels => {'en' => 'hello', 'es' => 'hola'}, :extra => 'extra'}
|
||||
tool1.settings[:resource_selection] = {:url => "http://www.example.com", :text => "hello", :labels => {'en' => 'hello', 'es' => 'hola'}, :selection_width => 100, :selection_height => 50, :extra => 'extra'}
|
||||
tool1.settings[:editor_button] = {:url => "http://www.example.com", :text => "hello", :labels => {'en' => 'hello', 'es' => 'hola'}, :selection_width => 100, :selection_height => 50, :icon_url => "http://www.example.com", :extra => 'extra'}
|
||||
tool1.settings[:icon_url] = "http://www.example.com/favicon.ico"
|
||||
tool1.save!
|
||||
tool2 = @copy_from.context_external_tools.new
|
||||
tool2.domain = 'example.com'
|
||||
|
@ -190,6 +192,8 @@ describe "Canvas Cartridge importing" do
|
|||
t1.domain.should == nil
|
||||
t1.consumer_key.should == 'fake'
|
||||
t1.shared_secret.should == 'fake'
|
||||
t1.tool_id.should == 'test_tool'
|
||||
t1.settings[:icon_url].should == 'http://www.example.com/favicon.ico'
|
||||
[:user_navigation, :course_navigation, :account_navigation].each do |type|
|
||||
t1.settings[type][:url].should == "http://www.example.com"
|
||||
t1.settings[type][:text].should == "hello"
|
||||
|
@ -228,6 +232,8 @@ describe "Canvas Cartridge importing" do
|
|||
t2.workflow_state.should == tool2.workflow_state
|
||||
t2.consumer_key.should == 'fake'
|
||||
t2.shared_secret.should == 'fake'
|
||||
t2.tool_id.should be_nil
|
||||
t2.settings[:icon_url].should be_nil
|
||||
t2.settings[:user_navigation].should be_nil
|
||||
t2.settings[:course_navigation].should be_nil
|
||||
t2.settings[:account_navigation].should be_nil
|
||||
|
|
|
@ -126,7 +126,7 @@ describe "Standard Common Cartridge importing" do
|
|||
et.name.should == "BLTI Test"
|
||||
et.url.should == 'http://www.imsglobal.org/developers/BLTI/tool.php'
|
||||
et.settings[:custom_fields].should == {"key1"=>"value1", "key2"=>"value2"}
|
||||
et.settings[:vendor_extensions].should == [{:platform=>"my.lms.com", :custom_fields=>{"key"=>"value"}}, {:platform=>"your.lms.com", :custom_fields=>{"key"=>"value", "key2"=>"value2"}}]
|
||||
et.settings[:vendor_extensions].should == [{:platform=>"my.lms.com", :custom_fields=>{"key"=>"value"}}, {:platform=>"your.lms.com", :custom_fields=>{"key"=>"value", "key2"=>"value2"}}].map(&:with_indifferent_access)
|
||||
@migration.warnings.member?("The security parameters for the external tool \"#{et.name}\" need to be set in Course Settings.").should be_true
|
||||
end
|
||||
|
||||
|
|
|
@ -335,6 +335,21 @@ describe ContextExternalTool do
|
|||
tool.has_editor_button.should be_true
|
||||
end
|
||||
|
||||
it "should allow setting tool_id and icon_url" do
|
||||
tool = new_external_tool
|
||||
tool.tool_id = "new_tool"
|
||||
tool.settings[:icon_url] = "http://www.example.com/favicon.ico"
|
||||
tool.save
|
||||
tool.tool_id.should == "new_tool"
|
||||
tool.settings[:icon_url].should == "http://www.example.com/favicon.ico"
|
||||
end
|
||||
|
||||
it "should use editor button's icon_url if none is set on the tool" do
|
||||
tool = new_external_tool
|
||||
tool.settings = {:editor_button => {:url => "http://www.example.com", :icon_url => "http://www.example.com/favicon.ico", :selection_width => 100, :selection_height => 100}}
|
||||
tool.save
|
||||
tool.settings[:icon_url].should == "http://www.example.com/favicon.ico"
|
||||
end
|
||||
end
|
||||
|
||||
describe "standardize_url" do
|
||||
|
|
Loading…
Reference in New Issue