summaryrefslogtreecommitdiff
path: root/spec/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'spec/helpers')
-rw-r--r--spec/helpers/auto_devops_helper_spec.rb6
-rw-r--r--spec/helpers/avatars_helper_spec.rb2
-rw-r--r--spec/helpers/blob_helper_spec.rb38
-rw-r--r--spec/helpers/boards_helper_spec.rb16
-rw-r--r--spec/helpers/ci_status_helper_spec.rb76
-rw-r--r--spec/helpers/dashboard_helper_spec.rb39
-rw-r--r--spec/helpers/emails_helper_spec.rb2
-rw-r--r--spec/helpers/groups_helper_spec.rb46
-rw-r--r--spec/helpers/icons_helper_spec.rb20
-rw-r--r--spec/helpers/issuables_helper_spec.rb41
-rw-r--r--spec/helpers/labels_helper_spec.rb24
-rw-r--r--spec/helpers/markup_helper_spec.rb73
-rw-r--r--spec/helpers/namespaces_helper_spec.rb4
-rw-r--r--spec/helpers/notifications_helper_spec.rb11
-rw-r--r--spec/helpers/projects_helper_spec.rb25
-rw-r--r--spec/helpers/search_helper_spec.rb44
-rw-r--r--spec/helpers/sessions_helper_spec.rb17
-rw-r--r--spec/helpers/sorting_helper_spec.rb148
-rw-r--r--spec/helpers/submodule_helper_spec.rb94
-rw-r--r--spec/helpers/tracking_helper_spec.rb28
-rw-r--r--spec/helpers/users_helper_spec.rb2
-rw-r--r--spec/helpers/visibility_level_helper_spec.rb72
-rw-r--r--spec/helpers/wiki_helper_spec.rb2
23 files changed, 721 insertions, 109 deletions
diff --git a/spec/helpers/auto_devops_helper_spec.rb b/spec/helpers/auto_devops_helper_spec.rb
index d2540696b17..e80388f9ea7 100644
--- a/spec/helpers/auto_devops_helper_spec.rb
+++ b/spec/helpers/auto_devops_helper_spec.rb
@@ -118,7 +118,7 @@ describe AutoDevopsHelper do
it { is_expected.to eq('instance enabled') }
end
- context 'with groups', :nested_groups do
+ context 'with groups' do
before do
receiver.update(parent: parent)
end
@@ -170,7 +170,7 @@ describe AutoDevopsHelper do
it { is_expected.to eq('instance enabled') }
end
- context 'with groups', :nested_groups do
+ context 'with groups' do
let(:receiver) { create(:project, :repository, namespace: group) }
before do
@@ -203,7 +203,7 @@ describe AutoDevopsHelper do
it { is_expected.to be_nil }
end
- context 'with groups', :nested_groups do
+ context 'with groups' do
let(:receiver) { create(:project, :repository, namespace: group) }
context 'when auto devops is disabled on group level' do
diff --git a/spec/helpers/avatars_helper_spec.rb b/spec/helpers/avatars_helper_spec.rb
index aa0442ab847..94998d302f9 100644
--- a/spec/helpers/avatars_helper_spec.rb
+++ b/spec/helpers/avatars_helper_spec.rb
@@ -16,7 +16,7 @@ describe AvatarsHelper do
shared_examples 'resource with a custom avatar' do |source_type|
it 'returns a custom avatar image' do
expect(public_send("#{source_type}_icon", *helper_args))
- .to eq "<img src=\"#{resource.avatar.url}\" alt=\"Banana sample\" />"
+ .to eq "<img src=\"#{resource.avatar.url}\" />"
end
end
diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb
index 6808ed86c9a..1f236429347 100644
--- a/spec/helpers/blob_helper_spec.rb
+++ b/spec/helpers/blob_helper_spec.rb
@@ -29,14 +29,15 @@ describe BlobHelper do
let(:project) { create(:project, :repository, namespace: namespace) }
before do
- allow(self).to receive(:current_user).and_return(nil)
- allow(self).to receive(:can_collaborate_with_project?).and_return(true)
+ allow(helper).to receive(:current_user).and_return(nil)
+ allow(helper).to receive(:can?).and_return(true)
+ allow(helper).to receive(:can_collaborate_with_project?).and_return(true)
end
it 'verifies blob is text' do
expect(helper).not_to receive(:blob_text_viewable?)
- button = edit_blob_button(project, 'refs/heads/master', 'README.md')
+ button = helper.edit_blob_button(project, 'refs/heads/master', 'README.md')
expect(button).to start_with('<button')
end
@@ -46,25 +47,25 @@ describe BlobHelper do
expect(project.repository).not_to receive(:blob_at)
- edit_blob_button(project, 'refs/heads/master', 'README.md', blob: blob)
+ helper.edit_blob_button(project, 'refs/heads/master', 'README.md', blob: blob)
end
it 'returns a link with the proper route' do
stub_feature_flags(web_ide_default: false)
- link = edit_blob_button(project, 'master', 'README.md')
+ link = helper.edit_blob_button(project, 'master', 'README.md')
expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/#{project.full_path}/edit/master/README.md")
end
it 'returns a link with a Web IDE route' do
- link = edit_blob_button(project, 'master', 'README.md')
+ link = helper.edit_blob_button(project, 'master', 'README.md')
expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/-/ide/project/#{project.full_path}/edit/master/-/README.md")
end
it 'returns a link with the passed link_opts on the expected route' do
stub_feature_flags(web_ide_default: false)
- link = edit_blob_button(project, 'master', 'README.md', link_opts: { mr_id: 10 })
+ link = helper.edit_blob_button(project, 'master', 'README.md', link_opts: { mr_id: 10 })
expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/#{project.full_path}/edit/master/README.md?mr_id=10")
end
@@ -203,6 +204,13 @@ describe BlobHelper do
describe '#ide_edit_path' do
let(:project) { create(:project) }
+ let(:current_user) { create(:user) }
+ let(:can_push_code) { true }
+
+ before do
+ allow(helper).to receive(:current_user).and_return(current_user)
+ allow(helper).to receive(:can?).and_return(can_push_code)
+ end
around do |example|
old_script_name = Rails.application.routes.default_url_options[:script_name]
@@ -243,5 +251,21 @@ describe BlobHelper do
expect(helper.ide_edit_path(project, "testing/slashes", "readme.md/")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/testing/slashes/-/readme.md/")
end
+
+ context 'when user is not logged in' do
+ let(:current_user) { nil }
+
+ it 'returns IDE path inside the project' do
+ expect(helper.ide_edit_path(project, "master", "")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/master")
+ end
+ end
+
+ context 'when user cannot push to the project' do
+ let(:can_push_code) { false }
+
+ it "returns IDE path with the user's fork" do
+ expect(helper.ide_edit_path(project, "master", "")).to eq("/-/ide/project/#{current_user.namespace.full_path}/#{project.path}/edit/master")
+ end
+ end
end
end
diff --git a/spec/helpers/boards_helper_spec.rb b/spec/helpers/boards_helper_spec.rb
index b22947911b9..f014537eb54 100644
--- a/spec/helpers/boards_helper_spec.rb
+++ b/spec/helpers/boards_helper_spec.rb
@@ -1,10 +1,12 @@
require 'spec_helper'
describe BoardsHelper do
+ set(:project) { create(:project) }
+
describe '#build_issue_link_base' do
context 'project board' do
it 'returns correct path for project board' do
- @project = create(:project)
+ @project = project
@board = create(:board, project: @project)
expect(build_issue_link_base).to eq("/#{@project.namespace.path}/#{@project.path}/issues")
@@ -31,7 +33,6 @@ describe BoardsHelper do
describe '#board_data' do
let(:user) { create(:user) }
- let(:project) { create(:project) }
let(:board) { create(:board, project: project) }
before do
@@ -46,4 +47,15 @@ describe BoardsHelper do
expect(helper.board_data[:lists_endpoint]).to eq(board_lists_path(board))
end
end
+
+ describe '#current_board_json' do
+ let(:board_json) { helper.current_board_json }
+
+ it 'can serialise with a basic set of attributes' do
+ board = create(:board, project: project)
+ assign(:board, board)
+
+ expect(board_json).to match_schema('current-board')
+ end
+ end
end
diff --git a/spec/helpers/ci_status_helper_spec.rb b/spec/helpers/ci_status_helper_spec.rb
index bc2422aba90..4f665dc0514 100644
--- a/spec/helpers/ci_status_helper_spec.rb
+++ b/spec/helpers/ci_status_helper_spec.rb
@@ -53,4 +53,80 @@ describe CiStatusHelper do
expect(helper.pipeline_status_cache_key(pipeline_status)).to eq("pipeline-status/123abc-success")
end
end
+
+ describe "#render_status_with_link" do
+ subject { helper.render_status_with_link("success") }
+
+ it "renders a passed status icon" do
+ is_expected.to include("<span class=\"ci-status-link ci-status-icon-success d-inline-flex")
+ end
+
+ it "has 'Pipeline' as the status type in the title" do
+ is_expected.to include("title=\"Pipeline: passed\"")
+ end
+
+ it "has the success status icon" do
+ is_expected.to include("ci-status-icon-success")
+ end
+
+ context "when pipeline has commit path" do
+ subject { helper.render_status_with_link("success", "/commit-path") }
+
+ it "links to commit" do
+ is_expected.to include("href=\"/commit-path\"")
+ end
+
+ it "does not contain a span element" do
+ is_expected.not_to include("<span")
+ end
+
+ it "has 'Pipeline' as the status type in the title" do
+ is_expected.to include("title=\"Pipeline: passed\"")
+ end
+
+ it "has the correct status icon" do
+ is_expected.to include("ci-status-icon-success")
+ end
+ end
+
+ context "when different type than pipeline is provided" do
+ subject { helper.render_status_with_link("success", type: "commit") }
+
+ it "has the provided type in the title" do
+ is_expected.to include("title=\"Commit: passed\"")
+ end
+ end
+
+ context "when tooltip_placement is provided" do
+ subject { helper.render_status_with_link("success", tooltip_placement: "right") }
+
+ it "has the provided tooltip placement" do
+ is_expected.to include("data-placement=\"right\"")
+ end
+ end
+
+ context "when additional CSS classes are provided" do
+ subject { helper.render_status_with_link("success", cssclass: "extra-class") }
+
+ it "has appended extra class to icon classes" do
+ is_expected.to include("class=\"ci-status-link ci-status-icon-success d-inline-flex extra-class\"")
+ end
+ end
+
+ context "when container is provided" do
+ subject { helper.render_status_with_link("success", container: "my-container") }
+
+ it "has the provided container in data" do
+ is_expected.to include("data-container=\"my-container\"")
+ end
+ end
+
+ context "when icon_size is provided" do
+ subject { helper.render_status_with_link("success", icon_size: 24) }
+
+ it "has the svg class to change size" do
+ is_expected.to include("<svg class=\"s24\">")
+ end
+ end
+ end
end
diff --git a/spec/helpers/dashboard_helper_spec.rb b/spec/helpers/dashboard_helper_spec.rb
index 023238ee0ae..059ae128d93 100644
--- a/spec/helpers/dashboard_helper_spec.rb
+++ b/spec/helpers/dashboard_helper_spec.rb
@@ -12,7 +12,7 @@ describe DashboardHelper do
it 'has all the expected links by default' do
menu_items = [:projects, :groups, :activity, :milestones, :snippets]
- expect(helper.dashboard_nav_links).to contain_exactly(*menu_items)
+ expect(helper.dashboard_nav_links).to include(*menu_items)
end
it 'does not contain cross project elements when the user cannot read cross project' do
@@ -22,6 +22,43 @@ describe DashboardHelper do
end
end
+ describe '#feature_entry' do
+ context 'when implicitly enabled' do
+ it 'considers feature enabled by default' do
+ entry = feature_entry('Demo', href: 'demo.link')
+
+ expect(entry).to include('<p aria-label="Demo: status on">')
+ expect(entry).to include('<a href="demo.link">Demo</a>')
+ end
+ end
+
+ context 'when explicitly enabled' do
+ it 'returns a link' do
+ entry = feature_entry('Demo', href: 'demo.link', enabled: true)
+
+ expect(entry).to include('<p aria-label="Demo: status on">')
+ expect(entry).to include('<a href="demo.link">Demo</a>')
+ end
+
+ it 'returns text if href is not provided' do
+ entry = feature_entry('Demo', enabled: true)
+
+ expect(entry).to include('<p aria-label="Demo: status on">')
+ expect(entry).not_to match(/<a[^>]+>/)
+ end
+ end
+
+ context 'when disabled' do
+ it 'returns text without link' do
+ entry = feature_entry('Demo', href: 'demo.link', enabled: false)
+
+ expect(entry).to include('<p aria-label="Demo: status off">')
+ expect(entry).not_to match(/<a[^>]+>/)
+ expect(entry).to include('Demo')
+ end
+ end
+ end
+
describe '.has_start_trial?' do
subject { helper.has_start_trial? }
diff --git a/spec/helpers/emails_helper_spec.rb b/spec/helpers/emails_helper_spec.rb
index e6aacb5b92b..d25f0c6de4a 100644
--- a/spec/helpers/emails_helper_spec.rb
+++ b/spec/helpers/emails_helper_spec.rb
@@ -103,7 +103,7 @@ describe EmailsHelper do
appearance = create :appearance, header_logo: fixture_file_upload('spec/fixtures/dk.png')
expect(header_logo).to eq(
- %{<img style="height: 50px" src="/uploads/-/system/appearance/header_logo/#{appearance.id}/dk.png" alt="Dk" />}
+ %{<img style="height: 50px" src="/uploads/-/system/appearance/header_logo/#{appearance.id}/dk.png" />}
)
end
end
diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb
index 1763c46389a..98719697cea 100644
--- a/spec/helpers/groups_helper_spec.rb
+++ b/spec/helpers/groups_helper_spec.rb
@@ -86,7 +86,7 @@ describe GroupsHelper do
end
end
- describe 'group_title', :nested_groups do
+ describe 'group_title' do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
let(:deep_nested_group) { create(:group, parent: nested_group) }
@@ -99,7 +99,7 @@ describe GroupsHelper do
end
# rubocop:disable Layout/SpaceBeforeComma
- describe '#share_with_group_lock_help_text', :nested_groups do
+ describe '#share_with_group_lock_help_text' do
let!(:root_group) { create(:group) }
let!(:subgroup) { create(:group, parent: root_group) }
let!(:sub_subgroup) { create(:group, parent: subgroup) }
@@ -230,7 +230,7 @@ describe GroupsHelper do
end
end
- describe 'parent_group_options', :nested_groups do
+ describe 'parent_group_options' do
let(:current_user) { create(:user) }
let(:group) { create(:group, name: 'group') }
let(:group2) { create(:group, name: 'group2') }
@@ -262,4 +262,44 @@ describe GroupsHelper do
expect(parent_group_options(group2)).to eq([{ id: group.id, text: group.human_name }].to_json)
end
end
+
+ describe '#can_disable_group_emails?' do
+ let(:current_user) { create(:user) }
+ let(:group) { create(:group, name: 'group') }
+ let(:subgroup) { create(:group, name: 'subgroup', parent: group) }
+
+ before do
+ allow(helper).to receive(:current_user) { current_user }
+ end
+
+ it 'returns true for the group owner' do
+ allow(helper).to receive(:can?).with(current_user, :set_emails_disabled, group) { true }
+
+ expect(helper.can_disable_group_emails?(group)).to be_truthy
+ end
+
+ it 'returns false for anyone else' do
+ allow(helper).to receive(:can?).with(current_user, :set_emails_disabled, group) { false }
+
+ expect(helper.can_disable_group_emails?(group)).to be_falsey
+ end
+
+ context 'when subgroups' do
+ before do
+ allow(helper).to receive(:can?).with(current_user, :set_emails_disabled, subgroup) { true }
+ end
+
+ it 'returns false if parent group is disabling emails' do
+ allow(group).to receive(:emails_disabled?).and_return(true)
+
+ expect(helper.can_disable_group_emails?(subgroup)).to be_falsey
+ end
+
+ it 'returns true if parent group is not disabling emails' do
+ allow(group).to receive(:emails_disabled?).and_return(false)
+
+ expect(helper.can_disable_group_emails?(subgroup)).to be_truthy
+ end
+ end
+ end
end
diff --git a/spec/helpers/icons_helper_spec.rb b/spec/helpers/icons_helper_spec.rb
index 37e9ddadb8c..f92b94a9583 100644
--- a/spec/helpers/icons_helper_spec.rb
+++ b/spec/helpers/icons_helper_spec.rb
@@ -125,6 +125,14 @@ describe IconsHelper do
expect(file_type_icon_class('file', 0, 'filename.png')).to eq 'file-image-o'
end
+ it 'returns file-image-o class with .apng' do
+ expect(file_type_icon_class('file', 0, 'filename.apng')).to eq 'file-image-o'
+ end
+
+ it 'returns file-image-o class with .webp' do
+ expect(file_type_icon_class('file', 0, 'filename.webp')).to eq 'file-image-o'
+ end
+
it 'returns file-archive-o class with .tar' do
expect(file_type_icon_class('file', 0, 'filename.tar')).to eq 'file-archive-o'
end
@@ -145,6 +153,10 @@ describe IconsHelper do
expect(file_type_icon_class('file', 0, 'filename.MP3')).to eq 'file-audio-o'
end
+ it 'returns file-audio-o class with .m4a' do
+ expect(file_type_icon_class('file', 0, 'filename.m4a')).to eq 'file-audio-o'
+ end
+
it 'returns file-audio-o class with .wav' do
expect(file_type_icon_class('file', 0, 'filename.wav')).to eq 'file-audio-o'
end
@@ -161,6 +173,10 @@ describe IconsHelper do
expect(file_type_icon_class('file', 0, 'filename.mp4')).to eq 'file-video-o'
end
+ it 'returns file-word-o class with .odt' do
+ expect(file_type_icon_class('file', 0, 'filename.odt')).to eq 'file-word-o'
+ end
+
it 'returns file-word-o class with .doc' do
expect(file_type_icon_class('file', 0, 'filename.doc')).to eq 'file-word-o'
end
@@ -185,6 +201,10 @@ describe IconsHelper do
expect(file_type_icon_class('file', 0, 'filename.xlsx')).to eq 'file-excel-o'
end
+ it 'returns file-excel-o class with .odp' do
+ expect(file_type_icon_class('file', 0, 'filename.odp')).to eq 'file-powerpoint-o'
+ end
+
it 'returns file-excel-o class with .ppt' do
expect(file_type_icon_class('file', 0, 'filename.ppt')).to eq 'file-powerpoint-o'
end
diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb
index 1d1446eaa30..3c8179460ac 100644
--- a/spec/helpers/issuables_helper_spec.rb
+++ b/spec/helpers/issuables_helper_spec.rb
@@ -202,5 +202,46 @@ describe IssuablesHelper do
}
expect(helper.issuable_initial_data(issue)).to match(hash_including(expected_data))
end
+
+ describe '#zoomMeetingUrl in issue' do
+ let(:issue) { create(:issue, author: user, description: description) }
+
+ before do
+ assign(:project, issue.project)
+ end
+
+ context 'no zoom links in the issue description' do
+ let(:description) { 'issue text' }
+
+ it 'does not set zoomMeetingUrl' do
+ expect(helper.issuable_initial_data(issue))
+ .not_to include(:zoomMeetingUrl)
+ end
+ end
+
+ context 'no zoom links in the issue description if it has link but not a zoom link' do
+ let(:description) { 'issue text https://stackoverflow.com/questions/22' }
+
+ it 'does not set zoomMeetingUrl' do
+ expect(helper.issuable_initial_data(issue))
+ .not_to include(:zoomMeetingUrl)
+ end
+ end
+
+ context 'with two zoom links in description' do
+ let(:description) do
+ <<~TEXT
+ issue text and
+ zoom call on https://zoom.us/j/123456789 this url
+ and new zoom url https://zoom.us/s/lastone and some more text
+ TEXT
+ end
+
+ it 'sets zoomMeetingUrl value to the last url' do
+ expect(helper.issuable_initial_data(issue))
+ .to include(zoomMeetingUrl: 'https://zoom.us/s/lastone')
+ end
+ end
+ end
end
end
diff --git a/spec/helpers/labels_helper_spec.rb b/spec/helpers/labels_helper_spec.rb
index 314305d7a8e..4f1cab38f34 100644
--- a/spec/helpers/labels_helper_spec.rb
+++ b/spec/helpers/labels_helper_spec.rb
@@ -3,10 +3,8 @@ require 'spec_helper'
describe LabelsHelper do
describe '#show_label_issuables_link?' do
shared_examples 'a valid response to show_label_issuables_link?' do |issuables_type, when_enabled = true, when_disabled = false|
- let(:context_project) { project }
-
context "when asking for a #{issuables_type} link" do
- subject { show_label_issuables_link?(label.present(issuable_subject: nil), issuables_type, project: context_project) }
+ subject { show_label_issuables_link?(label.present(issuable_subject: nil), issuables_type) }
context "when #{issuables_type} are enabled for the project" do
let(:project) { create(:project, "#{issuables_type}_access_level": ProjectFeature::ENABLED) }
@@ -39,27 +37,11 @@ describe LabelsHelper do
let(:label) { create(:group_label, group: group, title: 'bug') }
context 'when asking for an issue link' do
- context 'in the context of a project' do
- it_behaves_like 'a valid response to show_label_issuables_link?', :issues, true, true
- end
-
- context 'in the context of a group' do
- let(:context_project) { nil }
-
- it_behaves_like 'a valid response to show_label_issuables_link?', :issues, true, true
- end
+ it_behaves_like 'a valid response to show_label_issuables_link?', :issues, true, true
end
context 'when asking for a merge requests link' do
- context 'in the context of a project' do
- it_behaves_like 'a valid response to show_label_issuables_link?', :merge_requests, true, true
- end
-
- context 'in the context of a group' do
- let(:context_project) { nil }
-
- it_behaves_like 'a valid response to show_label_issuables_link?', :merge_requests, true, true
- end
+ it_behaves_like 'a valid response to show_label_issuables_link?', :merge_requests, true, true
end
end
end
diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb
index 6c6410cee9b..f6e1720e113 100644
--- a/spec/helpers/markup_helper_spec.rb
+++ b/spec/helpers/markup_helper_spec.rb
@@ -268,7 +268,7 @@ describe MarkupHelper do
end
end
- describe 'markup' do
+ describe '#markup' do
let(:content) { 'Noël' }
it 'preserves encoding' do
@@ -302,6 +302,77 @@ describe MarkupHelper do
end
end
+ describe '#markup_unsafe' do
+ subject { helper.markup_unsafe(file_name, text, context) }
+
+ let(:file_name) { 'foo.bar' }
+ let(:text) { 'Noël' }
+ let(:project_base) { build(:project, :repository) }
+ let(:context) { { project: project_base } }
+
+ context 'when text is missing' do
+ let(:text) { nil }
+
+ it 'returns an empty string' do
+ is_expected.to eq('')
+ end
+ end
+
+ context 'when file is a markdown file' do
+ let(:file_name) { 'foo.md' }
+
+ it 'returns html (rendered by Banzai)' do
+ expected_html = '<p data-sourcepos="1:1-1:5" dir="auto">Noël</p>'
+
+ expect(Banzai).to receive(:render).with(text, context) { expected_html }
+
+ is_expected.to eq(expected_html)
+ end
+
+ context 'when renderer returns an error' do
+ before do
+ allow(Banzai).to receive(:render).and_raise("An error")
+ end
+
+ it 'returns html (rendered by ActionView:TextHelper)' do
+ is_expected.to eq('<p>Noël</p>')
+ end
+ end
+ end
+
+ context 'when file is asciidoc file' do
+ let(:file_name) { 'foo.adoc' }
+
+ it 'returns html (rendered by Gitlab::Asciidoc)' do
+ expected_html = "<div>\n<p>Noël</p>\n</div>"
+
+ expect(Gitlab::Asciidoc).to receive(:render).with(text, context) { expected_html }
+
+ is_expected.to eq(expected_html)
+ end
+ end
+
+ context 'when file is a regular text file' do
+ let(:file_name) { 'foo.txt' }
+
+ it 'returns html (rendered by ActionView::TagHelper)' do
+ is_expected.to eq('<pre class="plain-readme">Noël</pre>')
+ end
+ end
+
+ context 'when file has an unknown type' do
+ let(:file_name) { 'foo' }
+
+ it 'returns html (rendered by Gitlab::OtherMarkup)' do
+ expected_html = 'Noël'
+
+ expect(Gitlab::OtherMarkup).to receive(:render).with(file_name, text, context) { expected_html }
+
+ is_expected.to eq(expected_html)
+ end
+ end
+ end
+
describe '#first_line_in_markdown' do
shared_examples_for 'common markdown examples' do
let(:project_base) { build(:project, :repository) }
diff --git a/spec/helpers/namespaces_helper_spec.rb b/spec/helpers/namespaces_helper_spec.rb
index 601f864ef36..e38513f6d94 100644
--- a/spec/helpers/namespaces_helper_spec.rb
+++ b/spec/helpers/namespaces_helper_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe NamespacesHelper, :postgresql do
+describe NamespacesHelper do
let!(:admin) { create(:admin) }
let!(:admin_project_creation_level) { nil }
let!(:admin_group) do
@@ -109,7 +109,7 @@ describe NamespacesHelper, :postgresql do
expect(options).to include(user_group.name)
end
- context 'when nested groups are available', :nested_groups do
+ context 'when nested groups are available' do
it 'includes groups nested in groups the user can administer' do
allow(helper).to receive(:current_user).and_return(user)
child_group = create(:group, :private, parent: user_group)
diff --git a/spec/helpers/notifications_helper_spec.rb b/spec/helpers/notifications_helper_spec.rb
index 9ecaabc04ed..5717b15d656 100644
--- a/spec/helpers/notifications_helper_spec.rb
+++ b/spec/helpers/notifications_helper_spec.rb
@@ -3,6 +3,7 @@ require 'spec_helper'
describe NotificationsHelper do
describe 'notification_icon' do
it { expect(notification_icon(:disabled)).to match('class="fa fa-microphone-slash fa-fw"') }
+ it { expect(notification_icon(:owner_disabled)).to match('class="fa fa-microphone-slash fa-fw"') }
it { expect(notification_icon(:participating)).to match('class="fa fa-volume-up fa-fw"') }
it { expect(notification_icon(:mention)).to match('class="fa fa-at fa-fw"') }
it { expect(notification_icon(:global)).to match('class="fa fa-globe fa-fw"') }
@@ -19,4 +20,14 @@ describe NotificationsHelper do
it { expect(notification_event_name(:success_pipeline)).to match('Successful pipeline') }
it { expect(notification_event_name(:failed_pipeline)).to match('Failed pipeline') }
end
+
+ describe '#notification_icon_level' do
+ let(:user) { create(:user) }
+ let(:global_setting) { user.global_notification_setting }
+ let(:notification_setting) { create(:notification_setting, level: :watch) }
+
+ it { expect(notification_icon_level(notification_setting, true)).to eq 'owner_disabled' }
+ it { expect(notification_icon_level(notification_setting)).to eq 'watch' }
+ it { expect(notification_icon_level(global_setting)).to eq 'participating' }
+ end
end
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index 3716879c458..a70bfc2adc7 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -107,6 +107,30 @@ describe ProjectsHelper do
end
end
+ describe '#can_disable_emails?' do
+ let(:project) { create(:project) }
+ let(:user) { create(:project_member, :maintainer, user: create(:user), project: project).user }
+
+ it 'returns true for the project owner' do
+ allow(helper).to receive(:can?).with(project.owner, :set_emails_disabled, project) { true }
+
+ expect(helper.can_disable_emails?(project, project.owner)).to be_truthy
+ end
+
+ it 'returns false for anyone else' do
+ allow(helper).to receive(:can?).with(user, :set_emails_disabled, project) { false }
+
+ expect(helper.can_disable_emails?(project, user)).to be_falsey
+ end
+
+ it 'returns false if group emails disabled' do
+ project = create(:project, group: create(:group))
+ allow(project.group).to receive(:emails_disabled?).and_return(true)
+
+ expect(helper.can_disable_emails?(project, project.owner)).to be_falsey
+ end
+ end
+
describe "readme_cache_key" do
let(:project) { create(:project, :repository) }
@@ -477,6 +501,7 @@ describe ProjectsHelper do
it 'returns the command to push to create project over SSH' do
allow(Gitlab::CurrentSettings.current_application_settings).to receive(:enabled_git_access_protocol) { 'ssh' }
+ allow(Gitlab.config.gitlab_shell).to receive(:ssh_path_prefix).and_return('git@localhost:')
expect(helper.push_to_create_project_command(user)).to eq('git push --set-upstream git@localhost:john/$(git rev-parse --show-toplevel | xargs basename).git $(git rev-parse --abbrev-ref HEAD)')
end
diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb
index c69493b579f..2ab72679ee7 100644
--- a/spec/helpers/search_helper_spec.rb
+++ b/spec/helpers/search_helper_spec.rb
@@ -177,4 +177,48 @@ describe SearchHelper do
end
end
end
+
+ describe 'search_filter_link' do
+ it 'renders a search filter link for the current scope' do
+ @scope = 'projects'
+ @search_results = double
+
+ expect(@search_results).to receive(:formatted_count).with('projects').and_return('23')
+
+ link = search_filter_link('projects', 'Projects')
+
+ expect(link).to have_css('li.active')
+ expect(link).to have_link('Projects', href: search_path(scope: 'projects'))
+ expect(link).to have_css('span.badge.badge-pill:not(.js-search-count):not(.hidden):not([data-url])', text: '23')
+ end
+
+ it 'renders a search filter link for another scope' do
+ link = search_filter_link('projects', 'Projects')
+ count_path = search_count_path(scope: 'projects')
+
+ expect(link).to have_css('li:not([class="active"])')
+ expect(link).to have_link('Projects', href: search_path(scope: 'projects'))
+ expect(link).to have_css("span.badge.badge-pill.js-search-count.hidden[data-url='#{count_path}']", text: '')
+ end
+
+ it 'merges in the current search params and given params' do
+ expect(self).to receive(:params).and_return(
+ ActionController::Parameters.new(
+ search: 'hello',
+ scope: 'ignored',
+ other_param: 'ignored'
+ )
+ )
+
+ link = search_filter_link('projects', 'Projects', search: { project_id: 23 })
+
+ expect(link).to have_link('Projects', href: search_path(scope: 'projects', search: 'hello', project_id: 23))
+ end
+
+ it 'assigns given data attributes on the list container' do
+ link = search_filter_link('projects', 'Projects', data: { foo: 'bar' })
+
+ expect(link).to have_css('li[data-foo="bar"]')
+ end
+ end
end
diff --git a/spec/helpers/sessions_helper_spec.rb b/spec/helpers/sessions_helper_spec.rb
new file mode 100644
index 00000000000..647771ace92
--- /dev/null
+++ b/spec/helpers/sessions_helper_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe SessionsHelper do
+ describe '#unconfirmed_email?' do
+ it 'returns true when the flash alert contains a devise failure unconfirmed message' do
+ flash[:alert] = t(:unconfirmed, scope: [:devise, :failure])
+ expect(helper.unconfirmed_email?).to be_truthy
+ end
+
+ it 'returns false when the flash alert does not contain a devise failure unconfirmed message' do
+ flash[:alert] = 'something else'
+ expect(helper.unconfirmed_email?).to be_falsey
+ end
+ end
+end
diff --git a/spec/helpers/sorting_helper_spec.rb b/spec/helpers/sorting_helper_spec.rb
index f405268d198..5397a47b3dd 100644
--- a/spec/helpers/sorting_helper_spec.rb
+++ b/spec/helpers/sorting_helper_spec.rb
@@ -4,6 +4,11 @@ require 'spec_helper'
describe SortingHelper do
include ApplicationHelper
include IconsHelper
+ include ExploreHelper
+
+ def set_sorting_url(option)
+ allow(self).to receive(:request).and_return(double(path: 'http://test.com', query_parameters: { label_name: option }))
+ end
describe '#issuable_sort_option_title' do
it 'returns correct title for issuable_sort_option_overrides key' do
@@ -21,7 +26,7 @@ describe SortingHelper do
describe '#issuable_sort_direction_button' do
before do
- allow(self).to receive(:request).and_return(double(path: 'http://test.com', query_parameters: { label_name: 'test_label' }))
+ set_sorting_url 'test_label'
end
it 'keeps label filter param' do
@@ -44,4 +49,145 @@ describe SortingHelper do
expect(issuable_sort_direction_button('due_date')).to include('sort-lowest')
end
end
+
+ def stub_controller_path(value)
+ allow(helper.controller).to receive(:controller_path).and_return(value)
+ end
+
+ def project_common_options
+ {
+ sort_value_latest_activity => sort_title_latest_activity,
+ sort_value_recently_created => sort_title_created_date,
+ sort_value_name => sort_title_name,
+ sort_value_stars_desc => sort_title_stars
+ }
+ end
+
+ describe 'with `admin/projects` controller' do
+ before do
+ stub_controller_path 'admin/projects'
+ end
+
+ describe '#projects_sort_options_hash' do
+ it 'returns a hash of available sorting options' do
+ admin_options = project_common_options.merge({
+ sort_value_oldest_activity => sort_title_oldest_activity,
+ sort_value_oldest_created => sort_title_oldest_created,
+ sort_value_recently_created => sort_title_recently_created,
+ sort_value_stars_desc => sort_title_most_stars,
+ sort_value_largest_repo => sort_title_largest_repo
+ })
+
+ expect(projects_sort_options_hash).to eq(admin_options)
+ end
+ end
+ end
+
+ describe 'with `projects` controller' do
+ before do
+ stub_controller_path 'projects'
+ end
+
+ describe '#projects_sort_options_hash' do
+ it 'returns a hash of available sorting options' do
+ expect(projects_sort_options_hash).to include(project_common_options)
+ end
+ end
+
+ describe '#projects_reverse_sort_options_hash' do
+ context 'returns a reversed hash of available sorting options' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:sort_key, :reverse_sort_title) do
+ sort_value_latest_activity | sort_value_oldest_activity
+ sort_value_recently_created | sort_value_oldest_created
+ sort_value_name | sort_value_name_desc
+ sort_value_stars_desc | sort_value_stars_asc
+ sort_value_oldest_activity | sort_value_latest_activity
+ sort_value_oldest_created | sort_value_recently_created
+ sort_value_name_desc | sort_value_name
+ sort_value_stars_asc | sort_value_stars_desc
+ end
+
+ with_them do
+ it do
+ reverse_hash = projects_reverse_sort_options_hash
+
+ expect(reverse_hash).to include(sort_key)
+ expect(reverse_hash[sort_key]).to eq(reverse_sort_title)
+ end
+ end
+ end
+ end
+
+ describe '#project_sort_direction_button' do
+ context 'returns the correct icon for each sort option' do
+ using RSpec::Parameterized::TableSyntax
+
+ sort_lowest_icon = 'sort-lowest'
+ sort_highest_icon = 'sort-highest'
+
+ where(:selected_sort, :icon) do
+ sort_value_latest_activity | sort_highest_icon
+ sort_value_recently_created | sort_highest_icon
+ sort_value_name_desc | sort_highest_icon
+ sort_value_stars_desc | sort_highest_icon
+ sort_value_oldest_activity | sort_lowest_icon
+ sort_value_oldest_created | sort_lowest_icon
+ sort_value_name | sort_lowest_icon
+ sort_value_stars_asc | sort_lowest_icon
+ end
+
+ with_them do
+ it do
+ set_sorting_url selected_sort
+
+ expect(project_sort_direction_button(selected_sort)).to include(icon)
+ end
+ end
+ end
+
+ it 'returns the correct link to reverse the current sort option' do
+ sort_options_links = projects_reverse_sort_options_hash
+
+ sort_options_links.each do |selected_sort, reverse_sort|
+ set_sorting_url selected_sort
+
+ expect(project_sort_direction_button(selected_sort)).to include(reverse_sort)
+ end
+ end
+ end
+
+ describe '#projects_sort_option_titles' do
+ it 'returns a hash of titles for the sorting options' do
+ options = project_common_options.merge({
+ sort_value_oldest_activity => sort_title_latest_activity,
+ sort_value_oldest_created => sort_title_created_date,
+ sort_value_name_desc => sort_title_name,
+ sort_value_stars_asc => sort_title_stars
+ })
+
+ expect(projects_sort_option_titles).to eq(options)
+ end
+ end
+
+ describe 'with project_list_filter_bar off' do
+ before do
+ stub_feature_flags(project_list_filter_bar: false)
+ end
+
+ describe '#projects_sort_options_hash' do
+ it 'returns a hash of available sorting options' do
+ options = project_common_options.merge({
+ sort_value_oldest_activity => sort_title_oldest_activity,
+ sort_value_oldest_created => sort_title_oldest_created,
+ sort_value_recently_created => sort_title_recently_created,
+ sort_value_stars_desc => sort_title_most_stars
+ })
+
+ expect(projects_sort_options_hash).to eq(options)
+ end
+ end
+ end
+ end
end
diff --git a/spec/helpers/submodule_helper_spec.rb b/spec/helpers/submodule_helper_spec.rb
index ea48c69e0ae..ab4ef899119 100644
--- a/spec/helpers/submodule_helper_spec.rb
+++ b/spec/helpers/submodule_helper_spec.rb
@@ -3,15 +3,11 @@ require 'spec_helper'
describe SubmoduleHelper do
include RepoHelpers
- describe 'submodule links' do
- let(:submodule_item) { double(id: 'hash', path: 'rack') }
- let(:config) { Gitlab.config.gitlab }
- let(:repo) { double }
-
- before do
- self.instance_variable_set(:@repository, repo)
- end
+ let(:submodule_item) { double(id: 'hash', path: 'rack') }
+ let(:config) { Gitlab.config.gitlab }
+ let(:repo) { double }
+ shared_examples 'submodule_links' do
context 'submodule on self' do
before do
allow(Gitlab.config.gitlab).to receive(:protocol).and_return('http') # set this just to be sure
@@ -21,28 +17,28 @@ describe SubmoduleHelper do
allow(Gitlab.config.gitlab_shell).to receive(:ssh_port).and_return(22) # set this just to be sure
allow(Gitlab.config.gitlab_shell).to receive(:ssh_path_prefix).and_return(Settings.send(:build_gitlab_shell_ssh_path_prefix))
stub_url([config.user, '@', config.host, ':gitlab-org/gitlab-ce.git'].join(''))
- expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
+ expect(subject).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
end
it 'detects ssh on non-standard port' do
allow(Gitlab.config.gitlab_shell).to receive(:ssh_port).and_return(2222)
allow(Gitlab.config.gitlab_shell).to receive(:ssh_path_prefix).and_return(Settings.send(:build_gitlab_shell_ssh_path_prefix))
stub_url(['ssh://', config.user, '@', config.host, ':2222/gitlab-org/gitlab-ce.git'].join(''))
- expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
+ expect(subject).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
end
it 'detects http on standard port' do
allow(Gitlab.config.gitlab).to receive(:port).and_return(80)
allow(Gitlab.config.gitlab).to receive(:url).and_return(Settings.send(:build_gitlab_url))
stub_url(['http://', config.host, '/gitlab-org/gitlab-ce.git'].join(''))
- expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
+ expect(subject).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
end
it 'detects http on non-standard port' do
allow(Gitlab.config.gitlab).to receive(:port).and_return(3000)
allow(Gitlab.config.gitlab).to receive(:url).and_return(Settings.send(:build_gitlab_url))
stub_url(['http://', config.host, ':3000/gitlab-org/gitlab-ce.git'].join(''))
- expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
+ expect(subject).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
end
it 'works with relative_url_root' do
@@ -50,7 +46,7 @@ describe SubmoduleHelper do
allow(Gitlab.config.gitlab).to receive(:relative_url_root).and_return('/gitlab/root')
allow(Gitlab.config.gitlab).to receive(:url).and_return(Settings.send(:build_gitlab_url))
stub_url(['http://', config.host, '/gitlab/root/gitlab-org/gitlab-ce.git'].join(''))
- expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
+ expect(subject).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
end
it 'works with subgroups' do
@@ -58,34 +54,34 @@ describe SubmoduleHelper do
allow(Gitlab.config.gitlab).to receive(:relative_url_root).and_return('/gitlab/root')
allow(Gitlab.config.gitlab).to receive(:url).and_return(Settings.send(:build_gitlab_url))
stub_url(['http://', config.host, '/gitlab/root/gitlab-org/sub/gitlab-ce.git'].join(''))
- expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org/sub', 'gitlab-ce'), namespace_project_tree_path('gitlab-org/sub', 'gitlab-ce', 'hash')])
+ expect(subject).to eq([namespace_project_path('gitlab-org/sub', 'gitlab-ce'), namespace_project_tree_path('gitlab-org/sub', 'gitlab-ce', 'hash')])
end
end
context 'submodule on github.com' do
it 'detects ssh' do
stub_url('git@github.com:gitlab-org/gitlab-ce.git')
- expect(submodule_links(submodule_item)).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash'])
+ expect(subject).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash'])
end
it 'detects http' do
stub_url('http://github.com/gitlab-org/gitlab-ce.git')
- expect(submodule_links(submodule_item)).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash'])
+ expect(subject).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash'])
end
it 'detects https' do
stub_url('https://github.com/gitlab-org/gitlab-ce.git')
- expect(submodule_links(submodule_item)).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash'])
+ expect(subject).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash'])
end
it 'handles urls with no .git on the end' do
stub_url('http://github.com/gitlab-org/gitlab-ce')
- expect(submodule_links(submodule_item)).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash'])
+ expect(subject).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash'])
end
it 'returns original with non-standard url' do
stub_url('http://github.com/another/gitlab-org/gitlab-ce.git')
- expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil])
+ expect(subject).to eq([repo.submodule_url_for, nil])
end
end
@@ -97,39 +93,39 @@ describe SubmoduleHelper do
allow(repo).to receive(:project).and_return(project)
stub_url('./')
- expect(submodule_links(submodule_item)).to eq(["/master-project/#{project.path}", "/master-project/#{project.path}/tree/hash"])
+ expect(subject).to eq(["/master-project/#{project.path}", "/master-project/#{project.path}/tree/hash"])
end
end
context 'submodule on gitlab.com' do
it 'detects ssh' do
stub_url('git@gitlab.com:gitlab-org/gitlab-ce.git')
- expect(submodule_links(submodule_item)).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
+ expect(subject).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
end
it 'detects http' do
stub_url('http://gitlab.com/gitlab-org/gitlab-ce.git')
- expect(submodule_links(submodule_item)).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
+ expect(subject).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
end
it 'detects https' do
stub_url('https://gitlab.com/gitlab-org/gitlab-ce.git')
- expect(submodule_links(submodule_item)).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
+ expect(subject).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
end
it 'handles urls with no .git on the end' do
stub_url('http://gitlab.com/gitlab-org/gitlab-ce')
- expect(submodule_links(submodule_item)).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
+ expect(subject).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
end
it 'handles urls with trailing whitespace' do
stub_url('http://gitlab.com/gitlab-org/gitlab-ce.git ')
- expect(submodule_links(submodule_item)).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
+ expect(subject).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
end
it 'returns original with non-standard url' do
stub_url('http://gitlab.com/another/gitlab-org/gitlab-ce.git')
- expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil])
+ expect(subject).to eq([repo.submodule_url_for, nil])
end
end
@@ -137,27 +133,25 @@ describe SubmoduleHelper do
it 'sanitizes unsupported protocols' do
stub_url('javascript:alert("XSS");')
- expect(helper.submodule_links(submodule_item)).to eq([nil, nil])
+ expect(subject).to eq([nil, nil])
end
it 'sanitizes unsupported protocols disguised as a repository URL' do
stub_url('javascript:alert("XSS");foo/bar.git')
- expect(helper.submodule_links(submodule_item)).to eq([nil, nil])
+ expect(subject).to eq([nil, nil])
end
it 'sanitizes invalid URL with extended ASCII' do
stub_url('é')
- expect(helper.submodule_links(submodule_item)).to eq([nil, nil])
+ expect(subject).to eq([nil, nil])
end
it 'returns original' do
stub_url('http://mygitserver.com/gitlab-org/gitlab-ce')
- expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil])
- stub_url('http://mygitserver.com/gitlab-org/gitlab-ce.git')
- expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil])
+ expect(subject).to eq([repo.submodule_url_for, nil])
end
end
@@ -168,8 +162,7 @@ describe SubmoduleHelper do
def expect_relative_link_to_resolve_to(relative_path, expected_path)
allow(repo).to receive(:submodule_url_for).and_return(relative_path)
-
- result = submodule_links(submodule_item)
+ result = subject
expect(result).to eq([expected_path, "#{expected_path}/tree/#{submodule_item.id}"])
end
@@ -190,7 +183,7 @@ describe SubmoduleHelper do
it 'returns nil' do
allow(repo).to receive(:submodule_url_for).and_return('../../test.git')
- result = submodule_links(submodule_item)
+ result = subject
expect(result).to eq([nil, nil])
end
@@ -200,7 +193,7 @@ describe SubmoduleHelper do
it 'returns nil because it is not possible to have repo nested under another repo' do
allow(repo).to receive(:submodule_url_for).and_return('./test.git')
- result = submodule_links(submodule_item)
+ result = subject
expect(result).to eq([nil, nil])
end
@@ -236,6 +229,35 @@ describe SubmoduleHelper do
end
end
end
+
+ context 'unknown submodule' do
+ before do
+ # When there is no `.gitmodules` file, or if `.gitmodules` does not
+ # know the submodule at the specified path,
+ # `Repository#submodule_url_for` returns `nil`
+ stub_url(nil)
+ end
+
+ it 'returns no links' do
+ expect(subject).to eq([nil, nil])
+ end
+ end
+ end
+
+ context 'as view helpers in view context' do
+ subject { helper.submodule_links(submodule_item) }
+
+ before do
+ self.instance_variable_set(:@repository, repo)
+ end
+
+ it_behaves_like 'submodule_links'
+ end
+
+ context 'as stand-alone module' do
+ subject { described_class.submodule_links(submodule_item, nil, repo) }
+
+ it_behaves_like 'submodule_links'
end
def stub_url(url)
diff --git a/spec/helpers/tracking_helper_spec.rb b/spec/helpers/tracking_helper_spec.rb
index 71505e8ea69..b0c98be4130 100644
--- a/spec/helpers/tracking_helper_spec.rb
+++ b/spec/helpers/tracking_helper_spec.rb
@@ -4,8 +4,32 @@ require 'spec_helper'
describe TrackingHelper do
describe '#tracking_attrs' do
- it 'returns an empty hash' do
- expect(helper.tracking_attrs('a', 'b', 'c')).to eq({})
+ using RSpec::Parameterized::TableSyntax
+
+ let(:input) { %w(a b c) }
+ let(:results) do
+ {
+ no_data: {},
+ with_data: { data: { track_label: 'a', track_event: 'b', track_property: 'c' } }
+ }
+ end
+
+ where(:snowplow_enabled, :environment, :result) do
+ true | 'production' | :with_data
+ false | 'production' | :no_data
+ true | 'development' | :no_data
+ false | 'development' | :no_data
+ true | 'test' | :no_data
+ false | 'test' | :no_data
+ end
+
+ with_them do
+ it 'returns a hash' do
+ stub_application_setting(snowplow_enabled: snowplow_enabled)
+ allow(Rails).to receive(:env).and_return(environment.inquiry)
+
+ expect(helper.tracking_attrs(*input)).to eq(results[result])
+ end
end
end
end
diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb
index f3649495493..a6623bc7941 100644
--- a/spec/helpers/users_helper_spec.rb
+++ b/spec/helpers/users_helper_spec.rb
@@ -27,7 +27,7 @@ describe UsersHelper do
context 'with public profile' do
it 'includes all the expected tabs' do
- expect(tabs).to include(:activity, :groups, :contributed, :projects, :snippets)
+ expect(tabs).to include(:activity, :groups, :contributed, :projects, :starred, :snippets)
end
end
diff --git a/spec/helpers/visibility_level_helper_spec.rb b/spec/helpers/visibility_level_helper_spec.rb
index 25a2fcf5a81..2d276696208 100644
--- a/spec/helpers/visibility_level_helper_spec.rb
+++ b/spec/helpers/visibility_level_helper_spec.rb
@@ -137,32 +137,6 @@ describe VisibilityLevelHelper do
end
end
- describe "disallowed_visibility_level_description" do
- let(:group) { create(:group, :internal) }
- let!(:subgroup) { create(:group, :internal, parent: group) }
- let!(:project) { create(:project, :internal, group: group) }
-
- describe "project" do
- it "provides correct description for disabled levels" do
- expect(disallowed_visibility_level?(project, Gitlab::VisibilityLevel::PUBLIC)).to be_truthy
- expect(strip_tags disallowed_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC, project))
- .to include "the visibility of #{project.group.name} is internal"
- end
- end
-
- describe "group" do
- it "provides correct description for disabled levels" do
- expect(disallowed_visibility_level?(group, Gitlab::VisibilityLevel::PRIVATE)).to be_truthy
- expect(disallowed_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, group))
- .to include "it contains projects with higher visibility", "it contains sub-groups with higher visibility"
-
- expect(disallowed_visibility_level?(subgroup, Gitlab::VisibilityLevel::PUBLIC)).to be_truthy
- expect(strip_tags disallowed_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC, subgroup))
- .to include "the visibility of #{group.name} is internal"
- end
- end
- end
-
describe "selected_visibility_level" do
let(:group) { create(:group, :public) }
let!(:project) { create(:project, :internal, group: group) }
@@ -207,4 +181,50 @@ describe VisibilityLevelHelper do
end
end
end
+
+ describe 'multiple_visibility_levels_restricted?' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:user) { create(:user) }
+
+ subject { helper.multiple_visibility_levels_restricted? }
+
+ where(:restricted_visibility_levels, :expected) do
+ [Gitlab::VisibilityLevel::PUBLIC] | false
+ [Gitlab::VisibilityLevel::PUBLIC, Gitlab::VisibilityLevel::INTERNAL] | true
+ [Gitlab::VisibilityLevel::PUBLIC, Gitlab::VisibilityLevel::INTERNAL, Gitlab::VisibilityLevel::PRIVATE] | true
+ end
+
+ with_them do
+ before do
+ allow(helper).to receive(:current_user) { user }
+ allow(Gitlab::CurrentSettings.current_application_settings).to receive(:restricted_visibility_levels) { restricted_visibility_levels }
+ end
+
+ it { is_expected.to eq(expected) }
+ end
+ end
+
+ describe 'all_visibility_levels_restricted?' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:user) { create(:user) }
+
+ subject { helper.all_visibility_levels_restricted? }
+
+ where(:restricted_visibility_levels, :expected) do
+ [Gitlab::VisibilityLevel::PUBLIC] | false
+ [Gitlab::VisibilityLevel::PUBLIC, Gitlab::VisibilityLevel::INTERNAL] | false
+ Gitlab::VisibilityLevel.values | true
+ end
+
+ with_them do
+ before do
+ allow(helper).to receive(:current_user) { user }
+ allow(Gitlab::CurrentSettings.current_application_settings).to receive(:restricted_visibility_levels) { restricted_visibility_levels }
+ end
+
+ it { is_expected.to eq(expected) }
+ end
+ end
end
diff --git a/spec/helpers/wiki_helper_spec.rb b/spec/helpers/wiki_helper_spec.rb
index 8eab40aeaf3..ee977e37ec1 100644
--- a/spec/helpers/wiki_helper_spec.rb
+++ b/spec/helpers/wiki_helper_spec.rb
@@ -22,7 +22,7 @@ describe WikiHelper do
describe '#wiki_sort_controls' do
let(:project) { create(:project) }
let(:wiki_link) { helper.wiki_sort_controls(project, sort, direction) }
- let(:classes) { "btn btn-default has-tooltip reverse-sort-btn qa-reverse-sort" }
+ let(:classes) { "btn btn-default has-tooltip reverse-sort-btn qa-reverse-sort rspec-reverse-sort" }
def expected_link(sort, direction, icon_class)
path = "/#{project.full_path}/wikis/pages?direction=#{direction}&sort=#{sort}"