summaryrefslogtreecommitdiff
path: root/spec/lib
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzesiek.bizon@gmail.com>2018-02-23 15:31:16 +0100
committerGrzegorz Bizon <grzesiek.bizon@gmail.com>2018-02-23 15:31:16 +0100
commitcab8cd7e2ee6ae1b21620443958dd3c312e5c655 (patch)
treec836a2b8377382b7cf94c7460ad28a8c74ebdb96 /spec/lib
parent011ddb51b40897bc13a75d78c9e992f559cbde48 (diff)
parent981b5905a02ac89ca9f33ad7c91d8c1a576ed9af (diff)
downloadgitlab-ce-cab8cd7e2ee6ae1b21620443958dd3c312e5c655.tar.gz
Merge commit '981b5905a02ac89ca9f33ad7c91d8c1a576ed9af' into backstage/gb/build-stages-catch-up-migrationbackstage/gb/build-stages-catch-up-migration
* commit '981b5905a02ac89ca9f33ad7c91d8c1a576ed9af': (40 commits)
Diffstat (limited to 'spec/lib')
-rw-r--r--spec/lib/banzai/commit_renderer_spec.rb2
-rw-r--r--spec/lib/banzai/filter/issuable_state_filter_spec.rb8
-rw-r--r--spec/lib/banzai/filter/redactor_filter_spec.rb2
-rw-r--r--spec/lib/banzai/redactor_spec.rb51
-rw-r--r--spec/lib/banzai/reference_parser/issue_parser_spec.rb47
-rw-r--r--spec/lib/gitlab/contributions_calendar_spec.rb13
-rw-r--r--spec/lib/gitlab/cross_project_access/check_collection_spec.rb55
-rw-r--r--spec/lib/gitlab/cross_project_access/check_info_spec.rb111
-rw-r--r--spec/lib/gitlab/cross_project_access/class_methods_spec.rb46
-rw-r--r--spec/lib/gitlab/cross_project_access_spec.rb84
-rw-r--r--spec/lib/gitlab/diff/highlight_spec.rb22
-rw-r--r--spec/lib/google_api/cloud_platform/client_spec.rb3
12 files changed, 437 insertions, 7 deletions
diff --git a/spec/lib/banzai/commit_renderer_spec.rb b/spec/lib/banzai/commit_renderer_spec.rb
index 84adaebdcbe..e7ebb2a332f 100644
--- a/spec/lib/banzai/commit_renderer_spec.rb
+++ b/spec/lib/banzai/commit_renderer_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Banzai::CommitRenderer do
describe '.render' do
it 'renders a commit description and title' do
- user = double(:user)
+ user = build(:user)
project = create(:project, :repository)
expect(Banzai::ObjectRenderer).to receive(:new).with(project, user).and_call_original
diff --git a/spec/lib/banzai/filter/issuable_state_filter_spec.rb b/spec/lib/banzai/filter/issuable_state_filter_spec.rb
index cacb33d3372..17347768a49 100644
--- a/spec/lib/banzai/filter/issuable_state_filter_spec.rb
+++ b/spec/lib/banzai/filter/issuable_state_filter_spec.rb
@@ -77,6 +77,14 @@ describe Banzai::Filter::IssuableStateFilter do
expect(doc.css('a').last.text).to eq("#{closed_issue.to_reference(other_project)} (closed)")
end
+ it 'skips cross project references if the user cannot read cross project' do
+ expect(Ability).to receive(:allowed?).with(user, :read_cross_project) { false }
+ link = create_link(closed_issue.to_reference(other_project), issue: closed_issue.id, reference_type: 'issue')
+ doc = filter(link, context.merge(project: other_project))
+
+ expect(doc.css('a').last.text).to eq("#{closed_issue.to_reference(other_project)}")
+ end
+
it 'does not append state when filter is not enabled' do
link = create_link('text', issue: closed_issue.id, reference_type: 'issue')
context = { current_user: user }
diff --git a/spec/lib/banzai/filter/redactor_filter_spec.rb b/spec/lib/banzai/filter/redactor_filter_spec.rb
index 5a7858e77f3..9a2e521fdcf 100644
--- a/spec/lib/banzai/filter/redactor_filter_spec.rb
+++ b/spec/lib/banzai/filter/redactor_filter_spec.rb
@@ -6,7 +6,7 @@ describe Banzai::Filter::RedactorFilter do
it 'ignores non-GFM links' do
html = %(See <a href="https://google.com/">Google</a>)
- doc = filter(html, current_user: double)
+ doc = filter(html, current_user: build(:user))
expect(doc.css('a').length).to eq 1
end
diff --git a/spec/lib/banzai/redactor_spec.rb b/spec/lib/banzai/redactor_spec.rb
index 2424c3fdc66..1fa89137972 100644
--- a/spec/lib/banzai/redactor_spec.rb
+++ b/spec/lib/banzai/redactor_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Banzai::Redactor do
- let(:user) { build(:user) }
+ let(:user) { create(:user) }
let(:project) { build(:project) }
let(:redactor) { described_class.new(project, user) }
@@ -88,6 +88,55 @@ describe Banzai::Redactor do
end
end
+ context 'when the user cannot read cross project' do
+ include ActionView::Helpers::UrlHelper
+ let(:project) { create(:project) }
+ let(:other_project) { create(:project, :public) }
+
+ def create_link(issuable)
+ type = issuable.class.name.underscore.downcase
+ link_to(issuable.to_reference, '',
+ class: 'gfm has-tooltip',
+ title: issuable.title,
+ data: {
+ reference_type: type,
+ "#{type}": issuable.id
+ })
+ end
+
+ before do
+ project.add_developer(user)
+
+ allow(Ability).to receive(:allowed?).and_call_original
+ allow(Ability).to receive(:allowed?).with(user, :read_cross_project, :global) { false }
+ allow(Ability).to receive(:allowed?).with(user, :read_cross_project) { false }
+ end
+
+ it 'skips links to issues within the same project' do
+ issue = create(:issue, project: project)
+ link = create_link(issue)
+ doc = Nokogiri::HTML.fragment(link)
+
+ redactor.redact([doc])
+ result = doc.css('a').last
+
+ expect(result['class']).to include('has-tooltip')
+ expect(result['title']).to eq(issue.title)
+ end
+
+ it 'removes info from a cross project reference' do
+ issue = create(:issue, project: other_project)
+ link = create_link(issue)
+ doc = Nokogiri::HTML.fragment(link)
+
+ redactor.redact([doc])
+ result = doc.css('a').last
+
+ expect(result['class']).not_to include('has-tooltip')
+ expect(result['title']).to be_empty
+ end
+ end
+
describe '#redact_nodes' do
it 'redacts an Array of nodes' do
doc = Nokogiri::HTML.fragment('<a href="foo">foo</a>')
diff --git a/spec/lib/banzai/reference_parser/issue_parser_spec.rb b/spec/lib/banzai/reference_parser/issue_parser_spec.rb
index 4cef3bdb24b..0a63567ee40 100644
--- a/spec/lib/banzai/reference_parser/issue_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/issue_parser_spec.rb
@@ -19,19 +19,58 @@ describe Banzai::ReferenceParser::IssueParser do
it 'returns the nodes when the user can read the issue' do
expect(Ability).to receive(:issues_readable_by_user)
- .with([issue], user)
- .and_return([issue])
+ .with([issue], user)
+ .and_return([issue])
expect(subject.nodes_visible_to_user(user, [link])).to eq([link])
end
it 'returns an empty Array when the user can not read the issue' do
expect(Ability).to receive(:issues_readable_by_user)
- .with([issue], user)
- .and_return([])
+ .with([issue], user)
+ .and_return([])
expect(subject.nodes_visible_to_user(user, [link])).to eq([])
end
+
+ context 'when the user cannot read cross project' do
+ let(:issue) { create(:issue) }
+
+ before do
+ allow(Ability).to receive(:allowed?).with(user, :read_cross_project) { false }
+ allow(Ability).to receive(:allowed?).with(user, :read_cross_project, :global) { false }
+ end
+
+ it 'returns the nodes when the user can read the issue' do
+ expect(Ability).to receive(:allowed?)
+ .with(user, :read_issue_iid, issue)
+ .and_return(true)
+
+ expect(subject.nodes_visible_to_user(user, [link])).to eq([link])
+ end
+
+ it 'returns an empty Array when the user can not read the issue' do
+ expect(Ability).to receive(:allowed?)
+ .with(user, :read_issue_iid, issue)
+ .and_return(false)
+
+ expect(subject.nodes_visible_to_user(user, [link])).to eq([])
+ end
+
+ context 'when the issue is not cross project' do
+ let(:issue) { create(:issue, project: project) }
+
+ it 'does not check `can_read_reference` if the issue is not cross project' do
+ expect(Ability).to receive(:issues_readable_by_user)
+ .with([issue], user)
+ .and_return([])
+
+ expect(subject).not_to receive(:can_read_reference?).with(user, issue)
+
+ expect(subject.nodes_visible_to_user(user, [link])).to eq([])
+ end
+ end
+ end
end
context 'when the link does not have a data-issue attribute' do
diff --git a/spec/lib/gitlab/contributions_calendar_spec.rb b/spec/lib/gitlab/contributions_calendar_spec.rb
index f1655854486..49a179ba875 100644
--- a/spec/lib/gitlab/contributions_calendar_spec.rb
+++ b/spec/lib/gitlab/contributions_calendar_spec.rb
@@ -118,6 +118,19 @@ describe Gitlab::ContributionsCalendar do
expect(calendar.events_by_date(today)).to contain_exactly(e1)
expect(calendar(contributor).events_by_date(today)).to contain_exactly(e1, e2, e3)
end
+
+ context 'when the user cannot read read cross project' do
+ before do
+ allow(Ability).to receive(:allowed?).and_call_original
+ expect(Ability).to receive(:allowed?).with(user, :read_cross_project) { false }
+ end
+
+ it 'does not return any events' do
+ create_event(public_project, today)
+
+ expect(calendar(user).events_by_date(today)).to be_empty
+ end
+ end
end
describe '#starting_year' do
diff --git a/spec/lib/gitlab/cross_project_access/check_collection_spec.rb b/spec/lib/gitlab/cross_project_access/check_collection_spec.rb
new file mode 100644
index 00000000000..a9e7575240e
--- /dev/null
+++ b/spec/lib/gitlab/cross_project_access/check_collection_spec.rb
@@ -0,0 +1,55 @@
+require 'spec_helper'
+
+describe Gitlab::CrossProjectAccess::CheckCollection do
+ subject(:collection) { described_class.new }
+
+ describe '#add_collection' do
+ it 'merges the checks of 2 collections' do
+ initial_check = double('check')
+ collection.add_check(initial_check)
+
+ other_collection = described_class.new
+ other_check = double('other_check')
+ other_collection.add_check(other_check)
+
+ shared_check = double('shared check')
+ other_collection.add_check(shared_check)
+ collection.add_check(shared_check)
+
+ collection.add_collection(other_collection)
+
+ expect(collection.checks).to contain_exactly(initial_check, shared_check, other_check)
+ end
+ end
+
+ describe '#should_run?' do
+ def fake_check(run, skip)
+ check = double("Check: run=#{run} - skip={skip}")
+ allow(check).to receive(:should_run?).and_return(run)
+ allow(check).to receive(:should_skip?).and_return(skip)
+ allow(check).to receive(:skip).and_return(skip)
+
+ check
+ end
+
+ it 'returns true if one of the check says it should run' do
+ check = fake_check(true, false)
+ other_check = fake_check(false, false)
+
+ collection.add_check(check)
+ collection.add_check(other_check)
+
+ expect(collection.should_run?(double)).to be_truthy
+ end
+
+ it 'returns false if one of the check says it should be skipped' do
+ check = fake_check(true, false)
+ other_check = fake_check(false, true)
+
+ collection.add_check(check)
+ collection.add_check(other_check)
+
+ expect(collection.should_run?(double)).to be_falsey
+ end
+ end
+end
diff --git a/spec/lib/gitlab/cross_project_access/check_info_spec.rb b/spec/lib/gitlab/cross_project_access/check_info_spec.rb
new file mode 100644
index 00000000000..bc9dbf2bece
--- /dev/null
+++ b/spec/lib/gitlab/cross_project_access/check_info_spec.rb
@@ -0,0 +1,111 @@
+require 'spec_helper'
+
+describe Gitlab::CrossProjectAccess::CheckInfo do
+ let(:dummy_controller) { double }
+
+ before do
+ allow(dummy_controller).to receive(:action_name).and_return('index')
+ end
+
+ describe '#should_run?' do
+ it 'runs when an action is defined' do
+ info = described_class.new({ index: true }, nil, nil, false)
+
+ expect(info.should_run?(dummy_controller)).to be_truthy
+ end
+
+ it 'runs when the action is missing' do
+ info = described_class.new({}, nil, nil, false)
+
+ expect(info.should_run?(dummy_controller)).to be_truthy
+ end
+
+ it 'does not run when the action is excluded' do
+ info = described_class.new({ index: false }, nil, nil, false)
+
+ expect(info.should_run?(dummy_controller)).to be_falsy
+ end
+
+ it 'runs when the `if` conditional is true' do
+ info = described_class.new({}, -> { true }, nil, false)
+
+ expect(info.should_run?(dummy_controller)).to be_truthy
+ end
+
+ it 'does not run when the if condition is false' do
+ info = described_class.new({}, -> { false }, nil, false)
+
+ expect(info.should_run?(dummy_controller)).to be_falsy
+ end
+
+ it 'does not run when the `unless` check is true' do
+ info = described_class.new({}, nil, -> { true }, false)
+
+ expect(info.should_run?(dummy_controller)).to be_falsy
+ end
+
+ it 'runs when the `unless` check is false' do
+ info = described_class.new({}, nil, -> { false }, false)
+
+ expect(info.should_run?(dummy_controller)).to be_truthy
+ end
+
+ it 'returns the the oposite of #should_skip? when the check is a skip' do
+ info = described_class.new({}, nil, nil, true)
+
+ expect(info).to receive(:should_skip?).with(dummy_controller).and_return(false)
+ expect(info.should_run?(dummy_controller)).to be_truthy
+ end
+ end
+
+ describe '#should_skip?' do
+ it 'skips when an action is defined' do
+ info = described_class.new({ index: true }, nil, nil, true)
+
+ expect(info.should_skip?(dummy_controller)).to be_truthy
+ end
+
+ it 'does not skip when the action is not defined' do
+ info = described_class.new({}, nil, nil, true)
+
+ expect(info.should_skip?(dummy_controller)).to be_falsy
+ end
+
+ it 'does not skip when the action is excluded' do
+ info = described_class.new({ index: false }, nil, nil, true)
+
+ expect(info.should_skip?(dummy_controller)).to be_falsy
+ end
+
+ it 'skips when the `if` conditional is true' do
+ info = described_class.new({ index: true }, -> { true }, nil, true)
+
+ expect(info.should_skip?(dummy_controller)).to be_truthy
+ end
+
+ it 'does not skip the `if` conditional is false' do
+ info = described_class.new({ index: true }, -> { false }, nil, true)
+
+ expect(info.should_skip?(dummy_controller)).to be_falsy
+ end
+
+ it 'does not skip when the `unless` check is true' do
+ info = described_class.new({ index: true }, nil, -> { true }, true)
+
+ expect(info.should_skip?(dummy_controller)).to be_falsy
+ end
+
+ it 'skips when `unless` check is false' do
+ info = described_class.new({ index: true }, nil, -> { false }, true)
+
+ expect(info.should_skip?(dummy_controller)).to be_truthy
+ end
+
+ it 'returns the the oposite of #should_run? when the check is not a skip' do
+ info = described_class.new({}, nil, nil, false)
+
+ expect(info).to receive(:should_run?).with(dummy_controller).and_return(false)
+ expect(info.should_skip?(dummy_controller)).to be_truthy
+ end
+ end
+end
diff --git a/spec/lib/gitlab/cross_project_access/class_methods_spec.rb b/spec/lib/gitlab/cross_project_access/class_methods_spec.rb
new file mode 100644
index 00000000000..5349685e633
--- /dev/null
+++ b/spec/lib/gitlab/cross_project_access/class_methods_spec.rb
@@ -0,0 +1,46 @@
+require 'spec_helper'
+
+describe Gitlab::CrossProjectAccess::ClassMethods do
+ let(:dummy_class) do
+ Class.new do
+ extend Gitlab::CrossProjectAccess::ClassMethods
+ end
+ end
+ let(:dummy_proc) { lambda { false } }
+
+ describe '#requires_cross_project_access' do
+ it 'creates a correct check when a hash is passed' do
+ expect(Gitlab::CrossProjectAccess)
+ .to receive(:add_check).with(dummy_class,
+ actions: { hello: true, world: false },
+ positive_condition: dummy_proc,
+ negative_condition: dummy_proc)
+
+ dummy_class.requires_cross_project_access(
+ hello: true, world: false, if: dummy_proc, unless: dummy_proc
+ )
+ end
+
+ it 'creates a correct check when an array is passed' do
+ expect(Gitlab::CrossProjectAccess)
+ .to receive(:add_check).with(dummy_class,
+ actions: { hello: true, world: true },
+ positive_condition: nil,
+ negative_condition: nil)
+
+ dummy_class.requires_cross_project_access(:hello, :world)
+ end
+
+ it 'creates a correct check when an array and a hash is passed' do
+ expect(Gitlab::CrossProjectAccess)
+ .to receive(:add_check).with(dummy_class,
+ actions: { hello: true, world: true },
+ positive_condition: dummy_proc,
+ negative_condition: dummy_proc)
+
+ dummy_class.requires_cross_project_access(
+ :hello, :world, if: dummy_proc, unless: dummy_proc
+ )
+ end
+ end
+end
diff --git a/spec/lib/gitlab/cross_project_access_spec.rb b/spec/lib/gitlab/cross_project_access_spec.rb
new file mode 100644
index 00000000000..614b0473c7e
--- /dev/null
+++ b/spec/lib/gitlab/cross_project_access_spec.rb
@@ -0,0 +1,84 @@
+require 'spec_helper'
+
+describe Gitlab::CrossProjectAccess do
+ let(:super_class) { Class.new }
+ let(:descendant_class) { Class.new(super_class) }
+ let(:current_instance) { described_class.new }
+
+ before do
+ allow(described_class).to receive(:instance).and_return(current_instance)
+ end
+
+ describe '#add_check' do
+ it 'keeps track of the properties to check' do
+ expect do
+ described_class.add_check(super_class,
+ actions: { index: true },
+ positive_condition: -> { true },
+ negative_condition: -> { false })
+ end.to change { described_class.checks.size }.by(1)
+ end
+
+ it 'builds the check correctly' do
+ check_collection = described_class.add_check(super_class,
+ actions: { index: true },
+ positive_condition: -> { 'positive' },
+ negative_condition: -> { 'negative' })
+
+ check = check_collection.checks.first
+
+ expect(check.actions).to eq(index: true)
+ expect(check.positive_condition.call).to eq('positive')
+ expect(check.negative_condition.call).to eq('negative')
+ end
+
+ it 'merges the checks of a parent class into existing checks of a subclass' do
+ subclass_collection = described_class.add_check(descendant_class)
+
+ expect(subclass_collection).to receive(:add_collection).and_call_original
+
+ described_class.add_check(super_class)
+ end
+
+ it 'merges the existing checks of a superclass into the checks of a subclass' do
+ super_collection = described_class.add_check(super_class)
+ descendant_collection = described_class.add_check(descendant_class)
+
+ expect(descendant_collection.checks).to include(*super_collection.checks)
+ end
+ end
+
+ describe '#find_check' do
+ it 'returns a check when it was defined for a superclass' do
+ expected_check = described_class.add_check(super_class,
+ actions: { index: true },
+ positive_condition: -> { 'positive' },
+ negative_condition: -> { 'negative' })
+
+ expect(described_class.find_check(descendant_class.new))
+ .to eq(expected_check)
+ end
+
+ it 'caches the result for a subclass' do
+ described_class.add_check(super_class,
+ actions: { index: true },
+ positive_condition: -> { 'positive' },
+ negative_condition: -> { 'negative' })
+
+ expect(described_class.instance).to receive(:closest_parent).once.and_call_original
+
+ 2.times { described_class.find_check(descendant_class.new) }
+ end
+
+ it 'returns the checks for the closest class if there are more checks available' do
+ described_class.add_check(super_class,
+ actions: { index: true })
+ expected_check = described_class.add_check(descendant_class,
+ actions: { index: true, show: false })
+
+ check = described_class.find_check(descendant_class.new)
+
+ expect(check).to eq(expected_check)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/diff/highlight_spec.rb b/spec/lib/gitlab/diff/highlight_spec.rb
index cd602ccab8e..73d60c021c8 100644
--- a/spec/lib/gitlab/diff/highlight_spec.rb
+++ b/spec/lib/gitlab/diff/highlight_spec.rb
@@ -72,6 +72,28 @@ describe Gitlab::Diff::Highlight do
expect(subject[5].text).to eq(code)
expect(subject[5].text).to be_html_safe
end
+
+ context 'when the inline diff marker has an invalid range' do
+ before do
+ allow_any_instance_of(Gitlab::Diff::InlineDiffMarker).to receive(:mark).and_raise(RangeError)
+ end
+
+ it 'keeps the original rich line' do
+ code = %q{+ raise RuntimeError, "System commands must be given as an array of strings"}
+
+ expect(subject[5].text).to eq(code)
+ expect(subject[5].text).not_to be_html_safe
+ end
+
+ it 'reports to Sentry if configured' do
+ allow(Gitlab::Sentry).to receive(:enabled?).and_return(true)
+
+ expect(Gitlab::Sentry).to receive(:context)
+ expect(Raven).to receive(:capture_exception)
+
+ subject
+ end
+ end
end
end
end
diff --git a/spec/lib/google_api/cloud_platform/client_spec.rb b/spec/lib/google_api/cloud_platform/client_spec.rb
index f65e41dfea3..db9d9158b29 100644
--- a/spec/lib/google_api/cloud_platform/client_spec.rb
+++ b/spec/lib/google_api/cloud_platform/client_spec.rb
@@ -115,6 +115,9 @@ describe GoogleApi::CloudPlatform::Client do
"initial_node_count": cluster_size,
"node_config": {
"machine_type": machine_type
+ },
+ "legacy_abac": {
+ "enabled": true
}
}
} )