extension tool launches default to settings from main tool

External Tool extension previously needed their own urls,
custom fields, and text. Now they use the settings from
the main tool config as the defaults. So an extension
only needs a hash to be enabled.

Test Plan:
 * Add a tool by xml that has custom parameters and that only has the enabled property in the course_navigation settings
 * Launch that tool and verify that it used the main tools launch url and custom parameters

closes #8786

Change-Id: If760bbfe5c1dc10814d2a4b900a53abceab08e2e
Reviewed-on: https://gerrit.instructure.com/11700
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Brian Palmer <brianp@instructure.com>
This commit is contained in:
Bracken Mosbacker 2012-06-20 08:46:03 -06:00
parent 31c12a3e82
commit d728f925e2
8 changed files with 390 additions and 155 deletions

View File

@ -178,12 +178,12 @@ class ExternalToolsController < ApplicationController
redirect_to named_context_url(@context, :context_url)
return
end
@resource_title = @tool.label_for(selection_type.to_sym)
@resource_url = @tool.settings[selection_type.to_sym][:url]
@opaque_id = @context.opaque_identifier(:asset_string)
@resource_type = selection_type
@return_url ||= url_for(@context)
@launch = BasicLTI::ToolLaunch.new(:url => @resource_url, :tool => @tool, :user => @current_user, :context => @context, :link_code => @opaque_id, :return_url => @return_url, :resource_type => @resource_type)
@launch = @tool.create_launch(@context, @current_user, @return_url, selection_type)
@resource_url = @launch.url
@tool_settings = @launch.generate
render :template => 'external_tools/tool_show'
end
@ -200,20 +200,28 @@ class ExternalToolsController < ApplicationController
# @argument description [string] [optional] A description of the tool
# @argument url [string] [optional] The url to match links against. Either "url" or "domain" should be set, not both.
# @argument domain [string] [optional] The domain to match links against. Either "url" or "domain" should be set, not both.
# @argument icon_url [string] [optional] The url of the icon to show for this tool
# @argument text [string] [optional] The default text to show for this tool
# @argument custom_fields [string] [optional] Custom fields that will be sent to the tool consumer, specified as custom_fields[field_name]
# @argument account_navigation[url] [string] [optional] The url of the external tool for account navigation
# @argument account_navigation[enabled] [boolean] [optional] Set this to enable this feature
# @argument account_navigation[text] [string] [optional] The text that will show on the left-tab in the account navigation
# @argument user_navigation[url] [string] [optional] The url of the external tool for user navigation
# @argument user_navigation[enabled] [boolean] [optional] Set this to enable this feature
# @argument user_navigation[text] [string] [optional] The text that will show on the left-tab in the user navigation
# @argument course_navigation[url] [string] [optional] The url of the external tool for course navigation
# @argument course_navigation[enabled] [boolean] [optional] Set this to enable this feature
# @argument course_navigation[text] [string] [optional] The text that will show on the left-tab in the course navigation
# @argument course_navigation[visibility] [string] [optional] Who will see the navigation tab. "admins" for course admins, "members" for students, null for everyone
# @argument course_navigation[default] [boolean] [optional] Whether the navigation option will show in the course by default or whether the teacher will have to explicitly enable it
# @argument editor_button[url] [string] [optional] The url of the external tool
# @argument editor_button[enabled] [boolean] [optional] Set this to enable this feature
# @argument editor_button[icon_url] [string] [optional] The url of the icon to show in the WYSIWYG editor
# @argument editor_button[selection_width] [string] [optional] The width of the dialog the tool is launched in
# @argument editor_button[selection_height] [string] [optional] The height of the dialog the tool is launched in
# @argument resource_selection[url] [string] [optional] The url of the external tool
# @argument resource_selection[enabled] [boolean] [optional] Set this to enable this feature
# @argument resource_selection[icon_url] [string] [optional] The url of the icon to show in the module external tool list
# @argument resource_selection[selection_width] [string] [optional] The width of the dialog the tool is launched in
# @argument resource_selection[selection_height] [string] [optional] The height of the dialog the tool is launched in
# @argument config_type [string] [optional] Configuration can be passed in as CC xml instead of using query parameters. If this value is "by_url" or "by_xml" then an xml configuration will be expected in either the "config_xml" or "config_url" parameter. Note that the name parameter overrides the tool name provided in the xml
@ -228,14 +236,14 @@ class ExternalToolsController < ApplicationController
# -F 'name=LTI Example' \
# -F 'consumer_key=asdfg' \
# -F 'shared_secret=lkjh' \
# -F 'url=http://example.com/ims/lti' \
# -F 'url=https://example.com/ims/lti' \
# -F 'privacy_level=name_only' \
# -F 'custom_fields[key1]=value1' \
# -F 'custom_fields[key2]=value2' \
# -F 'course_navigation[url]=http://example.com/ims/lti/course_endpoint' \
# -F 'course_navigation[text]=Course Materials' \
# -F 'course_navigation[text]=Course Materials' \
# -F 'course_navigation[default]=false'
#
# -F 'course_navigation[enabled]=true'
#
# @example_request
#
# This would create a tool on the account with navigation for the user profile page
@ -244,11 +252,12 @@ class ExternalToolsController < ApplicationController
# -F 'name=LTI Example' \
# -F 'consumer_key=asdfg' \
# -F 'shared_secret=lkjh' \
# -F 'url=http://example.com/ims/lti' \
# -F 'url=https://example.com/ims/lti' \
# -F 'privacy_level=name_only' \
# -F 'user_navigation[url]=http://example.com/ims/lti/user_endpoint' \
# -F 'user_navigation[text]=Soemthing Cool'
#
# -F 'user_navigation[url]=https://example.com/ims/lti/user_endpoint' \
# -F 'user_navigation[text]=Something Cool'
# -F 'user_navigation[enabled]=true'
#
# @example_request
#
# This would create a tool on the account with configuration pulled from an external URL
@ -258,7 +267,7 @@ class ExternalToolsController < ApplicationController
# -F 'consumer_key=asdfg' \
# -F 'shared_secret=lkjh' \
# -F 'config_type=by_url' \
# -F 'config_url=http://example.com/ims/lti/tool_config.xml'
# -F 'config_url=https://example.com/ims/lti/tool_config.xml'
def create
if authorized_action(@context, @current_user, :update)
@tool = @context.context_external_tools.new
@ -327,9 +336,9 @@ class ExternalToolsController < ApplicationController
private
def set_tool_attributes(tool, params)
[:name, :description, :url, :domain, :privacy_level, :consumer_key, :shared_secret,
[:name, :description, :url, :icon_url, :domain, :privacy_level, :consumer_key, :shared_secret,
:custom_fields, :custom_fields_string, :account_navigation, :user_navigation,
:course_navigation, :editor_button, :resource_selection,
:course_navigation, :editor_button, :resource_selection, :text,
:config_type, :config_url, :config_xml].each do |prop|
tool.send("#{prop}=", params[prop]) if params.has_key?(prop)
end

View File

@ -483,8 +483,8 @@ module ApplicationHelper
{
:name => tool.label_for(:editor_button, nil),
:id => tool.id,
:url => tool.settings[:editor_button][:url],
:icon_url => tool.settings[:editor_button][:icon_url],
:url => tool.settings[:editor_button][:url] || tool.url,
:icon_url => tool.settings[:editor_button][:icon_url] || tool.settings[:icon_url],
:width => tool.settings[:editor_button][:selection_width],
:height => tool.settings[:editor_button][:selection_height]
}

View File

@ -26,8 +26,26 @@ class ContextExternalTool < ActiveRecord::Base
state :public
state :deleted
end
set_policy do
def create_launch(context, user, return_url, selection_type=nil)
if selection_type
if self.settings[selection_type.to_sym]
resource_url = self.settings[selection_type.to_sym][:url]
else
raise t('no_selection_type', "This tool has no selection type %{type}", :type => selection_type)
end
end
resource_url ||= self.url
BasicLTI::ToolLaunch.new(:url => resource_url,
:tool => self,
:user => user,
:context => context,
:link_code => context.opaque_identifier(:asset_string),
:return_url => return_url,
:resource_type => selection_type)
end
set_policy do
given { |user, session| self.cached_context_grants_right?(user, session, :update) }
can :read and can :update and can :delete
end
@ -51,9 +69,12 @@ class ContextExternalTool < ActiveRecord::Base
def label_for(key, lang=nil)
labels = settings[key] && settings[key][:labels]
(labels && labels[lang]) ||
labels2 = settings[:labels]
(labels && labels[lang]) ||
(labels && lang && labels[lang.split('-').first]) ||
(settings[key] && settings[key][:text]) ||
(settings[key] && settings[key][:text]) ||
(labels2 && labels2[lang]) ||
(labels2 && lang && labels2[lang.split('-').first]) ||
settings[:text] || name || "External Tool"
end
@ -169,7 +190,7 @@ class ContextExternalTool < ActiveRecord::Base
end
def resource_selection=(hash)
tool_setting(:resource_selection, hash, :selection_width, :selection_height)
tool_setting(:resource_selection, hash, :selection_width, :selection_height, :icon_url)
end
def resource_selection
@ -183,6 +204,22 @@ class ContextExternalTool < ActiveRecord::Base
def editor_button
settings[:editor_button]
end
def icon_url=(i_url)
settings[:icon_url] = i_url
end
def icon_url
settings[:icon_url]
end
def text=(val)
settings[:text] = val
end
def text
settings[:text]
end
def shared_secret=(val)
write_attribute(:shared_secret, val) unless val.blank?
@ -191,19 +228,24 @@ class ContextExternalTool < ActiveRecord::Base
def infer_defaults
self.url = nil if url.blank?
self.domain = nil if domain.blank?
settings.delete(:user_navigation) if settings[:user_navigation] && (!settings[:user_navigation][:url])
settings.delete(:course_navigation) if settings[:course_navigation] && (!settings[:course_navigation][:url])
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
settings[type][:selection_height] = settings[type][:selection_height].to_i
settings[:icon_url] ||= settings[type][:icon_url] if settings[type][:icon_url]
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]
end
end
[:course_navigation, :account_navigation, :user_navigation, :resource_selection, :editor_button].each do |type|
if settings[type]
if !(settings[type][:url] || self.url) || (settings[type].has_key?(:enabled) && !settings[type][:enabled])
settings.delete(type)
end
end
end
settings.delete(:resource_selection) if settings[:resource_selection] && (!settings[:resource_selection][:selection_width] || !settings[:resource_selection][:selection_height])
settings.delete(:editor_button) if settings[:editor_button] && !settings[:icon_url]
self.has_user_navigation = !!settings[:user_navigation]
self.has_course_navigation = !!settings[:course_navigation]
@ -369,19 +411,23 @@ class ContextExternalTool < ActiveRecord::Base
end
end
end
# sets the custom fields from the main tool settings, and any on individual resource type settings
def set_custom_fields(hash, resource_type)
fields = resource_type ? settings[resource_type.to_sym][:custom_fields] : settings[:custom_fields]
(fields || {}).each do |key, val|
key = key.gsub(/[^\w]/, '_').downcase
if key.match(/^custom_/)
hash[key] = val
else
hash["custom_#{key}"] = val
fields = [settings[:custom_fields] || {}]
fields << (settings[resource_type.to_sym][:custom_fields] || {}) if resource_type && settings[resource_type.to_sym]
fields.each do |field_set|
field_set.each do |key, val|
key = key.to_s.gsub(/[^\w]/, '_').downcase
if key.match(/^custom_/)
hash[key] = val
else
hash["custom_#{key}"] = val
end
end
end
end
def clone_for(context, dup=nil, options={})
if !self.cloned_item && !self.new_record?
self.cloned_item = ClonedItem.create(:original_item => self)
@ -453,9 +499,11 @@ class ContextExternalTool < ActiveRecord::Base
settings[setting] = {}
end
settings[setting][:url] = hash[:url]
settings[setting][:url] = hash[:url] if hash[:url]
settings[setting][:text] = hash[:text] if hash[:text]
keys.each { |key| settings[setting][key] = hash[key] }
settings[setting][:custom_fields] = hash[:custom_fields] if hash[:custom_fields]
settings[setting][:enabled] = Canvas::Plugin.value_to_boolean(hash[:enabled]) if hash.has_key?(:enabled)
keys.each { |key| settings[setting][key] = hash[key] if hash.has_key?(key) }
# if the type needs to do some validations for specific keys
yield settings[setting] if block_given?

View File

@ -185,17 +185,20 @@ If the <code>launch_presentation_return_url</code> were
## Settings
All of these settings are contained under "editor_button" in the tool configuration
- url: &lt;url&gt; (required)
- url: &lt;url&gt; (optional)
This is the URL that will be POSTed to when users click the button in any rich editor. It can be the same as the tool's URL, or something different. Domain and URL matching are not enforced for editor button links. In order to prevent security warnings for users, it is recommended that this URL be over SSL (https).
This is required if a url is not set on the main tool configuration.
- icon_url: &lt;url&gt; (required)
- icon_url: &lt;url&gt; (optional)
This is the URL of the icon that will be shown on the button in the rich editor. Icons should be 16x16 in size, and can be any standard web image format (png, gif, ico, etc.). It is recommended that this URL be over SSL (https).
This is required if an icon_url is not set on the main tool configuration.
- text: &lt;text&gt; (required)
- text: &lt;text&gt; (optional)
This is the default text that will be shown if a user hovers over the editor button. This can be overridden by language-specific settings if desired by using the labels setting. This text will also be shown next to the icon if there are too many buttons and the tool is available in the "more tools" dropdown.
This is required if a text value is not set on the main tool configuration.
- labels: &lt;set of locale-label pairs&gt; (optional)
@ -208,3 +211,7 @@ All of these settings are contained under "editor_button" in the tool configurat
- selection_height: &lt;number&gt; (required)
This value is the explicit height of the dialog that is loaded when a user clicks the icon in the rich editor.
- enabled: &lt;boolean&gt; (required)
Whether to enable this selection feature.

View File

@ -59,13 +59,19 @@ If the <code>launch_presentation_return_url</code> were
## Settings
All of these settings are contained under "resource_selection"
- url: &lt;url&gt; (required)
- url: &lt;url&gt; (optional)
This is the URL that will be POSTed to when users click the button in any rich editor. It can be the same as the tool's URL, or something different. Domain and URL matching are not enforced for editor button links. In order to prevent security warnings for users, it is recommended that this URL be over SSL (https).
This is required if a url is not set on the main tool configuration.
- text: &lt;text&gt; (required)
- icon_url: &lt;url&gt; (optional)
This is the URL of the icon to be shown.
- text: &lt;text&gt; (optional)
This is the default text that will be shown if a user hovers over the editor button. This can be overridden by language-specific settings if desired by using the labels setting. This text will also be shown next to the icon if there are too many buttons and the tool is available in the "more tools" dropdown.
This is required if a text value is not set on the main tool configuration.
- labels: &lt;set of locale-label pairs&gt; (optional)
@ -78,3 +84,7 @@ All of these settings are contained under "resource_selection"
- selection_height: &lt;number&gt; (required)
This value is the explicit height of the dialog that is loaded when a user clicks the icon in the rich editor.
- enabled: &lt;boolean&gt; (required)
Whether to enable this selection feature.

View File

@ -20,9 +20,10 @@ of users.
### Settings
All of these settings are contained under "course_navigation"
- url: &lt;url&gt; (required)
- url: &lt;url&gt; (optional)
This is the URL that will be POSTed to when users click the left tab. It can be the same as the tool's URL, or something different. Domain and URL matching are not enforced for course navigation links. In order to prevent security warnings for users, it is recommended that this URL be over SSL (https).
This is required if a url is not set on the main tool configuration.
- default: ['enabled', 'disabled'] (optional, 'enabled' by default)
@ -32,14 +33,19 @@ All of these settings are contained under "course_navigation"
This specifies what types of users will see the link in the course navigation. "public" means anyone accessing the course, "members" means only users enrolled in the course, and "admins" means only Teachers, TAs, Designers and account admins will see the link.
- text: &lt;text&gt; (required)
- text: &lt;text&gt; (optional)
This is the default text that will be shown in the left hand navigation as the text of the link. This can be overridden by language-specific settings if desired by using the labels setting.
This is required if a text value is not set on the main tool configuration.
- labels: &lt;set of locale-label pairs&gt; (optional)
This can be used to specify different label names for different locales. For example, if an institution supports both English and Spanish interfaces, the text in the link should change depending on the language being displayed. This option lets you support multiple languages for a single tool.
- enabled: &lt;boolean&gt; (required)
Whether to enable this selection feature.
<a name="account_navigation"></a>
## Account navigation links
External tools can also be configured to appear as links in
@ -51,18 +57,24 @@ the link in their account navigation.
### Settings
All of these settings are contained under "account_navigation"
- url: &lt;url&gt; (required)
- url: &lt;url&gt; (optional)
This is the URL that will be POSTed to when users click the left tab. It can be the same as the tool's URL, or something different. Domain and URL matching are not enforced for account navigation links. In order to prevent security warnings for users, it is recommended that this URL be over SSL (https).
This is required if a url is not set on the main tool configuration.
- text: &lt;text&gt; (required)
- text: &lt;text&gt; (optional)
This is the default text that will be shown in the left hand navigation as the text of the link. This can be overridden by language-specific settings if desired by using the labels setting.
This is required if a text value is not set on the main tool configuration.
- labels: &lt;set of locale-label pairs&gt; (optional)
This can be used to specify different label names for different locales. For example, if an institution supports both English and Spanish interfaces, the text in the link should change depending on the language being displayed. This option lets you support multiple languages for a single tool.
- enabled: &lt;boolean&gt; (required)
Whether to enable this selection feature.
<a name="user_navigation"></a>
## User navigation links
External tools can also be configured to appear as links in
@ -76,14 +88,20 @@ profile navigation.
### Settings
All of these settings are contained under "user_navigation"
- url: &lt;url&gt; (required)
- url: &lt;url&gt; (optional)
This is the URL that will be POSTed to when users click the left tab. It can be the same as the tool's URL, or something different. Domain and URL matching are not enforced for user navigation links. In order to prevent security warnings for users, it is recommended that this URL be over SSL (https).
This is required if a url is not set on the main tool configuration.
- text: &lt;text&gt; (required)
- text: &lt;text&gt; (optional)
This is the default text that will be shown in the left hand navigation as the text of the link. This can be overridden by language-specific settings if desired by using the labels setting.
This is required if a text value is not set on the main tool configuration.
- labels: &lt;set of locale-label pairs&gt; (optional)
This can be used to specify different label names for different locales. For example, if an institution supports both English and Spanish interfaces, the text in the link should change depending on the language being displayed. This option lets you support multiple languages for a single tool.
- enabled: &lt;boolean&gt; (required)
Whether to enable this selection feature.

View File

@ -39,9 +39,7 @@ found below.
<blti:extensions platform="canvas.instructure.com">
<lticm:property name="privacy_level">public</lticm:property>
</blti:extensions>
<cartridge_bundle identifierref="BLTI001_Bundle"/>
<cartridge_icon identifierref="BLTI001_Icon"/>
</cartridge_basiclti_link>
</cartridge_basiclti_link>
### Domain matching, "name only" privacy level
<?xml version="1.0" encoding="UTF-8"?>
@ -60,9 +58,7 @@ found below.
<lticm:property name="privacy_level">name_only</lticm:property>
<lticm:property name="domain">example.com</lticm:property>
</blti:extensions>
<cartridge_bundle identifierref="BLTI001_Bundle"/>
<cartridge_icon identifierref="BLTI001_Icon"/>
</cartridge_basiclti_link>
</cartridge_basiclti_link>
## Course Navigation External Tool Examples
@ -78,19 +74,67 @@ found below.
http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd
http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd
http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
<blti:launch_url>https://example.com/attendance</blti:launch_url>
<blti:title>Attendance</blti:title>
<blti:description>Provides an interactive seating chart and attendance tool</blti:description>
<blti:extensions platform="canvas.instructure.com">
<lticm:property name="privacy_level">public</lticm:property>
<lticm:property name="domain">example.com</lticm:property>
<lticm:options name="course_navigation">
<lticm:property name="url">https://example.com/attendance</lticm:property>
<lticm:property name="text">Attendance</lticm:property>
<lticm:property name="enabled">true</lticm:property>
</lticm:options>
</blti:extensions>
<cartridge_bundle identifierref="BLTI001_Bundle"/>
<cartridge_icon identifierref="BLTI001_Icon"/>
</cartridge_basiclti_link>
</cartridge_basiclti_link>
### Minimal configuration with specific launch url for extension
<?xml version="1.0" encoding="UTF-8"?>
<cartridge_basiclti_link xmlns="http://www.imsglobal.org/xsd/imslticc_v1p0"
xmlns:blti = "http://www.imsglobal.org/xsd/imsbasiclti_v1p0"
xmlns:lticm ="http://www.imsglobal.org/xsd/imslticm_v1p0"
xmlns:lticp ="http://www.imsglobal.org/xsd/imslticp_v1p0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.imsglobal.org/xsd/imslticc_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticc_v1p0.xsd
http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd
http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd
http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
<blti:launch_url>https://example.com/</blti:launch_url>
<blti:title>Attendance</blti:title>
<blti:description>Provides an interactive seating chart and attendance tool</blti:description>
<blti:extensions platform="canvas.instructure.com">
<lticm:property name="privacy_level">public</lticm:property>
<lticm:options name="course_navigation">
<lticm:property name="url">https://example.com/attendance</lticm:property>
<lticm:property name="enabled">true</lticm:property>
</lticm:options>
</blti:extensions>
</cartridge_basiclti_link>
### Configuration with specific custom variables for extension
<?xml version="1.0" encoding="UTF-8"?>
<cartridge_basiclti_link xmlns="http://www.imsglobal.org/xsd/imslticc_v1p0"
xmlns:blti = "http://www.imsglobal.org/xsd/imsbasiclti_v1p0"
xmlns:lticm ="http://www.imsglobal.org/xsd/imslticm_v1p0"
xmlns:lticp ="http://www.imsglobal.org/xsd/imslticp_v1p0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.imsglobal.org/xsd/imslticc_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticc_v1p0.xsd
http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd
http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd
http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
<blti:launch_url>https://example.com/launch</blti:launch_url>
<blti:title>Mind blowing awesomeness</blti:title>
<blti:description>Provides something so awesome you'll just have to launch it to believe it</blti:description>
<blti:extensions platform="canvas.instructure.com">
<lticm:property name="privacy_level">public</lticm:property>
<lticm:options name="course_navigation">
<lticm:property name="enabled">true</lticm:property>
<lticm:options name="custom_fields">
<lticm:property name="key1">value1</lticm:property>
<lticm:property name="key2">value2</lticm:property>
</lticm:options>
</lticm:options>
</blti:extensions>
</cartridge_basiclti_link>
### Teacher/Admin-only navigation
@ -104,20 +148,18 @@ found below.
http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd
http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd
http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
<blti:launch_url>https://example.com/attendance</blti:launch_url>
<blti:title>Attendance</blti:title>
<blti:description>Provides an interactive seating chart and attendance tool</blti:description>
<blti:extensions platform="canvas.instructure.com">
<lticm:property name="privacy_level">public</lticm:property>
<lticm:property name="domain">example.com</lticm:property>
<lticm:options name="course_navigation">
<lticm:property name="url">https://example.com/attendance</lticm:property>
<lticm:property name="text">Attendance</lticm:property>
<lticm:property name="visibility">admins</lticm:property>
<lticm:property name="enabled">true</lticm:property>
</lticm:options>
</blti:extensions>
<cartridge_bundle identifierref="BLTI001_Bundle"/>
<cartridge_icon identifierref="BLTI001_Icon"/>
</cartridge_basiclti_link>
</cartridge_basiclti_link>
### Disabled by default
@ -131,20 +173,18 @@ found below.
http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd
http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd
http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
<blti:launch_url>https://example.com/attendance</blti:launch_url>
<blti:title>Attendance</blti:title>
<blti:description>Provides an interactive seating chart and attendance tool</blti:description>
<blti:extensions platform="canvas.instructure.com">
<lticm:property name="privacy_level">public</lticm:property>
<lticm:property name="domain">example.com</lticm:property>
<lticm:options name="course_navigation">
<lticm:property name="url">https://example.com/attendance</lticm:property>
<lticm:property name="text">Attendance</lticm:property>
<lticm:property name="default">disabled</lticm:property>
<lticm:property name="enabled">true</lticm:property>
</lticm:options>
</blti:extensions>
<cartridge_bundle identifierref="BLTI001_Bundle"/>
<cartridge_icon identifierref="BLTI001_Icon"/>
</cartridge_basiclti_link>
</cartridge_basiclti_link>
### Multiple language support
@ -166,15 +206,14 @@ found below.
<lticm:options name="course_navigation">
<lticm:property name="url">https://example.com/attendance</lticm:property>
<lticm:property name="text">Attendance</lticm:property>
<lticm:property name="enabled">true</lticm:property>
<lticm:options name="labels">
<lticm:property name="en">Attendance</lticm:property>
<lticm:property name="es">Asistencia</lticm:property>
</lticm:options>
</lticm:options>
</blti:extensions>
<cartridge_bundle identifierref="BLTI001_Bundle"/>
<cartridge_icon identifierref="BLTI001_Icon"/>
</cartridge_basiclti_link>
</cartridge_basiclti_link>
## Account Navigation External Tool Examples
@ -190,19 +229,18 @@ found below.
http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd
http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd
http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
<blti:launch_url>https://example.com/reports</blti:launch_url>
<blti:title>Custom Reports</blti:title>
<blti:description>Department reports pulled from other campus systems</blti:description>
<blti:extensions platform="canvas.instructure.com">
<lticm:property name="privacy_level">public</lticm:property>
<lticm:property name="domain">example.com</lticm:property>
<lticm:property name="text">Other Reports</lticm:property>
<lticm:options name="account_navigation">
<lticm:property name="url">https://example.com/reports</lticm:property>
<lticm:property name="text">Other Reports</lticm:property>
<lticm:property name="enabled">true</lticm:property>
</lticm:options>
</blti:extensions>
<cartridge_bundle identifierref="BLTI001_Bundle"/>
<cartridge_icon identifierref="BLTI001_Icon"/>
</cartridge_basiclti_link>
</cartridge_basiclti_link>
## User Navigation External Tool Examples
@ -218,19 +256,17 @@ found below.
http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd
http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd
http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
<blti:launch_url>https://example.com/profile</blti:launch_url>
<blti:title>Campus Profile</blti:title>
<blti:description>Access to campus profile from within Canvas</blti:description>
<blti:extensions platform="canvas.instructure.com">
<lticm:property name="privacy_level">public</lticm:property>
<lticm:property name="domain">example.com</lticm:property>
<lticm:options name="user_navigation">
<lticm:property name="url">https://example.com/profile</lticm:property>
<lticm:property name="text">Campus Profile</lticm:property>
<lticm:property name="enabled">true</lticm:property>
</lticm:options>
</blti:extensions>
<cartridge_bundle identifierref="BLTI001_Bundle"/>
<cartridge_icon identifierref="BLTI001_Icon"/>
</cartridge_basiclti_link>
</cartridge_basiclti_link>
## Rich Editor External Tool Examples
@ -246,22 +282,21 @@ found below.
http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd
http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd
http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
<blti:launch_url>https://example.com/image_selector</blti:launch_url>
<blti:title>Image Selector</blti:title>
<blti:description>This connects to the campus image library and allows inserting images into content directly from this library</blti:description>
<blti:extensions platform="canvas.instructure.com">
<lticm:property name="privacy_level">public</lticm:property>
<lticm:property name="domain">example.com</lticm:property>
<lticm:property name="text">Image Library</lticm:property>
<lticm:options name="editor_button">
<lticm:property name="url">https://example.com/image_selector</lticm:property>
<lticm:property name="enabled">true</lticm:property>
<lticm:property name="icon_url">https://example.com/image_selector.png</lticm:property>
<lticm:property name="text">Image Library</lticm:property>
<lticm:property name="selection_width">500</lticm:property>
<lticm:property name="selection_height">300</lticm:property>
</lticm:options>
</blti:extensions>
<cartridge_bundle identifierref="BLTI001_Bundle"/>
<cartridge_icon identifierref="BLTI001_Icon"/>
</cartridge_basiclti_link>
</cartridge_basiclti_link>
### Multiple language support
@ -275,14 +310,15 @@ found below.
http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd
http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd
http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
<blti:launch_url>https://example.com/image_selector</blti:launch_url>
<blti:title>Image Selector</blti:title>
<blti:description>This connects to the campus image library and allows inserting images into content directly from this library</blti:description>
<blti:extensions platform="canvas.instructure.com">
<lticm:property name="privacy_level">public</lticm:property>
<lticm:property name="domain">example.com</lticm:property>
<lticm:property name="icon_url">https://example.com/image_selector.png</lticm:property>
<lticm:options name="editor_button">
<lticm:property name="url">https://example.com/image_selector</lticm:property>
<lticm:property name="icon_url">https://example.com/image_selector.png</lticm:property>
<lticm:property name="enabled">true</lticm:property>
<lticm:property name="text">Image Library</lticm:property>
<lticm:property name="selection_width">500</lticm:property>
<lticm:property name="selection_height">300</lticm:property>
@ -292,9 +328,7 @@ found below.
</lticm:options>
</lticm:options>
</blti:extensions>
<cartridge_bundle identifierref="BLTI001_Bundle"/>
<cartridge_icon identifierref="BLTI001_Icon"/>
</cartridge_basiclti_link>
</cartridge_basiclti_link>
## Link Selection External Tool Examples
@ -319,15 +353,14 @@ matching, and to only return URLs matching that domain.
<lticm:property name="privacy_level">public</lticm:property>
<lticm:property name="domain">example.com</lticm:property>
<lticm:options name="resource_selection">
<lticm:property name="enabled">true</lticm:property>
<lticm:property name="url">https://example.com/chapter_selector</lticm:property>
<lticm:property name="text">eBook Chapter Selector</lticm:property>
<lticm:property name="selection_width">500</lticm:property>
<lticm:property name="selection_height">300</lticm:property>
</lticm:options>
</blti:extensions>
<cartridge_bundle identifierref="BLTI001_Bundle"/>
<cartridge_icon identifierref="BLTI001_Icon"/>
</cartridge_basiclti_link>
</cartridge_basiclti_link>
### Multiple language support
@ -347,6 +380,7 @@ matching, and to only return URLs matching that domain.
<lticm:property name="privacy_level">public</lticm:property>
<lticm:property name="domain">example.com</lticm:property>
<lticm:options name="resource_selection">
<lticm:property name="enabled">true</lticm:property>
<lticm:property name="url">https://example.com/chapter_selector</lticm:property>
<lticm:property name="text">eBook Chapter Selector</lticm:property>
<lticm:property name="selection_width">500</lticm:property>
@ -357,9 +391,7 @@ matching, and to only return URLs matching that domain.
</lticm:options>
</lticm:options>
</blti:extensions>
<cartridge_bundle identifierref="BLTI001_Bundle"/>
<cartridge_icon identifierref="BLTI001_Icon"/>
</cartridge_basiclti_link>
</cartridge_basiclti_link>
## Combined External Tool Configuration Examples
@ -386,19 +418,48 @@ by the service should be scoped to the matching domain.
<lticm:property name="privacy_level">public</lticm:property>
<lticm:property name="domain">example.com</lticm:property>
<lticm:options name="course_navigation">
<lticm:property name="enabled">true</lticm:property>
<lticm:property name="url">https://example.com/attendance</lticm:property>
<lticm:property name="text">Attendance</lticm:property>
<lticm:property name="visibility">admins</lticm:property>
<lticm:property name="default">disabled</lticm:property>
</lticm:options>
<lticm:options name="account_navigation">
<lticm:property name="enabled">true</lticm:property>
<lticm:property name="url">https://example.com/attendance_admin</lticm:property>
<lticm:property name="text">Attendance</lticm:property>
</lticm:options>
</blti:extensions>
<cartridge_bundle identifierref="BLTI001_Bundle"/>
<cartridge_icon identifierref="BLTI001_Icon"/>
</cartridge_basiclti_link>
</cartridge_basiclti_link>
### Course navigation and account navigation with shared url and text
<?xml version="1.0" encoding="UTF-8"?>
<cartridge_basiclti_link xmlns="http://www.imsglobal.org/xsd/imslticc_v1p0"
xmlns:blti = "http://www.imsglobal.org/xsd/imsbasiclti_v1p0"
xmlns:lticm ="http://www.imsglobal.org/xsd/imslticm_v1p0"
xmlns:lticp ="http://www.imsglobal.org/xsd/imslticp_v1p0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.imsglobal.org/xsd/imslticc_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticc_v1p0.xsd
http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd
http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd
http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
<blti:launch_url>https://example.com/attendance</blti:launch_url>
<blti:title>Attendance</blti:title>
<blti:description>Provides an interactive seating chart and attendance tool</blti:description>
<blti:extensions platform="canvas.instructure.com">
<lticm:property name="privacy_level">public</lticm:property>
<lticm:property name="text">Attendance</lticm:property>
<lticm:options name="course_navigation">
<lticm:property name="enabled">true</lticm:property>
<lticm:property name="visibility">admins</lticm:property>
<lticm:property name="default">disabled</lticm:property>
</lticm:options>
<lticm:options name="account_navigation">
<lticm:property name="enabled">true</lticm:property>
</lticm:options>
</blti:extensions>
</cartridge_basiclti_link>
### Rich editor and link selection with multiple language support
@ -412,33 +473,27 @@ by the service should be scoped to the matching domain.
http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd
http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd
http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
<blti:launch_url>https://example.com/wiki</blti:launch_url>
<blti:title>Global Wiki</blti:title>
<blti:description>Institution-wide wiki tool with all the trimmings</blti:description>
<blti:extensions platform="canvas.instructure.com">
<lticm:property name="privacy_level">public</lticm:property>
<lticm:property name="domain">example.com</lticm:property>
<lticm:options name="editor_button">
<lticm:property name="url">https://example.com/wiki</lticm:property>
<lticm:property name="icon_url">https://example.com/wiki.png</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 name="labels">
<lticm:property name="icon_url">https://example.com/wiki.png</lticm:property>
<lticm:property name="text">Build/Link to Wiki Page</lticm:property>
<lticm:options name="labels">
<lticm:property name="en-US">Build/Link to Wiki Page</lticm:property>
<lticm:property name="en-GB">Build/Link to Wiki Page</lticm:property>
</lticm:options>
<lticm:options name="editor_button">
<lticm:property name="enabled">true</lticm:property>
<lticm:property name="selection_width">500</lticm:property>
<lticm:property name="selection_height">300</lticm:property>
</lticm:options>
<lticm:options name="resource_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="enabled">true</lticm:property>
<lticm:property name="selection_width">500</lticm:property>
<lticm:property name="selection_height">300</lticm:property>
<lticm:options name="labels">
<lticm:property name="en-US">Build/Link to Wiki Page</lticm:property>
<lticm:property name="en-GB">Build/Link to Wiki Page</lticm:property>
</lticm:options>
</lticm:options>
</blti:extensions>
<cartridge_bundle identifierref="BLTI001_Bundle"/>
<cartridge_icon identifierref="BLTI001_Icon"/>
</cartridge_basiclti_link>
</cartridge_basiclti_link>

View File

@ -47,7 +47,7 @@ describe ContextExternalTool do
@tool.settings[:editor_button] = {
"icon_url"=>"http://www.example.com/favicon.ico",
"text"=>"Example",
"url"=>"http://www.example.com",
"url"=>"http://www.example.com",
"selection_height"=>400,
"selection_width"=>600
}
@ -55,7 +55,47 @@ describe ContextExternalTool do
@tool.should_not be_new_record
@tool.errors.should be_empty
end
def url_test(nav_url=nil)
course_with_teacher(:active_all => true)
@tool = @course.context_external_tools.new(:name => "a", :consumer_key => '12345', :shared_secret => 'secret', :url => "http://www.example.com")
[:course_navigation, :account_navigation, :user_navigation, :resource_selection, :editor_button].each do |type|
@tool.send "#{type}=", {
:url => nav_url,
:text => "Example",
:icon_url => "http://www.example.com/image.ico",
:selection_width => 50,
:selection_height => 50
}
@tool.save!
launch = @tool.create_launch(@course, @user, "http://test.com", type)
launch.resource_type.should == type
if nav_url
launch.url.should == nav_url
else
launch.url.should == @tool.url
end
end
end
it "should allow extension to not have a url if the main config has a url" do
url_test
end
it "should prefer the extension url to the main config url" do
url_test(nav_url="https://example.com/special_launch_of_death")
end
it "should not allow extension with no custom url and a domain match" do
@tool = @course.context_external_tools.create!(:name => "a", :domain => "google.com", :consumer_key => '12345', :shared_secret => 'secret')
@tool.course_navigation = {
:text => "Example"
}
@tool.save!
@tool.has_course_navigation.should == false
end
it "should not validate with no domain or url setting" do
@tool = @course.context_external_tools.create(:name => "a", :consumer_key => '12345', :shared_secret => 'secret')
@tool.should be_new_record
@ -63,6 +103,25 @@ describe ContextExternalTool do
@tool.errors['domain'].should == "Either the url or domain should be set."
end
end
it "should allow extension with only 'enabled' key" do
@tool = @course.context_external_tools.create!(:name => "a", :url => "http://google.com", :consumer_key => '12345', :shared_secret => 'secret')
@tool.course_navigation = {
:enabled => "true"
}
@tool.save!
@tool.has_course_navigation.should == true
end
it "should clear disabled extensions" do
@tool = @course.context_external_tools.create!(:name => "a", :url => "http://google.com", :consumer_key => '12345', :shared_secret => 'secret')
@tool.course_navigation = {
:enabled => "false"
}
@tool.save!
@tool.has_course_navigation.should == false
end
describe "find_external_tool" do
it "should match on the same domain" do
@tool = @course.context_external_tools.create!(:name => "a", :domain => "google.com", :consumer_key => '12345', :shared_secret => 'secret')
@ -217,8 +276,34 @@ describe ContextExternalTool do
tool = @course.context_external_tools.create!(:name => "a", :url => "http://www.google.com", :consumer_key => '12345', :shared_secret => 'secret', :custom_fields => {'a' => '123', 'b' => '456'})
tool.custom_fields_string.should == "a=123\nb=456"
end
it "should merge custom fields for extension launches" do
course_with_teacher(:active_all => true)
@tool = @course.context_external_tools.new(:name => "a", :consumer_key => '12345', :shared_secret => 'secret', :custom_fields => {'a' => "1", 'b' => "2"}, :url =>"http://www.example.com")
[:course_navigation, :account_navigation, :user_navigation, :resource_selection, :editor_button].each do |type|
@tool.send "#{type}=", {
:text =>"Example",
:url =>"http://www.example.com",
:icon_url => "http://www.example.com/image.ico",
:custom_fields => {"b" => "5", "c" => "3"},
:selection_width => 50,
:selection_height => 50
}
@tool.save!
hash = @tool.create_launch(@course, @user, "http://test.com", type).generate
hash["custom_a"].should == "1"
hash["custom_b"].should == "5"
hash["custom_c"].should == "3"
@tool.settings[type.to_sym][:custom_fields] = nil
@tool.save!
hash = @tool.create_launch(@course, @user, "http://test.com", type).generate
hash["custom_a"].should == "1"
hash["custom_b"].should == "2"
hash.has_key?("custom_c").should == false
end
end
end
describe "all_tools_for" do
@ -362,53 +447,56 @@ describe ContextExternalTool do
end
describe "label_for" do
append_before(:each) do
@tool = @root_account.context_external_tools.new(:name => 'tool', :consumer_key => '12345', :shared_secret => 'secret', :url => "http://example.com")
end
it "should return the tool name if nothing else is configured and no key is sent" do
tool = @root_account.context_external_tools.new(:name => 'tool', :consumer_key => '12345', :shared_secret => 'secret', :url => "http://example.com")
tool.save!
tool.label_for(nil).should == 'tool'
@tool.save!
@tool.label_for(nil).should == 'tool'
end
it "should return the tool name if nothing is configured on the sent key" do
tool = @root_account.context_external_tools.new(:name => 'tool', :consumer_key => '12345', :shared_secret => 'secret', :url => "http://example.com")
tool.settings = {:course_navigation => {:bob => 'asfd'}}
tool.save!
tool.label_for(:course_navigation).should == 'tool'
@tool.settings = {:course_navigation => {:bob => 'asfd'}}
@tool.save!
@tool.label_for(:course_navigation).should == 'tool'
end
it "should return the tool's 'text' value if no key is sent" do
tool = @root_account.context_external_tools.new(:name => 'tool', :consumer_key => '12345', :shared_secret => 'secret', :url => "http://example.com")
tool.settings = {:text => 'tool label', :course_navigation => {:url => "http://example.com", :text => 'course nav'}}
tool.save!
tool.label_for(nil).should == 'tool label'
@tool.settings = {:text => 'tool label', :course_navigation => {:url => "http://example.com", :text => 'course nav'}}
@tool.save!
@tool.label_for(nil).should == 'tool label'
end
it "should return the tool's 'text' value if no 'text' value is set for the sent key" do
tool = @root_account.context_external_tools.new(:name => 'tool', :consumer_key => '12345', :shared_secret => 'secret', :url => "http://example.com")
tool.settings = {:text => 'tool label', :course_navigation => {:bob => 'asdf'}}
tool.save!
tool.label_for(:course_navigation).should == 'tool label'
@tool.settings = {:text => 'tool label', :course_navigation => {:bob => 'asdf'}}
@tool.save!
@tool.label_for(:course_navigation).should == 'tool label'
end
it "should return the tool's locale-specific 'text' value if no 'text' value is set for the sent key" do
@tool.settings = {:text => 'tool label', :labels => {'en' => 'translated tool label'}, :course_navigation => {:bob => 'asdf'}}
@tool.save!
@tool.label_for(:course_navigation, 'en').should == 'translated tool label'
end
it "should return the setting's 'text' value for the sent key if available" do
tool = @root_account.context_external_tools.new(:name => 'tool', :consumer_key => '12345', :shared_secret => 'secret', :url => "http://example.com")
tool.settings = {:text => 'tool label', :course_navigation => {:url => "http://example.com", :text => 'course nav'}}
tool.save!
tool.label_for(:course_navigation).should == 'course nav'
@tool.settings = {:text => 'tool label', :course_navigation => {:url => "http://example.com", :text => 'course nav'}}
@tool.save!
@tool.label_for(:course_navigation).should == 'course nav'
end
it "should return the locale-specific label if specified and matching exactly" do
tool = @root_account.context_external_tools.new(:name => 'tool', :consumer_key => '12345', :shared_secret => 'secret', :url => "http://example.com")
tool.settings = {:text => 'tool label', :course_navigation => {:url => "http://example.com", :text => 'course nav', :labels => {'en-US' => 'english nav'}}}
tool.save!
tool.label_for(:course_navigation, 'en-US').should == 'english nav'
tool.label_for(:course_navigation, 'es').should == 'course nav'
@tool.settings = {:text => 'tool label', :course_navigation => {:url => "http://example.com", :text => 'course nav', :labels => {'en-US' => 'english nav'}}}
@tool.save!
@tool.label_for(:course_navigation, 'en-US').should == 'english nav'
@tool.label_for(:course_navigation, 'es').should == 'course nav'
end
it "should return the locale-specific label if specified and matching based on general locale" do
tool = @root_account.context_external_tools.new(:name => 'tool', :consumer_key => '12345', :shared_secret => 'secret', :url => "http://example.com")
tool.settings = {:text => 'tool label', :course_navigation => {:url => "http://example.com", :text => 'course nav', :labels => {'en' => 'english nav'}}}
tool.save!
tool.label_for(:course_navigation, 'en-US').should == 'english nav'
@tool.settings = {:text => 'tool label', :course_navigation => {:url => "http://example.com", :text => 'course nav', :labels => {'en' => 'english nav'}}}
@tool.save!
@tool.label_for(:course_navigation, 'en-US').should == 'english nav'
end
end