migrate has_X context_external_tool columns to separate table

currently every extension type has its own boolean db column
while this isn't strictly a problem, it is a little sad, and
given the fact that we will be adding more extension types soon,
it's probably better to take care of this now

also i'm refactoring some of the methods in context_external_tool

test plan:
* external tool regressions

refs #CNVS-13815

Change-Id: I6caf7b0e3d0de054906e3530f085fbfa9e8e499f
Reviewed-on: https://gerrit.instructure.com/38923
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Jeremy Stanley <jeremy@instructure.com>
QA-Review: Clare Strong <clare@instructure.com>
Reviewed-by: Brad Humphrey <brad@instructure.com>
Product-Review: James Williams  <jamesw@instructure.com>
This commit is contained in:
James Williams 2014-08-08 06:45:01 -06:00
parent 026980c3a9
commit 75d21f8f84
16 changed files with 308 additions and 163 deletions

View File

@ -120,8 +120,7 @@ class AssignmentsController < ApplicationController
@assignment.ensure_assignment_group
if @assignment.submission_types.include?("online_upload") || @assignment.submission_types.include?("online_url")
@external_tools = ContextExternalTool.all_tools_for(@context, :user => @current_user)
.select(&:has_homework_submission)
@external_tools = ContextExternalTool.all_tools_for(@context, :user => @current_user, :type => :homework_submission)
else
@external_tools = []
end

View File

@ -155,7 +155,7 @@ class ContentMigrationsController < ApplicationController
options = @plugins.map{|p| {:label => p.metadata(:select_text), :id => p.id}}
external_tools = ContextExternalTool.all_tools_for(@context).select(&:has_migration_selection?)
external_tools = ContextExternalTool.all_tools_for(@context, :type => :migration_selection)
options.concat(external_tools.map do |et|
{
id: et.asset_string,

View File

@ -936,7 +936,7 @@ class CoursesController < ApplicationController
enabled: Canvas::Plugin.find(:app_center).enabled?
}
@course_settings_sub_navigation_tools = ContextExternalTool.all_tools_for(@context).select(&:has_course_settings_sub_navigation?)
@course_settings_sub_navigation_tools = ContextExternalTool.all_tools_for(@context, :type => :course_settings_sub_navigation)
unless @context.grants_right?(@current_user, session, :manage_content)
@course_settings_sub_navigation_tools.reject! { |tool| tool.course_settings_sub_navigation(:visibility) == 'admins' }
end
@ -1395,7 +1395,7 @@ class CoursesController < ApplicationController
@recent_feedback = (@current_user && @current_user.recent_feedback(:contexts => @contexts)) || []
end
@course_home_sub_navigation_tools = ContextExternalTool.all_tools_for(@context).select(&:has_course_home_sub_navigation?)
@course_home_sub_navigation_tools = ContextExternalTool.all_tools_for(@context, :type => :course_home_sub_navigation)
unless @context.grants_right?(@current_user, session, :manage_content)
@course_home_sub_navigation_tools.reject! { |tool| tool.course_home_sub_navigation(:visibility) == 'admins' }
end

View File

@ -89,7 +89,7 @@ class ExternalToolsController < ApplicationController
def homework_submissions
if authorized_action(@context, @current_user, :read)
@tools = ContextExternalTool.all_tools_for(@context, :user => @current_user).select(&:has_homework_submission)
@tools = ContextExternalTool.all_tools_for(@context, :user => @current_user, :type => :has_homework_submission)
respond_to do |format|
format.json { render :json => external_tools_json(@tools, @context, @current_user, session) }
end
@ -633,7 +633,7 @@ class ExternalToolsController < ApplicationController
end
def invalidate_nav_tabs_cache(tool)
if tool.has_user_navigation || tool.has_course_navigation || tool.has_account_navigation
if tool.has_placement?(:user_navigation) || tool.has_placement?(:course_navigation) || tool.has_placement?(:account_navigation)
Lti::NavigationCache.new(@domain_root_account).invalidate_cache_key
end
end

View File

@ -3,6 +3,8 @@ class ContextExternalTool < ActiveRecord::Base
include SearchTermHelper
has_many :content_tags, :as => :content
has_many :context_external_tool_placements, :autosave => true
belongs_to :context, :polymorphic => true
validates_inclusion_of :context_type, :allow_nil => true, :in => ['Course', 'Account']
attr_accessible :privacy_level, :domain, :url, :shared_secret, :consumer_key,
@ -46,6 +48,77 @@ class ContextExternalTool < ActiveRecord::Base
:course_settings_sub_navigation
]
EXTENSION_TYPES.each do |type|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{type}(setting=nil)
extension_setting(:#{type}, setting)
end
def #{type}=(hash)
set_extension_setting(:#{type}, hash)
end
RUBY
end
def extension_setting(type, property = nil)
type = type.to_sym
return settings[type] unless property && settings[type]
settings[type][property] || settings[property] || extension_default_value(property)
end
def set_extension_setting(type, hash)
if !hash || !hash.is_a?(Hash)
settings.delete type
return
end
custom_keys = case type
when :course_navigation, :course_home_sub_navigation, :course_settings_sub_navigation
keys = {
:visibility => lambda{|v| %w{members admins}.include?(v)}
}.to_a
keys << :default if type == :course_navigation
keys << :icon_url if [:course_home_sub_navigation, :course_settings_sub_navigation].include?(type)
keys
when :resource_selection, :editor_button, :homework_submission, :migration_selection
[:selection_width, :selection_height, :icon_url]
else
[]
end
hash = hash.with_indifferent_access
hash[:enabled] = Canvas::Plugin.value_to_boolean(hash[:enabled]) if hash[:enabled]
settings[type] = {}.with_indifferent_access
extension_keys = [:url, :text, :display_type, :custom_fields, :enabled] + custom_keys
extension_keys.each do |key, validator|
if hash.has_key?(key) && (!validator || validator.call(hash[key]))
settings[type][key] = hash[key]
end
end
settings[type]
end
def has_placement?(type)
self.context_external_tool_placements.for_type(type).exists?
end
def set_placement!(type, value=true)
raise "invalid type" unless EXTENSION_TYPES.include?(type.to_sym)
if value
self.context_external_tool_placements.new(:placement_type => type) unless has_placement?(type)
else
if self.persisted?
self.context_external_tool_placements.for_type(type).delete_all
else
self.context_external_tool_placements.delete_if{|p| p.placement_type == type}
end
end
end
def url_or_domain_is_set
setting_types = EXTENSION_TYPES
# url or domain (or url on canvas lti extension) is required
@ -189,90 +262,6 @@ class ContextExternalTool < ActiveRecord::Base
settings[:custom_fields]
end
def course_navigation=(hash)
tool_setting(:course_navigation, hash, :default) { |nav_settings|
if hash[:visibility] == 'members' || hash[:visibility] == 'admins'
nav_settings[:visibility] = hash[:visibility]
end
}
end
def course_navigation(setting = nil)
extension_setting(:course_navigation, setting)
end
def account_navigation=(hash)
tool_setting(:account_navigation, hash)
end
def account_navigation(setting = nil)
extension_setting(:account_navigation, setting)
end
def user_navigation=(hash)
tool_setting(:user_navigation, hash)
end
def user_navigation(setting = nil)
extension_setting(:user_navigation, setting)
end
def resource_selection=(hash)
tool_setting(:resource_selection, hash, :selection_width, :selection_height, :icon_url)
end
def resource_selection(setting = nil)
extension_setting(:resource_selection, setting)
end
def editor_button=(hash)
tool_setting(:editor_button, hash, :selection_width, :selection_height, :icon_url)
end
def editor_button(setting = nil)
extension_setting(:editor_button, setting)
end
def homework_submission=(hash)
tool_setting(:homework_submission, hash, :selection_width, :selection_height, :icon_url)
end
def homework_submission(setting = nil)
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 course_home_sub_navigation=(hash)
tool_setting(:course_home_sub_navigation, hash, :icon_url) do |tool_settings|
if %w(members admins).include?(hash[:visibility])
tool_settings[:visibility] = hash[:visibility]
end
end
end
def course_home_sub_navigation(setting = nil)
extension_setting(:course_home_sub_navigation, setting)
end
def course_settings_sub_navigation=(hash)
tool_setting(:course_settings_sub_navigation, hash, :icon_url) do |tool_settings|
if %w(members admins).include?(hash[:visibility])
tool_settings[:visibility] = hash[:visibility]
end
end
end
def course_settings_sub_navigation(setting = nil)
extension_setting(:course_settings_sub_navigation, setting)
end
def icon_url=(i_url)
settings[:icon_url] = i_url
end
@ -297,12 +286,6 @@ class ContextExternalTool < ActiveRecord::Base
extension_setting(extension_type, :display_type) || 'in_context'
end
def extension_setting(type, property = nil)
type = type.to_sym
return settings[type] unless property && settings[type]
settings[type][property] || settings[property] || extension_default_value(property)
end
def extension_default_value(property)
case property
when :url
@ -340,8 +323,7 @@ class ContextExternalTool < ActiveRecord::Base
settings.delete(:editor_button) if !editor_button(:icon_url)
EXTENSION_TYPES.each do |type|
message = "has_#{type}="
self.send(message, !!settings[type]) if self.respond_to?(message)
set_placement!(type, !!settings[type])
end
true
end
@ -474,7 +456,9 @@ class ContextExternalTool < ActiveRecord::Base
return nil if contexts.empty?
tools = contexts.each_with_object([]) do |context, tools|
tools.concat context.context_external_tools.active
scope = context.context_external_tools.active
scope = scope.having_setting(options[:type]) if options[:type]
tools.concat scope
end
Canvas::ICU.collate_by(tools, &:name)
end
@ -522,7 +506,8 @@ class ContextExternalTool < ActiveRecord::Base
nil
end
scope :having_setting, lambda { |setting| setting ? where("has_#{setting.to_s}" => true) : scoped }
scope :having_setting, lambda { |setting| setting ? joins(:context_external_tool_placements).
where("context_external_tool_placements.placement_type = ?", setting) : scoped }
def self.find_for(id, context, type, raise_error=true)
id = id[Api::ID_REGEX] if id.is_a?(String)
@ -615,27 +600,4 @@ class ContextExternalTool < ActiveRecord::Base
raise "Empty value" if str.blank?
Canvas::Security.hmac_sha1(str, shard.settings[:encryption_key])
end
def tool_setting(setting, hash, *keys)
if !hash || !hash.is_a?(Hash)
settings.delete setting
return
else
settings[setting] = {}.with_indifferent_access
end
hash = hash.with_indifferent_access
settings[setting][:url] = hash[:url] if hash[:url]
settings[setting][:text] = hash[:text] if hash[:text]
settings[setting][:display_type] = hash[:display_type] if hash[:display_type]
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?
settings[setting]
end
end

View File

@ -0,0 +1,8 @@
class ContextExternalToolPlacement < ActiveRecord::Base
belongs_to :context_external_tool
attr_accessible :placement_type
validates_inclusion_of :placement_type, :in => ContextExternalTool::EXTENSION_TYPES.map(&:to_s)
scope :for_type, lambda { |type| where(:placement_type => type) }
end

View File

@ -0,0 +1,86 @@
class CreateContextExternalToolPlacements < ActiveRecord::Migration
tag :predeploy
EXTENSION_TYPES = [:account_navigation, :course_home_sub_navigation, :course_navigation,
:course_settings_sub_navigation, :editor_button, :homework_submission,
:migration_selection, :resource_selection, :user_navigation]
def up
create_table :context_external_tool_placements do |t|
t.string :placement_type
t.integer :context_external_tool_id, limit: 8, null: false
end
add_index :context_external_tool_placements, :context_external_tool_id, :name => 'external_tool_placements_tool_id'
add_index :context_external_tool_placements, [:placement_type, :context_external_tool_id], unique: true, :name => 'external_tool_placements_type_and_tool_id'
add_foreign_key :context_external_tool_placements, :context_external_tools
# create some triggers so nothing falls through the cracks
if connection.adapter_name == 'PostgreSQL'
EXTENSION_TYPES.each do |type|
column = "has_#{type}"
create_trigger("tool_after_insert_#{type}_is_true__tr", :generated => true).
on("context_external_tools").
after(:insert).
where("NEW.#{column}") do
<<-SQL_ACTIONS
INSERT INTO context_external_tool_placements(placement_type, context_external_tool_id)
VALUES ('#{type}', NEW.id)
SQL_ACTIONS
end
create_trigger("tool_after_update_#{type}_is_true__tr", :generated => true).
on("context_external_tools").
after(:update).
where("NEW.#{column}") do
<<-SQL_ACTIONS
INSERT INTO context_external_tool_placements(placement_type, context_external_tool_id)
SELECT '#{type}', NEW.id
WHERE NOT EXISTS(
SELECT 1 FROM context_external_tool_placements WHERE placement_type = '#{type}' AND context_external_tool_id = NEW.id
)
SQL_ACTIONS
end
create_trigger("tool_after_update_#{type}_is_false__tr", :generated => true).
on("context_external_tools").
after(:update).
where("NOT NEW.#{column}") do
<<-SQL_ACTIONS
DELETE FROM context_external_tool_placements WHERE placement_type = '#{type}' AND context_external_tool_id = NEW.id
SQL_ACTIONS
end
end
end
# now populate the placements
EXTENSION_TYPES.each do |type|
column = :"has_#{type}"
ContextExternalTool.where(column => true).find_ids_in_batches do |ids|
opts = ids.map{|id| {:context_external_tool_id => id, :placement_type => type}}
ActiveRecord::Base.connection.bulk_insert('context_external_tool_placements', opts)
end
end
end
def down
EXTENSION_TYPES.each do |type|
column = :"has_#{type}"
# set it false if the placement is missing
ContextExternalTool.where(column => true).find_ids_in_batches do |ids|
untrue_ids = ids - ContextExternalToolPlacement.where(:context_external_tool_id => ids).pluck(:context_external_tool_id)
ContextExternalTool.where(:id => untrue_ids).update_all(column => false)
end
# set it true if the placement is there
ContextExternalToolPlacement.where(:placement_type => type).find_in_batches do |placements|
ContextExternalTool.where(:id => placements.map(&:context_external_tool_id)).update_all(column => true)
end
end
drop_table :context_external_tool_placements
end
end

View File

@ -0,0 +1,37 @@
class DropHasColumnsFromContextExternalTools < ActiveRecord::Migration
tag :postdeploy
EXTENSION_TYPES = [:account_navigation, :course_home_sub_navigation, :course_navigation,
:course_settings_sub_navigation, :editor_button, :homework_submission,
:migration_selection, :resource_selection, :user_navigation]
def up
if connection.adapter_name == 'PostgreSQL'
EXTENSION_TYPES.each do |type|
drop_trigger("tool_after_insert_#{type}_is_true__tr", "context_external_tools", :generated => true)
drop_trigger("tool_after_update_#{type}_is_true__tr", "context_external_tools", :generated => true)
drop_trigger("tool_after_update_#{type}_is_false__tr", "context_external_tools", :generated => true)
end
end
EXTENSION_TYPES.each do |type|
remove_column :context_external_tools, :"has_#{type}"
end
EXTENSION_TYPES.each do |type|
next if type == :homework_submission # note, there is no index for homework_submission
remove_index :context_external_tools, :"external_tools_#{type}"
end
end
def down
EXTENSION_TYPES.each do |type|
add_column :context_external_tools, :"has_#{type}", :boolean
end
EXTENSION_TYPES.each do |type|
next if type == :homework_submission
add_index :context_external_tools, [:context_id, :context_type, :"has_#{type}"], :name => "external_tools_#{type}"
end
end
end

View File

@ -254,7 +254,7 @@ describe ExternalToolsController do
assigns[:tool].url.should == "http://example.com/other_url"
assigns[:tool].consumer_key.should == "key"
assigns[:tool].shared_secret.should == "secret"
assigns[:tool].has_editor_button.should be_true
assigns[:tool].has_placement?(:editor_button).should be_true
end
it "should handle advanced xml configurations with no url or domain set" do
@ -296,7 +296,7 @@ describe ExternalToolsController do
assigns[:tool].domain.should be_nil
assigns[:tool].consumer_key.should == "key"
assigns[:tool].shared_secret.should == "secret"
assigns[:tool].has_editor_button.should be_true
assigns[:tool].has_placement?(:editor_button).should be_true
end
it "should handle advanced xml configurations by URL retrieval" do
@ -340,7 +340,7 @@ describe ExternalToolsController do
assigns[:tool].url.should == "http://example.com/other_url"
assigns[:tool].consumer_key.should == "key"
assigns[:tool].shared_secret.should == "secret"
assigns[:tool].has_editor_button.should be_true
assigns[:tool].has_placement?(:editor_button).should be_true
end
it "should fail gracefully on invalid URL retrieval or timeouts" do

View File

@ -0,0 +1,53 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
require 'db/migrate/20140806161233_create_context_external_tool_placements.rb'
require 'db/migrate/20140806162559_drop_has_columns_from_context_external_tools.rb'
describe 'CreateContextExternalToolPlacements' do
describe "up" do
it "should populate the context external tool placements table" do
pending("PostgreSQL specific") unless ContentExport.connection.adapter_name == 'PostgreSQL'
course
migration1 = CreateContextExternalToolPlacements.new
migration2 = DropHasColumnsFromContextExternalTools.new
tool1 = @course.context_external_tools.new(:name => 'blah', :domain => "google.com", :consumer_key => '12345', :shared_secret => 'secret')
tool1.settings = {:course_navigation => {:url => "http://www.example.com"}}
tool1.save!
tool1.has_placement?(:course_navigation).should == true
migration2.down
migration1.down
# make sure that the down undoes all the things
ContextExternalTool.reset_column_information
tool1_old = ContextExternalTool.find(tool1.id)
tool1_old.has_course_navigation.should == true
migration1.up
# make sure the triggers work while they need to
# on update to false
ContextExternalTool.connection.execute("UPDATE context_external_tools SET has_course_navigation = 'f' WHERE id = #{tool1.id}")
# on update to true
ContextExternalTool.connection.execute("UPDATE context_external_tools SET has_account_navigation = 't' WHERE id = #{tool1.id}")
# and on re-update to true
ContextExternalTool.connection.execute("UPDATE context_external_tools SET has_account_navigation = 't' WHERE id = #{tool1.id}")
# on insert
ContextExternalTool.connection.execute("INSERT INTO context_external_tools(
context_id, context_type, workflow_state, name, shared_secret, consumer_key, created_at, updated_at, has_user_navigation)
VALUES(#{@course.id}, 'Course', 'active', '', '', '', '2014-07-07', '2014-07-07', 't')")
migration2.up
ContextExternalTool.reset_column_information
tool1.reload
tool1.has_placement?(:course_navigation).should == false
tool1.has_placement?(:account_navigation).should == true
tool2 = @course.context_external_tools.detect{|t| t.id != tool1.id}
tool2.has_placement?(:user_navigation).should == true
end
end
end

View File

@ -661,7 +661,7 @@ describe Account do
tool = @account.context_external_tools.new(:name => "bob", :consumer_key => "bob", :shared_secret => "bob", :domain => "example.com")
tool.user_navigation = {:url => "http://www.example.com", :text => "Example URL"}
tool.save!
tool.has_account_navigation.should == false
tool.has_placement?(:account_navigation).should == false
tabs = @account.tabs_available(nil)
tabs.map{|t| t[:id] }.should_not be_include(tool.asset_string)
end
@ -685,7 +685,7 @@ describe Account do
tool1, tool2 = tools
tool2.destroy
tools.each { |t| t.has_account_navigation.should == true }
tools.each { |t| t.has_placement?(:account_navigation).should == true }
tabs = @account.tabs_available
tab_ids = tabs.map{|t| t[:id] }
@ -701,7 +701,7 @@ describe Account do
tool = @account.context_external_tools.new(:name => "bob", :consumer_key => "bob", :shared_secret => "bob", :domain => "example.com")
tool.account_navigation = {:url => "http://www.example.com", :text => "Example URL"}
tool.save!
tool.has_account_navigation.should == true
tool.has_placement?(:account_navigation).should == true
tabs = @account.tabs_available(nil)
tabs.map{|t| t[:id] }.should be_include(tool.asset_string)
tab = tabs.detect{|t| t[:id] == tool.asset_string }

View File

@ -27,7 +27,7 @@ describe ContentMigration do
tool_to.name.should == @tool_from.name
tool_to.custom_fields.should == @tool_from.custom_fields
tool_to.has_course_navigation.should == true
tool_to.has_placement?(:course_navigation).should == true
tool_to.consumer_key.should == @tool_from.consumer_key
tool_to.shared_secret.should == @tool_from.shared_secret
end
@ -47,7 +47,7 @@ describe ContentMigration do
tool_to = @copy_to.context_external_tools.first
tool_to.name.should == @tool_from.name
tool_to.consumer_key.should == @tool_from.consumer_key
tool_to.has_course_navigation.should == true
tool_to.has_placement?(:course_navigation).should == true
end
it "should copy external tool assignments" do

View File

@ -92,7 +92,7 @@ describe ContextExternalTool do
:text => "Example"
}
@tool.save!
@tool.has_course_navigation.should == false
@tool.has_placement?(:course_navigation).should == false
end
it "should not validate with no domain or url setting" do
@ -115,7 +115,7 @@ describe ContextExternalTool do
:enabled => "true"
}
@tool.save!
@tool.has_course_navigation.should == true
@tool.has_placement?(:course_navigation).should == true
end
it "should clear disabled extensions" do
@ -124,7 +124,7 @@ describe ContextExternalTool do
:enabled => "false"
}
@tool.save!
@tool.has_course_navigation.should == false
@tool.has_placement?(:course_navigation).should == false
end
describe "find_external_tool" do
@ -448,44 +448,44 @@ describe ContextExternalTool do
tool.editor_button.should_not be_nil
end
it "should set has_user_navigation if navigation configured" do
it "should set user_navigation if navigation configured" do
tool = new_external_tool
tool.settings = {:user_navigation => {:url => "http://www.example.com"}}
tool.has_user_navigation.should be_false
tool.has_placement?(:user_navigation).should be_false
tool.save
tool.has_user_navigation.should be_true
tool.has_placement?(:user_navigation).should be_true
end
it "should set has_course_navigation if navigation configured" do
it "should set course_navigation if navigation configured" do
tool = new_external_tool
tool.settings = {:course_navigation => {:url => "http://www.example.com"}}
tool.has_course_navigation.should be_false
tool.has_placement?(:course_navigation).should be_false
tool.save
tool.has_course_navigation.should be_true
tool.has_placement?(:course_navigation).should be_true
end
it "should set has_account_navigation if navigation configured" do
it "should set account_navigation if navigation configured" do
tool = new_external_tool
tool.settings = {:account_navigation => {:url => "http://www.example.com"}}
tool.has_account_navigation.should be_false
tool.has_placement?(:account_navigation).should be_false
tool.save
tool.has_account_navigation.should be_true
tool.has_placement?(:account_navigation).should be_true
end
it "should set has_resource_selection if selection configured" do
it "should set resource_selection if selection configured" do
tool = new_external_tool
tool.settings = {:resource_selection => {:url => "http://www.example.com", :selection_width => 100, :selection_height => 100}}
tool.has_resource_selection.should be_false
tool.has_placement?(:resource_selection).should be_false
tool.save
tool.has_resource_selection.should be_true
tool.has_placement?(:resource_selection).should be_true
end
it "should set has_editor_button if button configured" do
it "should set editor_button if button configured" do
tool = new_external_tool
tool.settings = {:editor_button => {:url => "http://www.example.com", :icon_url => "http://www.example.com", :selection_width => 100, :selection_height => 100}}
tool.has_editor_button.should be_false
tool.has_placement?(:editor_button).should be_false
tool.save
tool.has_editor_button.should be_true
tool.has_placement?(:editor_button).should be_true
end
it "should allow setting tool_id and icon_url" do

View File

@ -2457,7 +2457,7 @@ describe Course, 'tabs_available' do
tool = new_external_tool @course
tool.user_navigation = {:url => "http://www.example.com", :text => "Example URL"}
tool.save!
tool.has_course_navigation.should == false
tool.has_placement?(:course_navigation).should == false
@teacher = user_model
@course.enroll_teacher(@teacher).accept
tabs = @course.tabs_available(@teacher)
@ -2468,7 +2468,7 @@ describe Course, 'tabs_available' do
tool = new_external_tool @course
tool.course_navigation = {:url => "http://www.example.com", :text => "Example URL"}
tool.save!
tool.has_course_navigation.should == true
tool.has_placement?(:course_navigation).should == true
@teacher = user_model
@course.enroll_teacher(@teacher).accept
tabs = @course.tabs_available(@teacher)
@ -2485,7 +2485,7 @@ describe Course, 'tabs_available' do
tool = new_external_tool @account
tool.course_navigation = {:url => "http://www.example.com", :text => "Example URL"}
tool.save!
tool.has_course_navigation.should == true
tool.has_placement?(:course_navigation).should == true
@teacher = user_model
@course.enroll_teacher(@teacher).accept
tabs = @course.tabs_available(@teacher)
@ -2502,7 +2502,7 @@ describe Course, 'tabs_available' do
tool = new_external_tool @account.root_account
tool.course_navigation = {:url => "http://www.example.com", :text => "Example URL"}
tool.save!
tool.has_course_navigation.should == true
tool.has_placement?(:course_navigation).should == true
@teacher = user_model
@course.enroll_teacher(@teacher).accept
tabs = @course.tabs_available(@teacher)
@ -2520,7 +2520,7 @@ describe Course, 'tabs_available' do
tool = new_external_tool @course
tool.course_navigation = {:url => "http://www.example.com", :text => "Example URL", :visibility => 'admins'}
tool.save!
tool.has_course_navigation.should == true
tool.has_placement?(:course_navigation).should == true
@teacher = user_model
@course.enroll_teacher(@teacher).accept
@student = user_model
@ -2545,7 +2545,7 @@ describe Course, 'tabs_available' do
tool = new_external_tool @course
tool.course_navigation = {:url => "http://www.example.com", :text => "Example URL", :visibility => 'members'}
tool.save!
tool.has_course_navigation.should == true
tool.has_placement?(:course_navigation).should == true
@teacher = user_model
@course.enroll_teacher(@teacher).accept
@student = user_model
@ -2567,7 +2567,7 @@ describe Course, 'tabs_available' do
tool = new_external_tool @course
tool.course_navigation = {:url => "http://www.example.com", :text => "Example URL"}
tool.save!
tool.has_course_navigation.should == true
tool.has_placement?(:course_navigation).should == true
@teacher = user_model
@course.enroll_teacher(@teacher).accept
@course.tab_configuration = Course.default_tabs.map{|t| {:id => t[:id] } }.insert(1, {:id => tool.asset_string})
@ -2580,7 +2580,7 @@ describe Course, 'tabs_available' do
tool = new_external_tool @course
tool.course_navigation = {:url => "http://www.example.com", :text => "Example URL"}
tool.save!
tool.has_course_navigation.should == true
tool.has_placement?(:course_navigation).should == true
@teacher = user_model
@course.enroll_teacher(@teacher).accept
tabs = @course.tabs_available(@teacher)
@ -2605,7 +2605,7 @@ describe Course, 'tabs_available' do
tool.save!
tool.course_navigation(:url).should == "http://www.example.com"
tool.has_course_navigation.should == true
tool.has_placement?(:course_navigation).should == true
settings = @course.external_tool_tabs({}).first
settings.should include(:visibility=>"members")
@ -2620,7 +2620,7 @@ describe Course, 'tabs_available' do
tool.save!
tool.course_navigation(:url).should == "http://www.example.com"
tool.has_course_navigation.should == true
tool.has_placement?(:course_navigation).should == true
settings = @course.external_tool_tabs({}).first
settings.should include(:visibility=>"admins")

View File

@ -1065,7 +1065,7 @@ describe User do
tool = Account.default.context_external_tools.new(:consumer_key => 'bob', :shared_secret => 'bob', :name => 'bob', :domain => "example.com")
tool.course_navigation = {:url => "http://www.example.com", :text => "Example URL"}
tool.save!
tool.has_user_navigation.should == false
tool.has_placement?(:user_navigation).should == false
user_model
tabs = @user.profile.tabs_available(@user, :root_account => Account.default)
tabs.map{|t| t[:id] }.should_not be_include(tool.asset_string)
@ -1075,7 +1075,7 @@ describe User do
tool = Account.default.context_external_tools.new(:consumer_key => 'bob', :shared_secret => 'bob', :name => 'bob', :domain => "example.com")
tool.user_navigation = {:url => "http://www.example.com", :text => "Example URL"}
tool.save!
tool.has_user_navigation.should == true
tool.has_placement?(:user_navigation).should == true
user_model
tabs = @user.profile.tabs_available(@user, :root_account => Account.default)
tabs.map{|t| t[:id] }.should be_include(tool.asset_string)

View File

@ -46,7 +46,7 @@ shared_examples_for "external tools tests" do
tool.workflow_state.should == "anonymous"
tool.url.should == "http://www.edu-apps.org/tool_redirect?id=youtube"
tool.description.should include_text "YouTube videos"
tool.has_editor_button.should be_true
tool.has_placement?(:editor_button).should be_true
tool.settings.should be_present
tool.editor_button.should be_present
f("#external_tool_#{tool.id} .edit_tool_link").should be_displayed