canvas-lms/spec/helpers/section_tab_helper_spec.rb

427 lines
15 KiB
Ruby

# frozen_string_literal: true
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
shared_examples "allow Quiz LTI placement when the correct Feature Flags are enabled" do
let(:available_section_tabs) do
SectionTabHelperSpec::AvailableSectionTabs.new(
context, current_user, domain_root_account, session
)
end
it "includes Quiz LTI placement if new_quizzes_account_course_level_item_banks and quizzes_next are enabled" do
Account.site_admin.enable_feature!(:new_quizzes_account_course_level_item_banks)
allow(context).to receive(:feature_enabled?).and_call_original
allow(context).to receive(:feature_enabled?).with(:quizzes_next).and_return(true)
expect(Account.site_admin.feature_enabled?(:new_quizzes_account_course_level_item_banks)).to eq(true)
expect(context.feature_enabled?(:quizzes_next)).to eq(true)
expect(quiz_lti_tool.quiz_lti?).to eq(true)
expect(available_section_tabs.to_a.pluck(:id)).to include("context_external_tool_#{quiz_lti_tool.id}")
end
it "does not include Quiz LTI placement if new_quizzes_account_course_level_item_banks is not enabled" do
allow(context).to receive(:feature_enabled?).and_call_original
allow(context).to receive(:feature_enabled?).with(:quizzes_next).and_return(true)
expect(context.feature_enabled?(:quizzes_next)).to eq(true)
expect(Account.site_admin.feature_enabled?(:new_quizzes_account_course_level_item_banks)).to eq(false)
expect(quiz_lti_tool.quiz_lti?).to eq(true)
expect(available_section_tabs.to_a.pluck(:id)).not_to include("context_external_tool_#{quiz_lti_tool.id}")
end
it "does not include Quiz LTI placement if next_quizzes is not enabled" do
Account.site_admin.enable_feature!(:new_quizzes_account_course_level_item_banks)
expect(Account.site_admin.feature_enabled?(:new_quizzes_account_course_level_item_banks)).to eq(true)
expect(domain_root_account.feature_enabled?(:quizzes_next)).to eq(false)
expect(quiz_lti_tool.quiz_lti?).to eq(true)
expect(available_section_tabs.to_a.pluck(:id)).not_to include("context_external_tool_#{quiz_lti_tool.id}")
end
end
describe SectionTabHelper do
before do
stub_const("SectionTabHelperSpec", Class.new { include SectionTabHelper })
end
let_once(:course) { course_model }
describe "AvailableSectionTabs" do
let_once(:current_user) { course.users.first }
let_once(:domain_root_account) { LoadAccount.default_domain_root_account }
let(:session) { user_session(current_user) }
let_once(:quiz_lti_tool) do
ContextExternalTool.create!(
context: domain_root_account,
consumer_key: "key",
shared_secret: "secret",
name: "Quizzes 2",
tool_id: "Quizzes 2",
url: "http://www.tool.com/launch",
developer_key: DeveloperKey.create!,
root_account: domain_root_account
)
end
describe "#to_a" do
context "when context !tabs_available" do
let(:available_section_tabs) do
SectionTabHelperSpec::AvailableSectionTabs.new(
Object.new, current_user, domain_root_account, session
)
end
it "returns an empty array" do
a = available_section_tabs.to_a
expect(a).to be_a Array
expect(a).to be_empty
end
end
context "when context has tabs_available" do
let(:bad_tab) { { label: "bad tab" } }
before do
tabs = Course.default_tabs + [bad_tab]
allow(course).to receive(:tabs_available).and_return(tabs)
end
let(:available_section_tabs) do
SectionTabHelperSpec::AvailableSectionTabs.new(
course, current_user, domain_root_account, session
)
end
it "returns a non-empty array" do
expect(available_section_tabs.to_a).to be_a Array
expect(available_section_tabs.to_a).to_not be_empty
end
it "excludes tabs without label & href elements" do
expect(available_section_tabs.to_a).to_not include(bad_tab)
end
context "and tabs include TAB_CONFERENCES" do
it "includes TAB_CONFERENCES if WebConference.config" do
allow(WebConference).to receive(:config).and_return({})
expect(available_section_tabs.to_a.pluck(:id)).to include(Course::TAB_CONFERENCES)
end
it "does not include TAB_CONFERENCES if !WebConference.config" do
expect(available_section_tabs.to_a.pluck(:id)).to_not include(Course::TAB_CONFERENCES)
end
end
context "and tabs include TAB_COLLABORATIONS" do
it "includes TAB_COLLABORATIONS if Collaboration.any_collaborations_configured?" do
allow(Collaboration).to receive(:any_collaborations_configured?).and_return(true)
expect(available_section_tabs.to_a.pluck(:id)).to include(Course::TAB_COLLABORATIONS)
end
it "does not include TAB_COLLABORATIONS if !Collaboration.any_collaborations_configured?" do
expect(available_section_tabs.to_a.pluck(:id)).to_not include(Course::TAB_COLLABORATIONS)
end
it "does not include TAB_COLLABORATIONS when new_collaborations feature flag has been enabled" do
domain_root_account.set_feature_flag!(:new_collaborations, "on")
allow(Collaboration).to receive(:any_collaborations_configured?).and_return(true)
expect(available_section_tabs.to_a.pluck(:id)).not_to include(Course::TAB_COLLABORATIONS)
end
end
context "and tabs include TAB_COLLABORATIONS_NEW" do
it "includes TAB_COLLABORATIONS_NEW if new_collaborations feature flag has been enabled" do
domain_root_account.set_feature_flag!(:new_collaborations, "on")
expect(available_section_tabs.to_a.pluck(:id)).to include(Course::TAB_COLLABORATIONS_NEW)
domain_root_account.set_feature_flag!(:new_collaborations, "off")
end
it "does not include TAB_COLLABORATIONS if new_collaborations feature flas has been disabled" do
domain_root_account.set_feature_flag!(:new_collaborations, "off")
expect(available_section_tabs.to_a.pluck(:id)).not_to include(Course::TAB_COLLABORATIONS_NEW)
end
end
context "the root account has an account_navigation Quiz LTI placement and @context is an Account" do
let_once(:context) { domain_root_account }
before do
tabs = [
{
id: "context_external_tool_#{quiz_lti_tool.id}",
label: "Quizzes 2",
css_class: "context_external_tool_#{quiz_lti_tool.id}",
visibility: nil,
href: :account_external_tool_path,
external: true,
hidden: false,
args: [context.id, quiz_lti_tool.id]
},
{
id: 9,
label: "Settings",
css_class: "settings",
href: :account_settings_path
}
]
allow(context).to receive(:tabs_available).and_return(tabs)
end
include_examples "allow Quiz LTI placement when the correct Feature Flags are enabled"
end
context "the root account has a course_navigation Quiz LTI placement and @context is a Course" do
let_once(:context) { course }
before do
course_placement = {
id: "context_external_tool_#{quiz_lti_tool.id}",
label: "Item Banks",
css_class: "context_external_tool_#{quiz_lti_tool.id}",
visibility: nil,
href: :course_external_tool_path,
external: true,
hidden: false,
args: [context.id, quiz_lti_tool.id]
}
tabs = Course.default_tabs + [course_placement]
allow(context).to receive(:tabs_available).and_return(tabs)
end
include_examples "allow Quiz LTI placement when the correct Feature Flags are enabled"
end
context "the root account has non-Quiz_LTI navigation placements" do
before do
non_quiz_lti_course_placement = {
id: "context_external_tool_0",
label: "Other LTI",
css_class: "context_external_tool_0",
visibility: nil,
href: :some_path,
external: true,
hidden: false,
args: [course.id, 0]
}
tabs = Course.default_tabs + [non_quiz_lti_course_placement]
allow(course).to receive(:tabs_available).and_return(tabs)
end
let(:available_section_tabs) do
SectionTabHelperSpec::AvailableSectionTabs.new(
course, current_user, domain_root_account, session
)
end
it "includes non-Quiz_LTI placement ignoring quizzes FFs" do
expect(Account.site_admin.feature_enabled?(:new_quizzes_account_course_level_item_banks)).to eq(false)
expect(domain_root_account.feature_enabled?(:quizzes_next)).to eq(false)
expect(available_section_tabs.to_a.pluck(:id)).to include("context_external_tool_0")
end
end
end
end
end
describe "SectionTabTag" do
# has screenreader
let_once(:tab_assignments) do
Course.default_tabs.find do |tab|
tab[:id] == Course::TAB_ASSIGNMENTS
end
end
# does not have screenreader
let_once(:tab_pages) do
Course.default_tabs.find do |tab|
tab[:id] == Course::TAB_PAGES
end
end
let(:new_window_tab) do
{
id: 1,
label: "my_tab",
css_class: "my_class",
href: :course_external_tool_path,
external: true,
target: "_blank",
args: [1, 1]
}
end
describe "#a_classes" do
it "is an array including tab css_class" do
tag = SectionTabHelperSpec::SectionTabTag.new(
tab_assignments, course
)
expect(tag.a_classes).to be_a Array
expect(tag.a_classes).to include tab_assignments[:css_class]
expect(tag.a_classes).not_to include "active"
end
it "includes `active` class if tab is active" do
tag = SectionTabHelperSpec::SectionTabTag.new(
tab_assignments, course, tab_assignments[:css_class]
)
expect(tag.a_classes).to include "active"
end
end
describe "#a_attributes" do
it "includes keys href & class" do
tag = SectionTabHelperSpec::SectionTabTag.new(
tab_pages, course
)
expect(tag.a_attributes.keys).to include(:href, :class)
end
it "includes a target if tab has the target attribute" do
tag = SectionTabHelperSpec::SectionTabTag.new(new_window_tab, course)
expect(tag.a_attributes[:target]).to eq "_blank"
end
it "does not include aria-current if tab is not active" do
tag = SectionTabHelperSpec::SectionTabTag.new(new_window_tab, course)
expect(tag.a_attributes[:"aria-current"]).to eq nil
end
it "includes aria-current if tab is active" do
tag = SectionTabHelperSpec::SectionTabTag.new(new_window_tab, course, new_window_tab[:css_class])
expect(tag.a_attributes[:"aria-current"]).to eq "page"
end
end
describe "#a_tag" do
context "when tab is not hidden" do
let(:string) do
SectionTabHelperSpec::SectionTabTag.new(
tab_assignments, course
).a_tag
end
let(:html) { Nokogiri::HTML5.fragment(string).children[0] }
it "is an a tag" do
expect(html.name).to eq "a"
end
it "includes text from tab label" do
expect(html.text).to eq tab_assignments[:label]
end
it "does not include icon indicating it is off" do
icon = html.xpath("i")
expect(icon).to be_empty
end
end
context "when tab is unused" do
let(:string) do
SectionTabHelperSpec::SectionTabTag.new(
tab_assignments.merge(hidden_unused: true), course
).a_tag
end
let(:html) { Nokogiri::HTML5.fragment(string).children[0] }
it "has a tooltip" do
expect(html.attributes).to include("data-tooltip")
expect(html.attributes).to include("title")
expect(html.attributes["title"].value).to eq "No content. Not visible to students"
end
it "includes icon indicating it is not visible to students" do
icon = html.xpath('i[contains(@class, "nav-icon")]')[0]
expect(icon.attributes["class"].value).to include("icon-off")
end
end
context "when tab is hidden" do
let(:string) do
SectionTabHelperSpec::SectionTabTag.new(
tab_assignments.merge(hidden: true), course
).a_tag
end
let(:html) { Nokogiri::HTML5.fragment(string).children[0] }
it "has a tooltip" do
expect(html.attributes).to include("data-tooltip")
expect(html.attributes).to include("title")
expect(html.attributes["title"].value).to eq "Disabled. Not visible to students"
end
it "includes icon indicating it is not visible to students" do
icon = html.xpath('i[contains(@class, "nav-icon")]')[0]
expect(icon.attributes["class"].value).to include("icon-off")
end
end
context "when tab is neither hidden nor unused" do
let(:string) do
SectionTabHelperSpec::SectionTabTag.new(
tab_assignments.merge, course
).a_tag
end
let(:html) { Nokogiri::HTML5.fragment(string).children[0] }
it "does not have a title attribute" do
expect(html.attributes).not_to include("title")
end
end
end
describe "#li_classess" do
it "returns an array including element `section`" do
tag = SectionTabHelperSpec::SectionTabTag.new(
tab_assignments, course
)
expect(tag.li_classes).to be_a Array
expect(tag.li_classes).to include("section")
end
it "includes `section-hidden` if tab is hidden" do
tag = SectionTabHelperSpec::SectionTabTag.new(
tab_assignments.merge(hidden: true), course
)
expect(tag.li_classes).to include("section-hidden")
end
end
describe "#to_html" do
let(:string) do
SectionTabHelperSpec::SectionTabTag.new(
tab_assignments, course
).to_html
end
let(:html) { Nokogiri::HTML5.fragment(string).children[0] }
it "is an li tag" do
expect(html.name).to eq "li"
end
it "includes a nested a tag" do
expect(html.children.any? do |child|
child.name == "a"
end).to be_truthy
end
end
end
end