diff options
author | Robert Speicher <rspeicher@gmail.com> | 2019-03-22 11:25:51 +0000 |
---|---|---|
committer | Robert Speicher <rspeicher@gmail.com> | 2019-03-22 11:25:51 +0000 |
commit | 322c14be63dd8eeab59a98aca6bb9b52642b377c (patch) | |
tree | 2542ac8019fa9c352dca41fa9ebe5008fcb90dcf /spec/support | |
parent | 685a85c6132fbd1f9e5ace08bd4b2808f3a50a8b (diff) | |
parent | 0750638f805eee7d386df5cfff23413610d4e528 (diff) | |
download | gitlab-ce-322c14be63dd8eeab59a98aca6bb9b52642b377c.tar.gz |
Merge branch 'ce-6618-extract-ee-specific-files-lines-for-create-spec-finders' into 'master'
[CE] Extract EE specific files/lines from spec/finders
Closes gitlab-ee#10142 and gitlab-ee#10141
See merge request gitlab-org/gitlab-ce!26337
Diffstat (limited to 'spec/support')
6 files changed, 447 insertions, 322 deletions
diff --git a/spec/support/shared_contexts/finders/group_projects_finder_shared_contexts.rb b/spec/support/shared_contexts/finders/group_projects_finder_shared_contexts.rb new file mode 100644 index 00000000000..a0d994c4d8d --- /dev/null +++ b/spec/support/shared_contexts/finders/group_projects_finder_shared_contexts.rb @@ -0,0 +1,24 @@ +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 diff --git a/spec/support/shared_contexts/finders/issues_finder_shared_contexts.rb b/spec/support/shared_contexts/finders/issues_finder_shared_contexts.rb new file mode 100644 index 00000000000..b8a9554f55f --- /dev/null +++ b/spec/support/shared_contexts/finders/issues_finder_shared_contexts.rb @@ -0,0 +1,44 @@ +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 diff --git a/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb b/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb new file mode 100644 index 00000000000..4df80b4168a --- /dev/null +++ b/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb @@ -0,0 +1,65 @@ +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 diff --git a/spec/support/shared_contexts/finders/users_finder_shared_contexts.rb b/spec/support/shared_contexts/finders/users_finder_shared_contexts.rb new file mode 100644 index 00000000000..9e1f89ee0ed --- /dev/null +++ b/spec/support/shared_contexts/finders/users_finder_shared_contexts.rb @@ -0,0 +1,8 @@ +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 diff --git a/spec/support/shared_examples/snippet_visibility.rb b/spec/support/shared_examples/snippet_visibility.rb deleted file mode 100644 index 3a7c69b7877..00000000000 --- a/spec/support/shared_examples/snippet_visibility.rb +++ /dev/null @@ -1,322 +0,0 @@ -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 diff --git a/spec/support/shared_examples/snippet_visibility_shared_examples.rb b/spec/support/shared_examples/snippet_visibility_shared_examples.rb new file mode 100644 index 00000000000..4f662db2120 --- /dev/null +++ b/spec/support/shared_examples/snippet_visibility_shared_examples.rb @@ -0,0 +1,306 @@ +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 |