Commit a971e201 authored by Robert Speicher's avatar Robert Speicher

Merge branch '6618-extract-ee-specific-files-lines-for-create-spec-finders' into 'master'

[EE] Extract EE specific files/lines from spec/finders

Closes #10142, #10141, and #6618

See merge request gitlab-org/gitlab-ee!10298
parents 0e14c581 76cf824f
require 'spec_helper'
describe GroupProjectsFinder do
include_context 'GroupProjectsFinder context'
subject { finder.execute }
describe 'with an auditor current user' do
let(:current_user) { create(:user, :auditor) }
context 'only shared' do
let(:options) { { only_shared: true } }
it { is_expected.to eq([shared_project_3, shared_project_2, shared_project_1]) }
end
context 'only owned' do
let(:options) { { only_owned: true } }
it { is_expected.to eq([private_project, public_project]) }
end
context 'all' do
subject { described_class.new(group: group, current_user: current_user).execute }
it { is_expected.to eq([shared_project_3, shared_project_2, shared_project_1, private_project, public_project]) }
end
end
end
...@@ -5,4 +5,93 @@ describe IssuesFinder do ...@@ -5,4 +5,93 @@ describe IssuesFinder do
let!(:subject) { create(:issue, project: project) } let!(:subject) { create(:issue, project: project) }
let(:project_params) { { project_id: project.id } } let(:project_params) { { project_id: project.id } }
end end
describe '#execute' do
include_context 'IssuesFinder context'
include_context 'IssuesFinder#execute context'
context 'scope: all' do
let(:scope) { 'all' }
describe 'filter by weight' do
set(:issue_with_weight_1) { create(:issue, project: project3, weight: 1) }
set(:issue_with_weight_42) { create(:issue, project: project3, weight: 42) }
context 'filter issues with no weight' do
let(:params) { { weight: Issue::WEIGHT_NONE } }
it 'returns all issues' do
expect(issues).to contain_exactly(issue1, issue2, issue3, issue4)
end
end
context 'filter issues with any weight' do
let(:params) { { weight: Issue::WEIGHT_ANY } }
it 'returns all issues' do
expect(issues).to contain_exactly(issue_with_weight_1, issue_with_weight_42)
end
end
context 'filter issues with a specific weight' do
let(:params) { { weight: 42 } }
it 'returns all issues' do
expect(issues).to contain_exactly(issue_with_weight_42)
end
end
end
context 'filtering by assignee IDs' do
set(:user3) { create(:user) }
let(:params) { { assignee_ids: [user2.id, user3.id] } }
before do
project2.add_developer(user3)
issue3.assignees = [user2, user3]
end
it 'returns issues assigned to those users' do
expect(issues).to contain_exactly(issue3)
end
end
end
end
describe '#with_confidentiality_access_check' do
let(:guest) { create(:user) }
set(:authorized_user) { create(:user) }
set(:project) { create(:project, namespace: authorized_user.namespace) }
set(:public_issue) { create(:issue, project: project) }
set(:confidential_issue) { create(:issue, project: project, confidential: true) }
context 'when no project filter is given' do
let(:params) { {} }
context 'for an auditor' do
let(:auditor_user) { create(:user, :auditor) }
subject { described_class.new(auditor_user, params).with_confidentiality_access_check }
it 'returns all issues' do
expect(subject).to include(public_issue, confidential_issue)
end
end
end
context 'when searching within a specific project' do
let(:params) { { project_id: project.id } }
context 'for an auditor' do
let(:auditor_user) { create(:user, :auditor) }
subject { described_class.new(auditor_user, params).with_confidentiality_access_check }
it 'returns all issues' do
expect(subject).to include(public_issue, confidential_issue)
end
end
end
end
end end
...@@ -5,4 +5,16 @@ describe MergeRequestsFinder do ...@@ -5,4 +5,16 @@ describe MergeRequestsFinder do
let!(:subject) { create(:merge_request, source_project: project) } let!(:subject) { create(:merge_request, source_project: project) }
let(:project_params) { { project_id: project.id } } let(:project_params) { { project_id: project.id } }
end end
describe '#execute' do
include_context 'MergeRequestsFinder multiple projects with merge requests context'
it 'ignores filtering by weight' do
params = { project_id: project1.id, scope: 'authored', state: 'opened', weight: Issue::WEIGHT_ANY }
merge_requests = described_class.new(user, params).execute
expect(merge_requests).to contain_exactly(merge_request1)
end
end
end end
...@@ -33,4 +33,21 @@ describe SnippetsFinder do ...@@ -33,4 +33,21 @@ describe SnippetsFinder do
expect(results).to be_empty expect(results).to be_empty
end end
end end
context 'filter by project' do
set(:user) { create(:user) }
set(:group) { create(:group, :public) }
set(:project) { create(:project, :public, group: group) }
set(:private_project_snippet) { create(:project_snippet, :private, project: project) }
set(:internal_project_snippet) { create(:project_snippet, :internal, project: project) }
set(:public_project_snippet) { create(:project_snippet, :public, project: project) }
it 'returns all snippets for auditor users' do
user = create(:user, :auditor)
snippets = described_class.new(user, project: project).execute
expect(snippets).to include(private_project_snippet, internal_project_snippet, public_project_snippet)
end
end
end end
require 'spec_helper'
describe UsersFinder do
describe '#execute' do
include_context 'UsersFinder#execute filter by project context'
context 'with a normal user' do
context 'with LDAP users' do
let!(:ldap_user) { create(:omniauth_user, provider: 'ldap') }
it 'returns ldap users by default' do
users = described_class.new(normal_user).execute
expect(users).to contain_exactly(normal_user, blocked_user, omniauth_user, ldap_user)
end
it 'returns only non-ldap users with skip_ldap: true' do
users = described_class.new(normal_user, skip_ldap: true).execute
expect(users).to contain_exactly(normal_user, blocked_user, omniauth_user)
end
end
end
end
end
require 'spec_helper' require 'spec_helper'
describe GroupProjectsFinder do describe GroupProjectsFinder do
let(:group) { create(:group) } include_context 'GroupProjectsFinder context'
let(:subgroup) { create(:group, parent: group) }
let(:current_user) { create(:user) }
let(:options) { {} }
let(:finder) { described_class.new(group: group, current_user: current_user, options: options) }
let!(:public_project) { create(:project, :public, group: group, path: '1') }
let!(:private_project) { create(:project, :private, group: group, path: '2') }
let!(:shared_project_1) { create(:project, :public, path: '3') }
let!(:shared_project_2) { create(:project, :private, path: '4') }
let!(:shared_project_3) { create(:project, :internal, path: '5') }
let!(:subgroup_project) { create(:project, :public, path: '6', group: subgroup) }
let!(:subgroup_private_project) { create(:project, :private, path: '7', group: subgroup) }
before do
shared_project_1.project_group_links.create(group_access: Gitlab::Access::MAINTAINER, group: group)
shared_project_2.project_group_links.create(group_access: Gitlab::Access::MAINTAINER, group: group)
shared_project_3.project_group_links.create(group_access: Gitlab::Access::MAINTAINER, group: group)
end
subject { finder.execute } subject { finder.execute }
...@@ -162,25 +143,6 @@ describe GroupProjectsFinder do ...@@ -162,25 +143,6 @@ describe GroupProjectsFinder do
end end
end end
describe 'with an auditor current user' do
let(:current_user) { create(:user, :auditor) }
context "only shared" do
let(:options) { { only_shared: true } }
it { is_expected.to eq([shared_project_3, shared_project_2, shared_project_1]) }
end
context "only owned" do
let(:options) { { only_owned: true } }
it { is_expected.to eq([private_project, public_project]) }
end
context "all" do
subject { described_class.new(group: group, current_user: current_user).execute }
it { is_expected.to eq([shared_project_3, shared_project_2, shared_project_1, private_project, public_project]) }
end
end
describe "no user" do describe "no user" do
context "only shared" do context "only shared" do
let(:options) { { only_shared: true } } let(:options) { { only_shared: true } }
......
require 'spec_helper' require 'spec_helper'
describe IssuesFinder do describe IssuesFinder do
set(:user) { create(:user) } include_context 'IssuesFinder context'
set(:user2) { create(:user) }
set(:group) { create(:group) }
set(:subgroup) { create(:group, parent: group) }
set(:project1) { create(:project, group: group) }
set(:project2) { create(:project) }
set(:project3) { create(:project, group: subgroup) }
set(:milestone) { create(:milestone, project: project1) }
set(:label) { create(:label, project: project2) }
set(:issue1) { create(:issue, author: user, assignees: [user], project: project1, milestone: milestone, title: 'gitlab', created_at: 1.week.ago, updated_at: 1.week.ago) }
set(:issue2) { create(:issue, author: user, assignees: [user], project: project2, description: 'gitlab', created_at: 1.week.from_now, updated_at: 1.week.from_now) }
set(:issue3) { create(:issue, author: user2, assignees: [user2], project: project2, title: 'tanuki', description: 'tanuki', created_at: 2.weeks.from_now, updated_at: 2.weeks.from_now) }
set(:issue4) { create(:issue, project: project3) }
set(:award_emoji1) { create(:award_emoji, name: 'thumbsup', user: user, awardable: issue1) }
set(:award_emoji2) { create(:award_emoji, name: 'thumbsup', user: user2, awardable: issue2) }
set(:award_emoji3) { create(:award_emoji, name: 'thumbsdown', user: user, awardable: issue3) }
describe '#execute' do describe '#execute' do
let!(:closed_issue) { create(:issue, author: user2, assignees: [user2], project: project2, state: 'closed') } include_context 'IssuesFinder#execute context'
let!(:label_link) { create(:label_link, label: label, target: issue2) }
let(:search_user) { user }
let(:params) { {} }
let(:issues) { described_class.new(search_user, params.reverse_merge(scope: scope, state: 'opened')).execute }
before(:context) do
project1.add_maintainer(user)
project2.add_developer(user)
project2.add_developer(user2)
project3.add_developer(user)
issue1
issue2
issue3
issue4
award_emoji1
award_emoji2
award_emoji3
end
context 'scope: all' do context 'scope: all' do
let(:scope) { 'all' } let(:scope) { 'all' }
...@@ -48,22 +13,6 @@ describe IssuesFinder do ...@@ -48,22 +13,6 @@ describe IssuesFinder do
expect(issues).to contain_exactly(issue1, issue2, issue3, issue4) expect(issues).to contain_exactly(issue1, issue2, issue3, issue4)
end end
context 'sort by issues with no weight' do
let(:params) { { weight: Issue::WEIGHT_NONE } }
it 'returns all issues' do
expect(issues).to contain_exactly(issue1, issue2, issue3, issue4)
end
end
context 'sort by issues with any weight' do
let(:params) { { weight: Issue::WEIGHT_ANY } }
it 'returns all issues' do
expect(issues).to be_empty
end
end
context 'filtering by assignee ID' do context 'filtering by assignee ID' do
let(:params) { { assignee_id: user.id } } let(:params) { { assignee_id: user.id } }
...@@ -72,21 +21,6 @@ describe IssuesFinder do ...@@ -72,21 +21,6 @@ describe IssuesFinder do
end end
end end
context 'filtering by assignee IDs' do
set(:user3) { create(:user) }
let(:params) { { assignee_ids: [user2.id, user3.id] } }
before do
project2.add_developer(user3)
issue3.assignees = [user2, user3]
end
it 'returns issues assigned to those users' do
expect(issues).to contain_exactly(issue3)
end
end
context 'filtering by assignee usernames' do context 'filtering by assignee usernames' do
set(:user3) { create(:user) } set(:user3) { create(:user) }
let(:params) { { assignee_username: [user2.username, user3.username] } } let(:params) { { assignee_username: [user2.username, user3.username] } }
...@@ -690,16 +624,6 @@ describe IssuesFinder do ...@@ -690,16 +624,6 @@ describe IssuesFinder do
end end
end end
context 'for an auditor' do
let(:auditor_user) { create(:user, :auditor) }
subject { described_class.new(auditor_user, params).with_confidentiality_access_check }
it 'returns all issues' do
expect(subject).to include(public_issue, confidential_issue)
end
end
context 'for an admin' do context 'for an admin' do
let(:admin_user) { create(:user, :admin) } let(:admin_user) { create(:user, :admin) }
...@@ -777,24 +701,8 @@ describe IssuesFinder do ...@@ -777,24 +701,8 @@ describe IssuesFinder do
end end
end end
context 'for an auditor' do
let(:auditor_user) { create(:user, :auditor) }
subject { described_class.new(auditor_user, params).with_confidentiality_access_check }
it 'returns all issues' do
expect(subject).to include(public_issue, confidential_issue)
end
it 'does not filter by confidentiality' do
expect(Issue).not_to receive(:where).with(a_string_matching('confidential'), anything)
subject
end
end
context 'for an admin' do context 'for an admin' do
let(:admin_user) { create(:user, :auditor) } let(:admin_user) { create(:user, :admin) }
subject { described_class.new(admin_user, params).with_confidentiality_access_check } subject { described_class.new(admin_user, params).with_confidentiality_access_check }
......
require 'spec_helper' require 'spec_helper'
describe MergeRequestsFinder do describe MergeRequestsFinder do
include ProjectForksHelper
# We need to explicitly permit Gitaly N+1s because of the specs that use
# :request_store. Gitaly N+1 detection is only enabled when :request_store is,
# but we don't care about potential N+1s when we're just creating several
# projects in the setup phase.
def create_project_without_n_plus_1(*args)
Gitlab::GitalyClient.allow_n_plus_1_calls do
create(:project, :public, *args)
end
end
context "multiple projects with merge requests" do context "multiple projects with merge requests" do
let(:user) { create :user } include_context 'MergeRequestsFinder multiple projects with merge requests context'
let(:user2) { create :user }
let(:group) { create(:group) }
let(:subgroup) { create(:group, parent: group) }
let(:project1) { create_project_without_n_plus_1(group: group) }
let(:project2) do
Gitlab::GitalyClient.allow_n_plus_1_calls do
fork_project(project1, user)
end
end
let(:project3) do
Gitlab::GitalyClient.allow_n_plus_1_calls do
p = fork_project(project1, user)
p.update!(archived: true)
p
end
end
let(:project4) { create_project_without_n_plus_1(:repository, group: subgroup) }
let(:project5) { create_project_without_n_plus_1(group: subgroup) }
let(:project6) { create_project_without_n_plus_1(group: subgroup) }
let!(:merge_request1) { create(:merge_request, author: user, source_project: project2, target_project: project1, target_branch: 'merged-target') }
let!(:merge_request2) { create(:merge_request, :conflict, author: user, source_project: project2, target_project: project1, state: 'closed') }
let!(:merge_request3) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project2, state: 'locked', title: 'thing WIP thing') }
let!(:merge_request4) { create(:merge_request, :simple, author: user, source_project: project3, target_project: project3, title: 'WIP thing') }
let!(:merge_request5) { create(:merge_request, :simple, author: user, source_project: project4, target_project: project4, title: '[WIP]') }
let!(:merge_request6) { create(:merge_request, :simple, author: user, source_project: project5, target_project: project5, title: 'WIP: thing') }
let!(:merge_request7) { create(:merge_request, :simple, author: user, source_project: project6, target_project: project6, title: 'wip thing') }
let!(:merge_request8) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project1, title: '[wip] thing') }
let!(:merge_request9) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project2, title: 'wip: thing') }
before do
project1.add_maintainer(user)
project2.add_developer(user)
project3.add_developer(user)
project2.add_developer(user2)
project4.add_developer(user)
project5.add_developer(user)
project6.add_developer(user)
end
describe '#execute' do describe '#execute' do
it 'filters by scope' do it 'filters by scope' do
params = { scope: 'authored', state: 'opened' } params = { scope: 'authored', state: 'opened' }
merge_requests = described_class.new(user, params).execute
expect(merge_requests.size).to eq(7)
end
it 'ignores sorting by weight' do
params = { project_id: project1.id, scope: 'authored', state: 'opened', weight: Issue::WEIGHT_ANY }
merge_requests = described_class.new(user, params).execute merge_requests = described_class.new(user, params).execute
expect(merge_requests.size).to eq(2)
expect(merge_requests).to contain_exactly(merge_request1, merge_request4, merge_request5)
end end
it 'filters by project' do it 'filters by project' do
params = { project_id: project1.id, scope: 'authored', state: 'opened' } params = { project_id: project1.id, scope: 'authored', state: 'opened' }
merge_requests = described_class.new(user, params).execute merge_requests = described_class.new(user, params).execute
expect(merge_requests.size).to eq(2)
expect(merge_requests).to contain_exactly(merge_request1)
end end
it 'filters by commit sha' do it 'filters by commit sha' do
...@@ -85,24 +31,15 @@ describe MergeRequestsFinder do ...@@ -85,24 +31,15 @@ describe MergeRequestsFinder do
end end
context 'filtering by group' do context 'filtering by group' do
it 'includes all merge requests when user has access' do it 'includes all merge requests when user has access exceluding merge requests from projects the user does not have access to' do
params = { group_id: group.id } private_project = allow_gitaly_n_plus_1 { create(:project, :private, group: group) }
private_project.add_guest(user)
merge_requests = described_class.new(user, params).execute create(:merge_request, :simple, author: user, source_project: private_project, target_project: private_project)
expect(merge_requests.size).to eq(3)
end
it 'excludes merge requests from projects the user does not have access to' do
private_project = create_project_without_n_plus_1(:private, group: group)
private_mr = create(:merge_request, :simple, author: user, source_project: private_project, target_project: private_project)
params = { group_id: group.id } params = { group_id: group.id }
private_project.add_guest(user)
merge_requests = described_class.new(user, params).execute merge_requests = described_class.new(user, params).execute
expect(merge_requests.size).to eq(3) expect(merge_requests).to contain_exactly(merge_request1, merge_request2)
expect(merge_requests).not_to include(private_mr)
end end
it 'filters by group including subgroups', :nested_groups do it 'filters by group including subgroups', :nested_groups do
...@@ -110,14 +47,16 @@ describe MergeRequestsFinder do ...@@ -110,14 +47,16 @@ describe MergeRequestsFinder do
merge_requests = described_class.new(user, params).execute merge_requests = described_class.new(user, params).execute
expect(merge_requests.size).to eq(6) expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request5)
end end
end end
it 'filters by non_archived' do it 'filters by non_archived' do
params = { non_archived: true } params = { non_archived: true }
merge_requests = described_class.new(user, params).execute merge_requests = described_class.new(user, params).execute
expect(merge_requests.size).to eq(8)
expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3, merge_request5)
end end
it 'filters by iid' do it 'filters by iid' do
...@@ -152,41 +91,45 @@ describe MergeRequestsFinder do ...@@ -152,41 +91,45 @@ describe MergeRequestsFinder do
expect(merge_requests).to contain_exactly(merge_request3) expect(merge_requests).to contain_exactly(merge_request3)
end end
it 'filters by wip' do describe 'WIP state' do
params = { wip: 'yes' } let!(:wip_merge_request1) { create(:merge_request, :simple, author: user, source_project: project5, target_project: project5, title: 'WIP: thing') }
let!(:wip_merge_request2) { create(:merge_request, :simple, author: user, source_project: project6, target_project: project6, title: 'wip thing') }
let!(:wip_merge_request3) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project1, title: '[wip] thing') }
let!(:wip_merge_request4) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project2, title: 'wip: thing') }
merge_requests = described_class.new(user, params).execute it 'filters by wip' do
params = { wip: 'yes' }
expect(merge_requests).to contain_exactly(merge_request4, merge_request5, merge_request6, merge_request7, merge_request8, merge_request9) merge_requests = described_class.new(user, params).execute
end
it 'filters by not wip' do expect(merge_requests).to contain_exactly(merge_request4, merge_request5, wip_merge_request1, wip_merge_request2, wip_merge_request3, wip_merge_request4)
params = { wip: 'no' } end
merge_requests = described_class.new(user, params).execute it 'filters by not wip' do
params = { wip: 'no' }
expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3) merge_requests = described_class.new(user, params).execute
end
it 'returns all items if no valid wip param exists' do expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3)
params = { wip: '' } end
merge_requests = described_class.new(user, params).execute it 'returns all items if no valid wip param exists' do
params = { wip: '' }
expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3, merge_request4, merge_request5, merge_request6, merge_request7, merge_request8, merge_request9) merge_requests = described_class.new(user, params).execute
end
it 'adds wip to scalar params' do expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3, merge_request4, merge_request5, wip_merge_request1, wip_merge_request2, wip_merge_request3, wip_merge_request4)
scalar_params = described_class.scalar_params end
it 'adds wip to scalar params' do
scalar_params = described_class.scalar_params
expect(scalar_params).to include(:wip, :assignee_id) expect(scalar_params).to include(:wip, :assignee_id)
end
end end
context 'filtering by group milestone' do context 'filtering by group milestone' do
let!(:group) { create(:group, :public) }
let(:group_milestone) { create(:milestone, group: group) } let(:group_milestone) { create(:milestone, group: group) }
let!(:group_member) { create(:group_member, group: group, user: user) }
let(:params) { { milestone_title: group_milestone.title } }
before do before do
project2.update(namespace: group) project2.update(namespace: group)
...@@ -194,7 +137,9 @@ describe MergeRequestsFinder do ...@@ -194,7 +137,9 @@ describe MergeRequestsFinder do
merge_request3.update(milestone: group_milestone) merge_request3.update(milestone: group_milestone)
end end
it 'returns issues assigned to that group milestone' do it 'returns merge requests assigned to that group milestone' do
params = { milestone_title: group_milestone.title }
merge_requests = described_class.new(user, params).execute merge_requests = described_class.new(user, params).execute
expect(merge_requests).to contain_exactly(merge_request2, merge_request3) expect(merge_requests).to contain_exactly(merge_request2, merge_request3)
...@@ -291,7 +236,7 @@ describe MergeRequestsFinder do ...@@ -291,7 +236,7 @@ describe MergeRequestsFinder do
it 'returns the number of rows for the default state' do it 'returns the number of rows for the default state' do
finder = described_class.new(user) finder = described_class.new(user)
expect(finder.row_count).to eq(7) expect(finder.row_count).to eq(3)
end end
it 'returns the number of rows for a given state' do it 'returns the number of rows for a given state' do
......
...@@ -2,7 +2,6 @@ require 'spec_helper' ...@@ -2,7 +2,6 @@ require 'spec_helper'
describe SnippetsFinder do describe SnippetsFinder do
include Gitlab::Allowable include Gitlab::Allowable
using RSpec::Parameterized::TableSyntax
describe '#initialize' do describe '#initialize' do
it 'raises ArgumentError when a project and author are given' do it 'raises ArgumentError when a project and author are given' do
...@@ -14,182 +13,142 @@ describe SnippetsFinder do ...@@ -14,182 +13,142 @@ describe SnippetsFinder do
end end
end end
context 'filter by scope' do describe '#execute' do
let(:user) { create :user } set(:user) { create(:user) }
let!(:snippet1) { create(:personal_snippet, :private, author: user) } set(:private_personal_snippet) { create(:personal_snippet, :private, author: user) }
let!(:snippet2) { create(:personal_snippet, :internal, author: user) } set(:internal_personal_snippet) { create(:personal_snippet, :internal, author: user) }
let!(:snippet3) { create(:personal_snippet, :public, author: user) } set(:public_personal_snippet) { create(:personal_snippet, :public, author: user) }
it "returns all snippets for 'all' scope" do
snippets = described_class.new(user, scope: :all).execute
expect(snippets).to include(snippet1, snippet2, snippet3)
end
it "returns all snippets for 'are_private' scope" do
snippets = described_class.new(user, scope: :are_private).execute
expect(snippets).to include(snippet1)
expect(snippets).not_to include(snippet2, snippet3)
end
it "returns all snippets for 'are_internal' scope" do
snippets = described_class.new(user, scope: :are_internal).execute
expect(snippets).to include(snippet2) context 'filter by scope' do
expect(snippets).not_to include(snippet1, snippet3) it "returns all snippets for 'all' scope" do
end snippets = described_class.new(user, scope: :all).execute
it "returns all snippets for 'are_private' scope" do expect(snippets).to contain_exactly(private_personal_snippet, internal_personal_snippet, public_personal_snippet)
snippets = described_class.new(user, scope: :are_public).execute end
expect(snippets).to include(snippet3) it "returns all snippets for 'are_private' scope" do
expect(snippets).not_to include(snippet1, snippet2) snippets = described_class.new(user, scope: :are_private).execute
end
end
context 'filter by author' do expect(snippets).to contain_exactly(private_personal_snippet)
let(:user) { create :user } end
let(:user1) { create :user }
let!(:snippet1) { create(:personal_snippet, :private, author: user) }
let!(:snippet2) { create(:personal_snippet, :internal, author: user) }
let!(:snippet3) { create(:personal_snippet, :public, author: user) }
it "returns all public and internal snippets" do it "returns all snippets for 'are_internal' scope" do
snippets = described_class.new(user1, author: user).execute snippets = described_class.new(user, scope: :are_internal).execute
expect(snippets).to include(snippet2, snippet3) expect(snippets).to contain_exactly(internal_personal_snippet)
expect(snippets).not_to include(snippet1) end
end
it "returns internal snippets" do it "returns all snippets for 'are_private' scope" do
snippets = described_class.new(user, author: user, scope: :are_internal).execute snippets = described_class.new(user, scope: :are_public).execute
expect(snippets).to include(snippet2) expect(snippets).to contain_exactly(public_personal_snippet)
expect(snippets).not_to include(snippet1, snippet3) end
end end
it "returns private snippets" do context 'filter by author' do
snippets = described_class.new(user, author: user, scope: :are_private).execute it 'returns all public and internal snippets' do
snippets = described_class.new(create(:user), author: user).execute
expect(snippets).to include(snippet1) expect(snippets).to contain_exactly(internal_personal_snippet, public_personal_snippet)
expect(snippets).not_to include(snippet2, snippet3) end
end
it "returns public snippets" do it 'returns internal snippets' do
snippets = described_class.new(user, author: user, scope: :are_public).execute snippets = described_class.new(user, author: user, scope: :are_internal).execute
expect(snippets).to include(snippet3) expect(snippets).to contain_exactly(internal_personal_snippet)
expect(snippets).not_to include(snippet1, snippet2) end
end
it "returns all snippets" do it 'returns private snippets' do
snippets = described_class.new(user, author: user).execute snippets = described_class.new(user, author: user, scope: :are_private).execute
expect(snippets).to include(snippet1, snippet2, snippet3) expect(snippets).to contain_exactly(private_personal_snippet)
end end
it "returns only public snippets if unauthenticated user" do it 'returns public snippets' do
snippets = described_class.new(nil, author: user).execute snippets = described_class.new(user, author: user, scope: :are_public).execute
expect(snippets).to include(snippet3) expect(snippets).to contain_exactly(public_personal_snippet)
expect(snippets).not_to include(snippet2, snippet1) end
end
it 'returns all snippets for an admin' do it 'returns all snippets' do
admin = create(:user, :admin) snippets = described_class.new(user, author: user).execute
snippets = described_class.new(admin, author: user).execute
expect(snippets).to include(snippet1, snippet2, snippet3) expect(snippets).to contain_exactly(private_personal_snippet, internal_personal_snippet, public_personal_snippet)
end end
end
context 'filter by project' do it 'returns only public snippets if unauthenticated user' do
let(:user) { create :user } snippets = described_class.new(nil, author: user).execute
let(:group) { create :group, :public }
let(:project1) { create(:project, :public, group: group) }
before do expect(snippets).to contain_exactly(public_personal_snippet)
@snippet1 = create(:project_snippet, :private, project: project1) end
@snippet2 = create(:project_snippet, :internal, project: project1)
@snippet3 = create(:project_snippet, :public, project: project1)
end
it "returns public snippets for unauthorized user" do it 'returns all snippets for an admin' do
snippets = described_class.new(nil, project: project1).execute admin = create(:user, :admin)
snippets = described_class.new(admin, author: user).execute
expect(snippets).to include(@snippet3) expect(snippets).to contain_exactly(private_personal_snippet, internal_personal_snippet, public_personal_snippet)
expect(snippets).not_to include(@snippet1, @snippet2) end
end end
it "returns public and internal snippets for non project members" do context 'project snippets' do
snippets = described_class.new(user, project: project1).execute let(:group) { create(:group, :public) }
let(:project) { create(:project, :public, group: group) }
expect(snippets).to include(@snippet2, @snippet3) let!(:private_project_snippet) { create(:project_snippet, :private, project: project) }
expect(snippets).not_to include(@snippet1) let!(:internal_project_snippet) { create(:project_snippet, :internal, project: project) }
end let!(:public_project_snippet) { create(:project_snippet, :public, project: project) }
it "returns public snippets for non project members" do it 'returns public personal and project snippets for unauthorized user' do
snippets = described_class.new(user, project: project1, scope: :are_public).execute snippets = described_class.new(nil, project: project).execute
expect(snippets).to include(@snippet3) expect(snippets).to contain_exactly(public_project_snippet)
expect(snippets).not_to include(@snippet1, @snippet2) end
end
it "returns internal snippets for non project members" do it 'returns public and internal snippets for non project members' do
snippets = described_class.new(user, project: project1, scope: :are_internal).execute snippets = described_class.new(user, project: project).execute
expect(snippets).to include(@snippet2) expect(snippets).to contain_exactly(internal_project_snippet, public_project_snippet)
expect(snippets).not_to include(@snippet1, @snippet3) end
end
it "does not return private snippets for non project members" do it 'returns public snippets for non project members' do
snippets = described_class.new(user, project: project1, scope: :are_private).execute snippets = described_class.new(user, project: project, scope: :are_public).execute
expect(snippets).not_to include(@snippet1, @snippet2, @snippet3) expect(snippets).to contain_exactly(public_project_snippet)
end end
it "returns all snippets for project members" do it 'returns internal snippets for non project members' do
project1.add_developer(user) snippets = described_class.new(user, project: project, scope: :are_internal).execute
snippets = described_class.new(user, project: project1).execute expect(snippets).to contain_exactly(internal_project_snippet)
end
expect(snippets).to include(@snippet1, @snippet2, @snippet3) it 'does not return private snippets for non project members' do
end snippets = described_class.new(user, project: project, scope: :are_private).execute
it "returns private snippets for project members" do expect(snippets).to be_empty
project1.add_developer(user) end
snippets = described_class.new(user, project: project1, scope: :are_private).execute it 'returns all snippets for project members' do
project.add_developer(user)
expect(snippets).to include(@snippet1) snippets = described_class.new(user, project: project).execute
end
it 'returns all snippets for an admin' do expect(snippets).to contain_exactly(private_project_snippet, internal_project_snippet, public_project_snippet)
admin = create(:user, :admin) end
snippets = described_class.new(admin, project: project1).execute
expect(snippets).to include(@snippet1, @snippet2, @snippet3) it 'returns private snippets for project members' do
end project.add_developer(user)
it "returns all snippets for auditor users" do snippets = described_class.new(user, project: project, scope: :are_private).execute
user = create(:user, :auditor)
snippets = described_class.new(user, project: project1).execute expect(snippets).to contain_exactly(private_project_snippet)
end
expect(snippets).to include(@snippet1, @snippet2, @snippet3) it 'returns all snippets for an admin' do
end admin = create(:user, :admin)
end snippets = described_class.new(admin, project: project).execute
describe '#execute' do expect(snippets).to contain_exactly(private_project_snippet, internal_project_snippet, public_project_snippet)
let(:project) { create(:project, :public) } end
let!(:project_snippet) { create(:project_snippet, :public, project: project) }
let!(:personal_snippet) { create(:personal_snippet, :public) }
let(:user) { create(:user) }
subject(:finder) { described_class.new(user) }
it 'returns project- and personal snippets' do
expect(finder.execute).to contain_exactly(project_snippet, personal_snippet)
end end
context 'when the user cannot read cross project' do context 'when the user cannot read cross project' do
...@@ -199,7 +158,7 @@ describe SnippetsFinder do ...@@ -199,7 +158,7 @@ describe SnippetsFinder do
end end
it 'returns only personal snippets when the user cannot read cross project' do it 'returns only personal snippets when the user cannot read cross project' do
expect(finder.execute).to contain_exactly(personal_snippet) expect(described_class.new(user).execute).to contain_exactly(private_personal_snippet, internal_personal_snippet, public_personal_snippet)
end end
end end
end end
......
...@@ -2,10 +2,7 @@ require 'spec_helper' ...@@ -2,10 +2,7 @@ require 'spec_helper'
describe UsersFinder do describe UsersFinder do
describe '#execute' do describe '#execute' do
let!(:user1) { create(:user, username: 'johndoe') } include_context 'UsersFinder#execute filter by project context'
let!(:user2) { create(:user, :blocked, username: 'notsorandom') }
let!(:external_user) { create(:user, :external) }
let!(:omniauth_user) { create(:omniauth_user, provider: 'twitter', extern_uid: '123456') }
context 'with a normal user' do context 'with a normal user' do
let(:user) { create(:user) } let(:user) { create(:user) }
...@@ -13,59 +10,43 @@ describe UsersFinder do ...@@ -13,59 +10,43 @@ describe UsersFinder do
it 'returns all users' do it 'returns all users' do
users = described_class.new(user).execute users = described_class.new(user).execute
expect(users).to contain_exactly(user, user1, user2, omniauth_user) expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user)
end end
it 'filters by username' do it 'filters by username' do
users = described_class.new(user, username: 'johndoe').execute users = described_class.new(user, username: 'johndoe').execute
expect(users).to contain_exactly(user1) expect(users).to contain_exactly(normal_user)
end end
it 'filters by username (case insensitive)' do it 'filters by username (case insensitive)' do
users = described_class.new(user, username: 'joHNdoE').execute users = described_class.new(user, username: 'joHNdoE').execute
expect(users).to contain_exactly(user1) expect(users).to contain_exactly(normal_user)
end end
it 'filters by search' do it 'filters by search' do
users = described_class.new(user, search: 'orando').execute users = described_class.new(user, search: 'orando').execute
expect(users).to contain_exactly(user2) expect(users).to contain_exactly(blocked_user)
end end
it 'filters by blocked users' do it 'filters by blocked users' do
users = described_class.new(user, blocked: true).execute users = described_class.new(user, blocked: true).execute
expect(users).to contain_exactly(user2) expect(users).to contain_exactly(blocked_user)
end end
it 'filters by active users' do it 'filters by active users' do
users = described_class.new(user, active: true).execute users = described_class.new(user, active: true).execute
expect(users).to contain_exactly(user, user1, omniauth_user) expect(users).to contain_exactly(user, normal_user, omniauth_user)
end end
it 'returns no external users' do it 'returns no external users' do
users = described_class.new(user, external: true).execute users = described_class.new(user, external: true).execute
expect(users).to contain_exactly(user, user1, user2, omniauth_user) expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user)
end
context 'with LDAP users' do
let!(:ldap_user) { create(:omniauth_user, provider: 'ldap') }
it 'returns ldap users by default' do
users = described_class.new(user).execute
expect(users).to contain_exactly(user, user1, user2, omniauth_user, ldap_user)
end
it 'returns only non-ldap users with skip_ldap: true' do
users = described_class.new(user, skip_ldap: true).execute
expect(users).to contain_exactly(user, user1, user2, omniauth_user)
end
end end
it 'filters by created_at' do it 'filters by created_at' do
...@@ -85,7 +66,7 @@ describe UsersFinder do ...@@ -85,7 +66,7 @@ describe UsersFinder do
custom_attributes: { foo: 'bar' } custom_attributes: { foo: 'bar' }
).execute ).execute
expect(users).to contain_exactly(user, user1, user2, omniauth_user) expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user)
end end
end end
...@@ -101,20 +82,20 @@ describe UsersFinder do ...@@ -101,20 +82,20 @@ describe UsersFinder do
it 'returns all users' do it 'returns all users' do
users = described_class.new(admin).execute users = described_class.new(admin).execute
expect(users).to contain_exactly(admin, user1, user2, external_user, omniauth_user) expect(users).to contain_exactly(admin, normal_user, blocked_user, external_user, omniauth_user)
end end
it 'filters by custom attributes' do it 'filters by custom attributes' do
create :user_custom_attribute, user: user1, key: 'foo', value: 'foo' create :user_custom_attribute, user: normal_user, key: 'foo', value: 'foo'
create :user_custom_attribute, user: user1, key: 'bar', value: 'bar' create :user_custom_attribute, user: normal_user, key: 'bar', value: 'bar'
create :user_custom_attribute, user: user2, key: 'foo', value: 'foo' create :user_custom_attribute, user: blocked_user, key: 'foo', value: 'foo'
users = described_class.new( users = described_class.new(
admin, admin,
custom_attributes: { foo: 'foo', bar: 'bar' } custom_attributes: { foo: 'foo', bar: 'bar' }
).execute ).execute
expect(users).to contain_exactly(user1) expect(users).to contain_exactly(normal_user)
end end
end end
end end
......
require 'spec_helper'
RSpec.shared_context 'GroupProjectsFinder context' do
let(:group) { create(:group) }
let(:subgroup) { create(:group, parent: group) }
let(:current_user) { create(:user) }
let(:options) { {} }
let(:finder) { described_class.new(group: group, current_user: current_user, options: options) }
let!(:public_project) { create(:project, :public, group: group, path: '1') }
let!(:private_project) { create(:project, :private, group: group, path: '2') }
let!(:shared_project_1) { create(:project, :public, path: '3') }
let!(:shared_project_2) { create(:project, :private, path: '4') }
let!(:shared_project_3) { create(:project, :internal, path: '5') }
let!(:subgroup_project) { create(:project, :public, path: '6', group: subgroup) }
let!(:subgroup_private_project) { create(:project, :private, path: '7', group: subgroup) }
before do
shared_project_1.project_group_links.create(group_access: Gitlab::Access::MAINTAINER, group: group)
shared_project_2.project_group_links.create(group_access: Gitlab::Access::MAINTAINER, group: group)
shared_project_3.project_group_links.create(group_access: Gitlab::Access::MAINTAINER, group: group)
end
end
require 'spec_helper'
RSpec.shared_context 'IssuesFinder context' do
set(:user) { create(:user) }
set(:user2) { create(:user) }
set(:group) { create(:group) }
set(:subgroup) { create(:group, parent: group) }
set(:project1) { create(:project, group: group) }
set(:project2) { create(:project) }
set(:project3) { create(:project, group: subgroup) }
set(:milestone) { create(:milestone, project: project1) }
set(:label) { create(:label, project: project2) }
set(:issue1) { create(:issue, author: user, assignees: [user], project: project1, milestone: milestone, title: 'gitlab', created_at: 1.week.ago, updated_at: 1.week.ago) }
set(:issue2) { create(:issue, author: user, assignees: [user], project: project2, description: 'gitlab', created_at: 1.week.from_now, updated_at: 1.week.from_now) }
set(:issue3) { create(:issue, author: user2, assignees: [user2], project: project2, title: 'tanuki', description: 'tanuki', created_at: 2.weeks.from_now, updated_at: 2.weeks.from_now) }
set(:issue4) { create(:issue, project: project3) }
set(:award_emoji1) { create(:award_emoji, name: 'thumbsup', user: user, awardable: issue1) }
set(:award_emoji2) { create(:award_emoji, name: 'thumbsup', user: user2, awardable: issue2) }
set(:award_emoji3) { create(:award_emoji, name: 'thumbsdown', user: user, awardable: issue3) }
end
RSpec.shared_context 'IssuesFinder#execute context' do
let!(:closed_issue) { create(:issue, author: user2, assignees: [user2], project: project2, state: 'closed') }
let!(:label_link) { create(:label_link, label: label, target: issue2) }
let(:search_user) { user }
let(:params) { {} }
let(:issues) { described_class.new(search_user, params.reverse_merge(scope: scope, state: 'opened')).execute }
before(:context) do
project1.add_maintainer(user)
project2.add_developer(user)
project2.add_developer(user2)
project3.add_developer(user)
issue1
issue2
issue3
issue4
award_emoji1
award_emoji2
award_emoji3
end
end
require 'spec_helper'
RSpec.shared_context 'MergeRequestsFinder multiple projects with merge requests context' do
include ProjectForksHelper
# We need to explicitly permit Gitaly N+1s because of the specs that use
# :request_store. Gitaly N+1 detection is only enabled when :request_store is,
# but we don't care about potential N+1s when we're just creating several
# projects in the setup phase.
def allow_gitaly_n_plus_1
Gitlab::GitalyClient.allow_n_plus_1_calls do
yield
end
end
set(:user) { create(:user) }
set(:user2) { create(:user) }
set(:group) { create(:group) }
set(:subgroup) { create(:group, parent: group) }
set(:project1) do
allow_gitaly_n_plus_1 { create(:project, :public, group: group) }
end
# We cannot use `set` here otherwise we get:
# Failure/Error: allow(RepositoryForkWorker).to receive(:perform_async).and_return(true)
# The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported.
let(:project2) do
allow_gitaly_n_plus_1 do
fork_project(project1, user)
end
end
let(:project3) do
allow_gitaly_n_plus_1 do
fork_project(project1, user).tap do |project|
project.update!(archived: true)
end
end
end
set(:project4) do
allow_gitaly_n_plus_1 { create(:project, :repository, group: subgroup) }
end
set(:project5) do
allow_gitaly_n_plus_1 { create(:project, group: subgroup) }
end
set(:project6) do
allow_gitaly_n_plus_1 { create(:project, group: subgroup) }
end
let!(:merge_request1) { create(:merge_request, author: user, source_project: project2, target_project: project1, target_branch: 'merged-target') }
let!(:merge_request2) { create(:merge_request, :conflict, author: user, source_project: project2, target_project: project1, state: 'closed') }
let!(:merge_request3) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project2, state: 'locked', title: 'thing WIP thing') }
let!(:merge_request4) { create(:merge_request, :simple, author: user, source_project: project3, target_project: project3, title: 'WIP thing') }
let!(:merge_request5) { create(:merge_request, :simple, author: user, source_project: project4, target_project: project4, title: '[WIP]') }
before do
project1.add_maintainer(user)
project2.add_developer(user)
project3.add_developer(user)
project4.add_developer(user)
project5.add_developer(user)
project6.add_developer(user)
project2.add_developer(user2)
end
end
require 'spec_helper'
RSpec.shared_context 'UsersFinder#execute filter by project context' do
set(:normal_user) { create(:user, username: 'johndoe') }
set(:blocked_user) { create(:user, :blocked, username: 'notsorandom') }
set(:external_user) { create(:user, :external) }
set(:omniauth_user) { create(:omniauth_user, provider: 'twitter', extern_uid: '123456') }
end
RSpec.shared_examples 'snippet visibility' do
let!(:author) { create(:user) }
let!(:member) { create(:user) }
let!(:external) { create(:user, :external) }
let!(:snippet_type_visibilities) do
{
public: Snippet::PUBLIC,
internal: Snippet::INTERNAL,
private: Snippet::PRIVATE
}
end
context "For project snippets" do
let!(:users) do
{
unauthenticated: nil,
external: external,
non_member: create(:user),
member: member,
author: author
}
end
let!(:project_type_visibilities) do
{
public: Gitlab::VisibilityLevel::PUBLIC,
internal: Gitlab::VisibilityLevel::INTERNAL,
private: Gitlab::VisibilityLevel::PRIVATE
}
end
let(:project_feature_visibilities) do
{
enabled: ProjectFeature::ENABLED,
private: ProjectFeature::PRIVATE,
disabled: ProjectFeature::DISABLED
}
end
where(:project_type, :feature_visibility, :user_type, :snippet_type, :outcome) do
[
# Public projects
[:public, :enabled, :unauthenticated, :public, true],
[:public, :enabled, :unauthenticated, :internal, false],
[:public, :enabled, :unauthenticated, :private, false],
[:public, :enabled, :external, :public, true],
[:public, :enabled, :external, :internal, false],
[:public, :enabled, :external, :private, false],
[:public, :enabled, :non_member, :public, true],
[:public, :enabled, :non_member, :internal, true],
[:public, :enabled, :non_member, :private, false],
[:public, :enabled, :member, :public, true],
[:public, :enabled, :member, :internal, true],
[:public, :enabled, :member, :private, true],
[:public, :enabled, :author, :public, true],
[:public, :enabled, :author, :internal, true],
[:public, :enabled, :author, :private, true],
[:public, :private, :unauthenticated, :public, false],
[:public, :private, :unauthenticated, :internal, false],
[:public, :private, :unauthenticated, :private, false],
[:public, :private, :external, :public, false],
[:public, :private, :external, :internal, false],
[:public, :private, :external, :private, false],
[:public, :private, :non_member, :public, false],
[:public, :private, :non_member, :internal, false],
[:public, :private, :non_member, :private, false],
[:public, :private, :member, :public, true],
[:public, :private, :member, :internal, true],
[:public, :private, :member, :private, true],
[:public, :private, :author, :public, true],
[:public, :private, :author, :internal, true],
[:public, :private, :author, :private, true],
[:public, :disabled, :unauthenticated, :public, false],
[:public, :disabled, :unauthenticated, :internal, false],
[:public, :disabled, :unauthenticated, :private, false],
[:public, :disabled, :external, :public, false],
[:public, :disabled, :external, :internal, false],
[:public, :disabled, :external, :private, false],
[:public, :disabled, :non_member, :public, false],
[:public, :disabled, :non_member, :internal, false],
[:public, :disabled, :non_member, :private, false],
[:public, :disabled, :member, :public, false],
[:public, :disabled, :member, :internal, false],
[:public, :disabled, :member, :private, false],
[:public, :disabled, :author, :public, false],
[:public, :disabled, :author, :internal, false],
[:public, :disabled, :author, :private, false],
# Internal projects
[:internal, :enabled, :unauthenticated, :public, false],
[:internal, :enabled, :unauthenticated, :internal, false],
[:internal, :enabled, :unauthenticated, :private, false],
[:internal, :enabled, :external, :public, false],
[:internal, :enabled, :external, :internal, false],
[:internal, :enabled, :external, :private, false],
[:internal, :enabled, :non_member, :public, true],
[:internal, :enabled, :non_member, :internal, true],
[:internal, :enabled, :non_member, :private, false],
[:internal, :enabled, :member, :public, true],
[:internal, :enabled, :member, :internal, true],
[:internal, :enabled, :member, :private, true],
[:internal, :enabled, :author, :public, true],
[:internal, :enabled, :author, :internal, true],
[:internal, :enabled, :author, :private, true],
[:internal, :private, :unauthenticated, :public, false],
[:internal, :private, :unauthenticated, :internal, false],
[:internal, :private, :unauthenticated, :private, false],
[:internal, :private, :external, :public, false],
[:internal, :private, :external, :internal, false],
[:internal, :private, :external, :private, false],
[:internal, :private, :non_member, :public, false],
[:internal, :private, :non_member, :internal, false],
[:internal, :private, :non_member, :private, false],
[:internal, :private, :member, :public, true],
[:internal, :private, :member, :internal, true],
[:internal, :private, :member, :private, true],
[:internal, :private, :author, :public, true],
[:internal, :private, :author, :internal, true],
[:internal, :private, :author, :private, true],
[:internal, :disabled, :unauthenticated, :public, false],
[:internal, :disabled, :unauthenticated, :internal, false],
[:internal, :disabled, :unauthenticated, :private, false],
[:internal, :disabled, :external, :public, false],
[:internal, :disabled, :external, :internal, false],
[:internal, :disabled, :external, :private, false],
[:internal, :disabled, :non_member, :public, false],
[:internal, :disabled, :non_member, :internal, false],
[:internal, :disabled, :non_member, :private, false],
[:internal, :disabled, :member, :public, false],
[:internal, :disabled, :member, :internal, false],
[:internal, :disabled, :member, :private, false],
[:internal, :disabled, :author, :public, false],
[:internal, :disabled, :author, :internal, false],
[:internal, :disabled, :author, :private, false],
# Private projects
[:private, :enabled, :unauthenticated, :public, false],
[:private, :enabled, :unauthenticated, :internal, false],
[:private, :enabled, :unauthenticated, :private, false],
[:private, :enabled, :external, :public, true],
[:private, :enabled, :external, :internal, true],
[:private, :enabled, :external, :private, true],
[:private, :enabled, :non_member, :public, false],
[:private, :enabled, :non_member, :internal, false],
[:private, :enabled, :non_member, :private, false],
[:private, :enabled, :member, :public, true],
[:private, :enabled, :member, :internal, true],
[:private, :enabled, :member, :private, true],
[:private, :enabled, :author, :public, true],
[:private, :enabled, :author, :internal, true],
[:private, :enabled, :author, :private, true],
[:private, :private, :unauthenticated, :public, false],
[:private, :private, :unauthenticated, :internal, false],
[:private, :private, :unauthenticated, :private, false],
[:private, :private, :external, :public, true],
[:private, :private, :external, :internal, true],
[:private, :private, :external, :private, true],
[:private, :private, :non_member, :public, false],
[:private, :private, :non_member, :internal, false],
[:private, :private, :non_member, :private, false],
[:private, :private, :member, :public, true],
[:private, :private, :member, :internal, true],
[:private, :private, :member, :private, true],
[:private, :private, :author, :public, true],
[:private, :private, :author, :internal, true],
[:private, :private, :author, :private, true],
[:private, :disabled, :unauthenticated, :public, false],
[:private, :disabled, :unauthenticated, :internal, false],
[:private, :disabled, :unauthenticated, :private, false],
[:private, :disabled, :external, :public, false],
[:private, :disabled, :external, :internal, false],
[:private, :disabled, :external, :private, false],
[:private, :disabled, :non_member, :public, false],
[:private, :disabled, :non_member, :internal, false],
[:private, :disabled, :non_member, :private, false],
[:private, :disabled, :member, :public, false],
[:private, :disabled, :member, :internal, false],
[:private, :disabled, :member, :private, false],
[:private, :disabled, :author, :public, false],
[:private, :disabled, :author, :internal, false],
[:private, :disabled, :author, :private, false]
]
end
with_them do
let!(:project) { create(:project, visibility_level: project_type_visibilities[project_type]) }
let!(:project_feature) { project.project_feature.update_column(:snippets_access_level, project_feature_visibilities[feature_visibility]) }
let!(:user) { users[user_type] }
let!(:snippet) { create(:project_snippet, visibility_level: snippet_type_visibilities[snippet_type], project: project, author: author) }
let!(:members) do
project.add_developer(author)
project.add_developer(member)
project.add_developer(external) if project.private?
end
context "For #{params[:project_type]} project and #{params[:user_type]} users" do
it 'should agree with the read_project_snippet policy' do
expect(can?(user, :read_project_snippet, snippet)).to eq(outcome)
end
it 'should return proper outcome' do
results = described_class.new(user, project: project).execute
expect(results.include?(snippet)).to eq(outcome)
end
end
context "Without a given project and #{params[:user_type]} users" do
it 'should return proper outcome' do
results = described_class.new(user).execute
expect(results.include?(snippet)).to eq(outcome)
end
it 'returns no snippets when the user cannot read cross project' do
allow(Ability).to receive(:allowed?).and_call_original
allow(Ability).to receive(:allowed?).with(user, :read_cross_project) { false }
snippets = described_class.new(user).execute
expect(snippets).to be_empty
end
end
end
end
context 'For personal snippets' do
let!(:users) do
{
unauthenticated: nil,
external: external,
non_member: create(:user),
author: author
}
end
where(:snippet_visibility, :user_type, :outcome) do
[
[:public, :unauthenticated, true],
[:public, :external, true],
[:public, :non_member, true],
[:public, :author, true],
[:internal, :unauthenticated, false],
[:internal, :external, false],
[:internal, :non_member, true],
[:internal, :author, true],
[:private, :unauthenticated, false],
[:private, :external, false],
[:private, :non_member, false],
[:private, :author, true]
]
end
with_them do
let!(:user) { users[user_type] }
let!(:snippet) { create(:personal_snippet, visibility_level: snippet_type_visibilities[snippet_visibility], author: author) }
context "For personal and #{params[:snippet_visibility]} snippets with #{params[:user_type]} user" do
it 'should agree with read_personal_snippet policy' do
expect(can?(user, :read_personal_snippet, snippet)).to eq(outcome)
end
it 'should return proper outcome' do
results = described_class.new(user).execute
expect(results.include?(snippet)).to eq(outcome)
end
it 'should return personal snippets when the user cannot read cross project' do
allow(Ability).to receive(:allowed?).and_call_original
allow(Ability).to receive(:allowed?).with(user, :read_cross_project) { false }
results = described_class.new(user).execute
expect(results.include?(snippet)).to eq(outcome)
end
end
end
end
end
RSpec.shared_examples 'snippet visibility' do
using RSpec::Parameterized::TableSyntax
# Make sure no snippets exist prior to running the test matrix
before(:context) do
DatabaseCleaner.clean_with(:truncation)
end
set(:author) { create(:user) }
set(:member) { create(:user) }
set(:external) { create(:user, :external) }
context "For project snippets" do
let!(:users) do
{
unauthenticated: nil,
external: external,
non_member: create(:user),
member: member,
author: author
}
end
where(:project_type, :feature_visibility, :user_type, :snippet_type, :outcome) do
[
# Public projects
[:public, ProjectFeature::ENABLED, :unauthenticated, Snippet::PUBLIC, true],
[:public, ProjectFeature::ENABLED, :unauthenticated, Snippet::INTERNAL, false],
[:public, ProjectFeature::ENABLED, :unauthenticated, Snippet::PRIVATE, false],
[:public, ProjectFeature::ENABLED, :external, Snippet::PUBLIC, true],
[:public, ProjectFeature::ENABLED, :external, Snippet::INTERNAL, false],
[:public, ProjectFeature::ENABLED, :external, Snippet::PRIVATE, false],
[:public, ProjectFeature::ENABLED, :non_member, Snippet::PUBLIC, true],
[:public, ProjectFeature::ENABLED, :non_member, Snippet::INTERNAL, true],
[:public, ProjectFeature::ENABLED, :non_member, Snippet::PRIVATE, false],
[:public, ProjectFeature::ENABLED, :member, Snippet::PUBLIC, true],
[:public, ProjectFeature::ENABLED, :member, Snippet::INTERNAL, true],
[:public, ProjectFeature::ENABLED, :member, Snippet::PRIVATE, true],
[:public, ProjectFeature::ENABLED, :author, Snippet::PUBLIC, true],
[:public, ProjectFeature::ENABLED, :author, Snippet::INTERNAL, true],
[:public, ProjectFeature::ENABLED, :author, Snippet::PRIVATE, true],
[:public, ProjectFeature::PRIVATE, :unauthenticated, Snippet::PUBLIC, false],
[:public, ProjectFeature::PRIVATE, :unauthenticated, Snippet::INTERNAL, false],
[:public, ProjectFeature::PRIVATE, :unauthenticated, Snippet::PRIVATE, false],
[:public, ProjectFeature::PRIVATE, :external, Snippet::PUBLIC, false],
[:public, ProjectFeature::PRIVATE, :external, Snippet::INTERNAL, false],
[:public, ProjectFeature::PRIVATE, :external, Snippet::PRIVATE, false],
[:public, ProjectFeature::PRIVATE, :non_member, Snippet::PUBLIC, false],
[:public, ProjectFeature::PRIVATE, :non_member, Snippet::INTERNAL, false],
[:public, ProjectFeature::PRIVATE, :non_member, Snippet::PRIVATE, false],
[:public, ProjectFeature::PRIVATE, :member, Snippet::PUBLIC, true],
[:public, ProjectFeature::PRIVATE, :member, Snippet::INTERNAL, true],
[:public, ProjectFeature::PRIVATE, :member, Snippet::PRIVATE, true],
[:public, ProjectFeature::PRIVATE, :author, Snippet::PUBLIC, true],
[:public, ProjectFeature::PRIVATE, :author, Snippet::INTERNAL, true],
[:public, ProjectFeature::PRIVATE, :author, Snippet::PRIVATE, true],
[:public, ProjectFeature::DISABLED, :unauthenticated, Snippet::PUBLIC, false],
[:public, ProjectFeature::DISABLED, :unauthenticated, Snippet::INTERNAL, false],
[:public, ProjectFeature::DISABLED, :unauthenticated, Snippet::PRIVATE, false],
[:public, ProjectFeature::DISABLED, :external, Snippet::PUBLIC, false],
[:public, ProjectFeature::DISABLED, :external, Snippet::INTERNAL, false],
[:public, ProjectFeature::DISABLED, :external, Snippet::PRIVATE, false],
[:public, ProjectFeature::DISABLED, :non_member, Snippet::PUBLIC, false],
[:public, ProjectFeature::DISABLED, :non_member, Snippet::INTERNAL, false],
[:public, ProjectFeature::DISABLED, :non_member, Snippet::PRIVATE, false],
[:public, ProjectFeature::DISABLED, :member, Snippet::PUBLIC, false],
[:public, ProjectFeature::DISABLED, :member, Snippet::INTERNAL, false],
[:public, ProjectFeature::DISABLED, :member, Snippet::PRIVATE, false],
[:public, ProjectFeature::DISABLED, :author, Snippet::PUBLIC, false],
[:public, ProjectFeature::DISABLED, :author, Snippet::INTERNAL, false],
[:public, ProjectFeature::DISABLED, :author, Snippet::PRIVATE, false],
# Internal projects
[:internal, ProjectFeature::ENABLED, :unauthenticated, Snippet::PUBLIC, false],
[:internal, ProjectFeature::ENABLED, :unauthenticated, Snippet::INTERNAL, false],
[:internal, ProjectFeature::ENABLED, :unauthenticated, Snippet::PRIVATE, false],
[:internal, ProjectFeature::ENABLED, :external, Snippet::PUBLIC, false],
[:internal, ProjectFeature::ENABLED, :external, Snippet::INTERNAL, false],
[:internal, ProjectFeature::ENABLED, :external, Snippet::PRIVATE, false],
[:internal, ProjectFeature::ENABLED, :non_member, Snippet::PUBLIC, true],
[:internal, ProjectFeature::ENABLED, :non_member, Snippet::INTERNAL, true],
[:internal, ProjectFeature::ENABLED, :non_member, Snippet::PRIVATE, false],
[:internal, ProjectFeature::ENABLED, :member, Snippet::PUBLIC, true],
[:internal, ProjectFeature::ENABLED, :member, Snippet::INTERNAL, true],
[:internal, ProjectFeature::ENABLED, :member, Snippet::PRIVATE, true],
[:internal, ProjectFeature::ENABLED, :author, Snippet::PUBLIC, true],
[:internal, ProjectFeature::ENABLED, :author, Snippet::INTERNAL, true],
[:internal, ProjectFeature::ENABLED, :author, Snippet::PRIVATE, true],
[:internal, ProjectFeature::PRIVATE, :unauthenticated, Snippet::PUBLIC, false],
[:internal, ProjectFeature::PRIVATE, :unauthenticated, Snippet::INTERNAL, false],
[:internal, ProjectFeature::PRIVATE, :unauthenticated, Snippet::PRIVATE, false],
[:internal, ProjectFeature::PRIVATE, :external, Snippet::PUBLIC, false],
[:internal, ProjectFeature::PRIVATE, :external, Snippet::INTERNAL, false],
[:internal, ProjectFeature::PRIVATE, :external, Snippet::PRIVATE, false],
[:internal, ProjectFeature::PRIVATE, :non_member, Snippet::PUBLIC, false],
[:internal, ProjectFeature::PRIVATE, :non_member, Snippet::INTERNAL, false],
[:internal, ProjectFeature::PRIVATE, :non_member, Snippet::PRIVATE, false],
[:internal, ProjectFeature::PRIVATE, :member, Snippet::PUBLIC, true],
[:internal, ProjectFeature::PRIVATE, :member, Snippet::INTERNAL, true],
[:internal, ProjectFeature::PRIVATE, :member, Snippet::PRIVATE, true],
[:internal, ProjectFeature::PRIVATE, :author, Snippet::PUBLIC, true],
[:internal, ProjectFeature::PRIVATE, :author, Snippet::INTERNAL, true],
[:internal, ProjectFeature::PRIVATE, :author, Snippet::PRIVATE, true],
[:internal, ProjectFeature::DISABLED, :unauthenticated, Snippet::PUBLIC, false],
[:internal, ProjectFeature::DISABLED, :unauthenticated, Snippet::INTERNAL, false],
[:internal, ProjectFeature::DISABLED, :unauthenticated, Snippet::PRIVATE, false],
[:internal, ProjectFeature::DISABLED, :external, Snippet::PUBLIC, false],
[:internal, ProjectFeature::DISABLED, :external, Snippet::INTERNAL, false],
[:internal, ProjectFeature::DISABLED, :external, Snippet::PRIVATE, false],
[:internal, ProjectFeature::DISABLED, :non_member, Snippet::PUBLIC, false],
[:internal, ProjectFeature::DISABLED, :non_member, Snippet::INTERNAL, false],
[:internal, ProjectFeature::DISABLED, :non_member, Snippet::PRIVATE, false],
[:internal, ProjectFeature::DISABLED, :member, Snippet::PUBLIC, false],
[:internal, ProjectFeature::DISABLED, :member, Snippet::INTERNAL, false],
[:internal, ProjectFeature::DISABLED, :member, Snippet::PRIVATE, false],
[:internal, ProjectFeature::DISABLED, :author, Snippet::PUBLIC, false],
[:internal, ProjectFeature::DISABLED, :author, Snippet::INTERNAL, false],
[:internal, ProjectFeature::DISABLED, :author, Snippet::PRIVATE, false],
# Private projects
[:private, ProjectFeature::ENABLED, :unauthenticated, Snippet::PUBLIC, false],
[:private, ProjectFeature::ENABLED, :unauthenticated, Snippet::INTERNAL, false],
[:private, ProjectFeature::ENABLED, :unauthenticated, Snippet::PRIVATE, false],
[:private, ProjectFeature::ENABLED, :external, Snippet::PUBLIC, true],
[:private, ProjectFeature::ENABLED, :external, Snippet::INTERNAL, true],
[:private, ProjectFeature::ENABLED, :external, Snippet::PRIVATE, true],
[:private, ProjectFeature::ENABLED, :non_member, Snippet::PUBLIC, false],
[:private, ProjectFeature::ENABLED, :non_member, Snippet::INTERNAL, false],
[:private, ProjectFeature::ENABLED, :non_member, Snippet::PRIVATE, false],
[:private, ProjectFeature::ENABLED, :member, Snippet::PUBLIC, true],
[:private, ProjectFeature::ENABLED, :member, Snippet::INTERNAL, true],
[:private, ProjectFeature::ENABLED, :member, Snippet::PRIVATE, true],
[:private, ProjectFeature::ENABLED, :author, Snippet::PUBLIC, true],
[:private, ProjectFeature::ENABLED, :author, Snippet::INTERNAL, true],
[:private, ProjectFeature::ENABLED, :author, Snippet::PRIVATE, true],
[:private, ProjectFeature::PRIVATE, :unauthenticated, Snippet::PUBLIC, false],
[:private, ProjectFeature::PRIVATE, :unauthenticated, Snippet::INTERNAL, false],
[:private, ProjectFeature::PRIVATE, :unauthenticated, Snippet::PRIVATE, false],
[:private, ProjectFeature::PRIVATE, :external, Snippet::PUBLIC, true],
[:private, ProjectFeature::PRIVATE, :external, Snippet::INTERNAL, true],
[:private, ProjectFeature::PRIVATE, :external, Snippet::PRIVATE, true],
[:private, ProjectFeature::PRIVATE, :non_member, Snippet::PUBLIC, false],
[:private, ProjectFeature::PRIVATE, :non_member, Snippet::INTERNAL, false],
[:private, ProjectFeature::PRIVATE, :non_member, Snippet::PRIVATE, false],
[:private, ProjectFeature::PRIVATE, :member, Snippet::PUBLIC, true],
[:private, ProjectFeature::PRIVATE, :member, Snippet::INTERNAL, true],
[:private, ProjectFeature::PRIVATE, :member, Snippet::PRIVATE, true],
[:private, ProjectFeature::PRIVATE, :author, Snippet::PUBLIC, true],
[:private, ProjectFeature::PRIVATE, :author, Snippet::INTERNAL, true],
[:private, ProjectFeature::PRIVATE, :author, Snippet::PRIVATE, true],
[:private, ProjectFeature::DISABLED, :unauthenticated, Snippet::PUBLIC, false],
[:private, ProjectFeature::DISABLED, :unauthenticated, Snippet::INTERNAL, false],
[:private, ProjectFeature::DISABLED, :unauthenticated, Snippet::PRIVATE, false],
[:private, ProjectFeature::DISABLED, :external, Snippet::PUBLIC, false],
[:private, ProjectFeature::DISABLED, :external, Snippet::INTERNAL, false],
[:private, ProjectFeature::DISABLED, :external, Snippet::PRIVATE, false],
[:private, ProjectFeature::DISABLED, :non_member, Snippet::PUBLIC, false],
[:private, ProjectFeature::DISABLED, :non_member, Snippet::INTERNAL, false],
[:private, ProjectFeature::DISABLED, :non_member, Snippet::PRIVATE, false],
[:private, ProjectFeature::DISABLED, :member, Snippet::PUBLIC, false],
[:private, ProjectFeature::DISABLED, :member, Snippet::INTERNAL, false],
[:private, ProjectFeature::DISABLED, :member, Snippet::PRIVATE, false],
[:private, ProjectFeature::DISABLED, :author, Snippet::PUBLIC, false],
[:private, ProjectFeature::DISABLED, :author, Snippet::INTERNAL, false],
[:private, ProjectFeature::DISABLED, :author, Snippet::PRIVATE, false]
]
end
with_them do
let!(:project) { create(:project, visibility_level: Gitlab::VisibilityLevel.level_value(project_type.to_s)) }
let!(:project_feature) { project.project_feature.update_column(:snippets_access_level, feature_visibility) }
let!(:user) { users[user_type] }
let!(:snippet) { create(:project_snippet, visibility_level: snippet_type, project: project, author: author) }
let!(:members) do
project.add_developer(author)
project.add_developer(member)
project.add_developer(external) if project.private?
end
context "For #{params[:project_type]} project and #{params[:user_type]} users" do
it 'should agree with the read_project_snippet policy' do
expect(can?(user, :read_project_snippet, snippet)).to eq(outcome)
end
it 'should return proper outcome' do
results = described_class.new(user, project: project).execute
expect(results.include?(snippet)).to eq(outcome)
end
end
context "Without a given project and #{params[:user_type]} users" do
it 'should return proper outcome' do
results = described_class.new(user).execute
expect(results.include?(snippet)).to eq(outcome)
end
it 'returns no snippets when the user cannot read cross project' do
allow(Ability).to receive(:allowed?).and_call_original
allow(Ability).to receive(:allowed?).with(user, :read_cross_project) { false }
snippets = described_class.new(user).execute
expect(snippets).to be_empty
end
end
end
end
context 'For personal snippets' do
let!(:users) do
{
unauthenticated: nil,
external: external,
non_member: create(:user),
author: author
}
end
where(:snippet_visibility, :user_type, :outcome) do
[
[Snippet::PUBLIC, :unauthenticated, true],
[Snippet::PUBLIC, :external, true],
[Snippet::PUBLIC, :non_member, true],
[Snippet::PUBLIC, :author, true],
[Snippet::INTERNAL, :unauthenticated, false],
[Snippet::INTERNAL, :external, false],
[Snippet::INTERNAL, :non_member, true],
[Snippet::INTERNAL, :author, true],
[Snippet::PRIVATE, :unauthenticated, false],
[Snippet::PRIVATE, :external, false],
[Snippet::PRIVATE, :non_member, false],
[Snippet::PRIVATE, :author, true]
]
end
with_them do
let!(:user) { users[user_type] }
let!(:snippet) { create(:personal_snippet, visibility_level: snippet_visibility, author: author) }
context "For personal and #{params[:snippet_visibility]} snippets with #{params[:user_type]} user" do
it 'should agree with read_personal_snippet policy' do
expect(can?(user, :read_personal_snippet, snippet)).to eq(outcome)
end
it 'should return proper outcome' do
results = described_class.new(user).execute
expect(results.include?(snippet)).to eq(outcome)
end
it 'should return personal snippets when the user cannot read cross project' do
allow(Ability).to receive(:allowed?).and_call_original
allow(Ability).to receive(:allowed?).with(user, :read_cross_project) { false }
results = described_class.new(user).execute
expect(results.include?(snippet)).to eq(outcome)
end
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment