add course_home_sub_navigation extension to external tools
this puts lti app links on the right side bar of the course home page. fixes RAN-53, RAN-55 test plan: - modify an lti app's xml to include the course_home_sub_navigation extension - configure an lti app via modified xml - navigate to a course home page, where you should see a button for the configured tool on the right sidebar. - clicking on the button should launch the tool. - configure another tool the same way, but include a "visibility" property in new extension with a value of "admins" - view the course home page as a teacher. you should be able to tee the newly configured tool, in addition to the previously configured tool. - view the course home page as a student. you should only see the first tool you configured, and not see the tool with the limited visibility property. Change-Id: Ibe50c649f6d5f6806a87f0c8e8402f1209b9ed40 Reviewed-on: https://gerrit.instructure.com/35161 Reviewed-by: Brad Humphrey <brad@instructure.com> Tested-by: Jenkins <jenkins@instructure.com> QA-Review: Nathan Rogowski <nathan@instructure.com> Product-Review: Jon Willesen <jonw@instructure.com>
This commit is contained in:
parent
08ae58b7a9
commit
3c65211658
|
@ -23,6 +23,7 @@ define [
|
|||
{extension_type: 'user_navigation', text: I18n.t 'user_navigation_configured', 'User navigation configured'}
|
||||
{extension_type: 'homework_submission', text: I18n.t 'homework_submission_configured', 'Homework submission configured'}
|
||||
{extension_type: 'migration_selection', text: I18n.t 'migration_selection_configured', 'Migration selection configured'}
|
||||
{extension_type: 'course_home_sub_navigation', text: I18n.t 'course_home_sub_navigation_configured', 'Course home sub navigation configured'}
|
||||
]
|
||||
|
||||
json = super
|
||||
|
|
|
@ -1368,6 +1368,11 @@ class CoursesController < ApplicationController
|
|||
if @current_user and (@show_recent_feedback = @context.user_is_student?(@current_user))
|
||||
@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?)
|
||||
unless @context.grants_right?(@current_user, session, :manage_content)
|
||||
@course_home_sub_navigation_tools.reject! { |tool| tool.course_home_sub_navigation(:visibility) == 'admins' }
|
||||
end
|
||||
else
|
||||
# clear notices that would have been displayed as a result of processing
|
||||
# an enrollment invitation, since we're giving an error
|
||||
|
|
|
@ -9,6 +9,7 @@ class ContextExternalTool < ActiveRecord::Base
|
|||
:name, :description, :custom_fields, :custom_fields_string,
|
||||
:course_navigation, :account_navigation, :user_navigation,
|
||||
:resource_selection, :editor_button, :homework_submission,
|
||||
:course_home_sub_navigation,
|
||||
:config_type, :config_url, :config_xml, :tool_id
|
||||
|
||||
validates_presence_of :context_id, :context_type, :workflow_state
|
||||
|
@ -38,7 +39,7 @@ class ContextExternalTool < ActiveRecord::Base
|
|||
can :read and can :update and can :delete
|
||||
end
|
||||
|
||||
EXTENSION_TYPES = [:user_navigation, :course_navigation, :account_navigation, :resource_selection, :editor_button, :homework_submission, :migration_selection]
|
||||
EXTENSION_TYPES = [:user_navigation, :course_navigation, :account_navigation, :resource_selection, :editor_button, :homework_submission, :migration_selection, :course_home_sub_navigation]
|
||||
def url_or_domain_is_set
|
||||
setting_types = EXTENSION_TYPES
|
||||
# url or domain (or url on canvas lti extension) is required
|
||||
|
@ -242,6 +243,18 @@ class ContextExternalTool < ActiveRecord::Base
|
|||
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 icon_url=(i_url)
|
||||
settings[:icon_url] = i_url
|
||||
end
|
||||
|
|
|
@ -17,8 +17,15 @@
|
|||
<% @can_manage_content = can_do(@context, @current_user, :manage_content) %>
|
||||
<% if @context.feature_enabled?(:draft_state) %>
|
||||
|
||||
<% if @can_manage_content || @course_home_view != 'feed' %>
|
||||
<% if @can_manage_content || @course_home_view != 'feed' || @course_home_sub_navigation_tools.present? %>
|
||||
<div class="course-options">
|
||||
<% @course_home_sub_navigation_tools.each do |tool| %>
|
||||
<a class="button-sidebar-wide course-home-sub-navigation-lti"
|
||||
href="<%= course_external_tool_path(@context, tool, launch_type: 'course_home_sub_navigation') %>">
|
||||
<img class="icon" src="<%= tool.course_home_sub_navigation(:icon_url) %>" />
|
||||
<%= tool.label_for(:course_home_sub_navigation) %>
|
||||
</a>
|
||||
<% end %>
|
||||
<% if @can_manage_content %>
|
||||
<a class="button-sidebar-wide element_toggler" aria-controls="edit_course_home_content_form" href="<%= context_url(@context, :context_details_url) %>">
|
||||
<i class="icon-target"></i>
|
||||
|
@ -45,10 +52,19 @@
|
|||
<% end %>
|
||||
|
||||
<% else %>
|
||||
<% if @can_manage_content %>
|
||||
<% if @can_manage_content || @course_home_sub_navigation_tools.present? %>
|
||||
<div class="secondary-button-group rs-margin-lr rs-margin-top rs-margin-bottom">
|
||||
<a href="#" class="btn button-sidebar-wide wizard_popup_link <%= 'auto_open' if @context.created? || @context.claimed? %>"><i class="icon-question"></i> <%= t('links.course_setup', %{Course Setup Checklist}) %></a>
|
||||
<a class="btn button-sidebar-wide" href="<%= context_url(@context, :new_context_discussion_topic_url, :is_announcement => true) %>"><i class="icon-announcement"></i> <%= t('links.new_announcement', %{New Announcement}) %></a>
|
||||
<% @course_home_sub_navigation_tools.each do |tool| %>
|
||||
<a class="btn button-sidebar-wide course-home-sub-navigation-lti"
|
||||
href="<%= course_external_tool_path(@context, tool, launch_type: 'course_home_sub_navigation') %>">
|
||||
<img class="icon" src="<%= tool.course_home_sub_navigation(:icon_url) %>" />
|
||||
<%= tool.label_for(:course_home_sub_navigation) %>
|
||||
</a>
|
||||
<% end %>
|
||||
<% if @can_manage_content %>
|
||||
<a href="#" class="btn button-sidebar-wide wizard_popup_link <%= 'auto_open' if @context.created? || @context.claimed? %>"><i class="icon-question"></i> <%= t('links.course_setup', %{Course Setup Checklist}) %></a>
|
||||
<a class="btn button-sidebar-wide" href="<%= context_url(@context, :new_context_discussion_topic_url, :is_announcement => true) %>"><i class="icon-announcement"></i> <%= t('links.new_announcement', %{New Announcement}) %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
class AddCourseHomeNavigationForExternalTools < ActiveRecord::Migration
|
||||
tag :predeploy
|
||||
def self.up
|
||||
add_column :context_external_tools, :has_course_home_sub_navigation, :boolean
|
||||
add_index :context_external_tools, [:context_id, :context_type, :has_course_home_sub_navigation], :name => "external_tools_course_home_sub_navigation"
|
||||
end
|
||||
|
||||
def self.down
|
||||
remove_column :context_external_tools, :has_course_home_sub_navigation
|
||||
remove_index :context_external_tools, :name => "external_tools_course_home_sub_navigation"
|
||||
end
|
||||
end
|
|
@ -267,7 +267,6 @@ describe ExternalToolsController, type: :request do
|
|||
json = api_call(:get, "/api/v1/#{type}s/#{context.id}/external_tools/#{et.id}.json",
|
||||
{:controller => 'external_tools', :action => 'show', :format => 'json',
|
||||
:"#{type}_id" => context.id.to_s, :external_tool_id => et.id.to_s})
|
||||
|
||||
HashDiff.diff(json, example_json(et)).should == []
|
||||
end
|
||||
|
||||
|
@ -394,6 +393,7 @@ describe ExternalToolsController, type: :request do
|
|||
et.homework_submission = {:url=>"http://www.example.com/ims/lti/editor", :selection_width=>50, :selection_height=>50, :text=>"homework submission"}
|
||||
et.resource_selection = {:url=>"http://www.example.com/ims/lti/resource", :text => "", :selection_width=>50, :selection_height=>50}
|
||||
et.migration_selection = {:url=>"http://www.example.com/ims/lti/resource", :text => "migration selection", :selection_width=>42, :selection_height=>24}
|
||||
et.course_home_sub_navigation = {:url=>"http://www.example.com/ims/lti/resource", :text => "course home sub navigation", display_type: 'full_width', visibility: 'admins'}
|
||||
et.save!
|
||||
et
|
||||
end
|
||||
|
@ -502,6 +502,14 @@ describe ExternalToolsController, type: :request do
|
|||
"label"=>"migration selection",
|
||||
"url"=>"http://www.example.com/ims/lti/resource",
|
||||
"selection_height"=>24,
|
||||
"selection_width"=>42}}
|
||||
"selection_width"=>42},
|
||||
"course_home_sub_navigation"=>
|
||||
{"text"=>"course home sub navigation",
|
||||
"label"=>"course home sub navigation",
|
||||
"url"=>"http://www.example.com/ims/lti/resource",
|
||||
"visibility"=>'admins',
|
||||
"display_type"=>'full_width',
|
||||
"selection_height"=>400,
|
||||
"selection_width"=>800}}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -49,6 +49,7 @@ define [
|
|||
},
|
||||
"homework_submission": null,
|
||||
"migration_selection": null,
|
||||
"course_home_sub_navigation": null,
|
||||
"icon_url": "https://www.edu-apps.org/tools/khan_academy/icon.png"
|
||||
}
|
||||
)
|
||||
|
|
|
@ -210,6 +210,74 @@ describe "courses" do
|
|||
roles_to_sections[role_name].should == sections.first.text
|
||||
end
|
||||
end
|
||||
|
||||
context "course_home_sub_navigation lti apps" do
|
||||
def create_course_home_sub_navigation_tool(options = {})
|
||||
defaults = {
|
||||
name: options[:name] || "external tool",
|
||||
consumer_key: 'test',
|
||||
shared_secret: 'asdf',
|
||||
url: 'http://example.com/ims/lti',
|
||||
course_home_sub_navigation: { icon_url: '/images/delete.png' },
|
||||
}
|
||||
@course.context_external_tools.create!(defaults.merge(options))
|
||||
end
|
||||
|
||||
it "should display course_home_sub_navigation lti apps (draft state off)" do
|
||||
course_with_teacher_logged_in(active_all: true)
|
||||
num_tools = 3
|
||||
num_tools.times { |index| create_course_home_sub_navigation_tool(name: "external tool #{index}") }
|
||||
get "/courses/#{@course.id}"
|
||||
ff(".course-home-sub-navigation-lti").size.should == num_tools
|
||||
end
|
||||
|
||||
it "should display course_home_sub_navigation lti apps (draft state on)" do
|
||||
course_with_teacher_logged_in(active_all: true)
|
||||
@course.account.enable_feature!(:draft_state)
|
||||
num_tools = 2
|
||||
num_tools.times { |index| create_course_home_sub_navigation_tool(name: "external tool #{index}") }
|
||||
get "/courses/#{@course.id}"
|
||||
ff(".course-home-sub-navigation-lti").size.should == num_tools
|
||||
end
|
||||
|
||||
it "should include launch type parameter (draft state off)" do
|
||||
course_with_teacher_logged_in(active_all: true)
|
||||
create_course_home_sub_navigation_tool
|
||||
get "/courses/#{@course.id}"
|
||||
f('.course-home-sub-navigation-lti').attribute("href").should match(/launch_type=course_home_sub_navigation/)
|
||||
end
|
||||
|
||||
it "should include launch type parameter (draft state on)" do
|
||||
course_with_teacher_logged_in(active_all: true)
|
||||
@course.account.enable_feature!(:draft_state)
|
||||
create_course_home_sub_navigation_tool
|
||||
get "/courses/#{@course.id}"
|
||||
f('.course-home-sub-navigation-lti').attribute("href").should match(/launch_type=course_home_sub_navigation/)
|
||||
end
|
||||
|
||||
it "should only display active tools" do
|
||||
course_with_teacher_logged_in(active_all: true)
|
||||
tool = create_course_home_sub_navigation_tool
|
||||
tool.workflow_state = 'deleted'
|
||||
tool.save!
|
||||
get "/courses/#{@course.id}"
|
||||
ff(".course-home-sub-navigation-lti").size.should == 0
|
||||
end
|
||||
|
||||
it "should not display admin tools to students" do
|
||||
course_with_teacher_logged_in(active_all: true)
|
||||
tool = create_course_home_sub_navigation_tool
|
||||
tool.course_home_sub_navigation['visibility'] = 'admins'
|
||||
tool.save!
|
||||
get "/courses/#{@course.id}"
|
||||
ff(".course-home-sub-navigation-lti").size.should == 1
|
||||
|
||||
course_with_student_logged_in(course: @course, active_all: true)
|
||||
get "/courses/#{@course.id}"
|
||||
ff(".course-home-sub-navigation-lti").size.should == 0
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "course as a student" do
|
||||
|
|
|
@ -160,6 +160,11 @@ shared_examples_for "external tools tests" do
|
|||
<lticm:property name="selection_width">500</lticm:property>
|
||||
<lticm:property name="selection_height">300</lticm:property>
|
||||
</lticm:options>
|
||||
<lticm:options name="course_home_sub_navigation">
|
||||
<lticm:property name="url">https://example.com/wiki</lticm:property>
|
||||
<lticm:property name="text">Build/Link to Wiki Page</lticm:property>
|
||||
<lticm:property name="display_type">full_width</lticm:property>
|
||||
</lticm:options>
|
||||
XML
|
||||
f("#external_tool_config_xml").send_keys <<-XML
|
||||
<lticm:options name="user_navigation">
|
||||
|
|
Loading…
Reference in New Issue