diff options
author | Lin Jen-Shin <godfat@godfat.org> | 2019-03-28 09:42:50 +0300 |
---|---|---|
committer | Lin Jen-Shin <godfat@godfat.org> | 2019-03-28 09:42:50 +0300 |
commit | 7753648a2e9e1e5407b729d650384961807b6e6f (patch) | |
tree | 3893775e3a6bf24fdd896e23de57e77fa3e1eefe | |
parent | 5a2be4c8a548331df011e9de0bc77d7bbe48f700 (diff) | |
parent | 65441cfdda18e1233021b2633552e101dd3b36a1 (diff) |
Merge branch 'ce-reduce-ee-diff-in-spec-policies' into 'master'
[CE] Reduce diff with EE in `spec/policies`
See merge request gitlab-org/gitlab-ce!26593
-rw-r--r-- | spec/policies/board_policy_spec.rb | 8 | ||||
-rw-r--r-- | spec/policies/group_policy_spec.rb | 58 | ||||
-rw-r--r-- | spec/policies/namespace_policy_spec.rb | 2 | ||||
-rw-r--r-- | spec/policies/project_policy_spec.rb | 324 | ||||
-rw-r--r-- | spec/policies/project_snippet_policy_spec.rb | 109 | ||||
-rw-r--r-- | spec/spec_helper.rb | 1 | ||||
-rw-r--r-- | spec/support/helpers/policy_helpers.rb | 11 | ||||
-rw-r--r-- | spec/support/shared_context/policies/project_policy_shared_context.rb | 88 | ||||
-rw-r--r-- | spec/support/shared_contexts/policies/group_policy_shared_context.rb | 47 | ||||
-rw-r--r-- | spec/support/shared_examples/policies/project_policy_shared_examples.rb | 231 |
10 files changed, 432 insertions, 447 deletions
diff --git a/spec/policies/board_policy_spec.rb b/spec/policies/board_policy_spec.rb index 4b76d65ef69..52c23951e37 100644 --- a/spec/policies/board_policy_spec.rb +++ b/spec/policies/board_policy_spec.rb @@ -17,14 +17,6 @@ describe BoardPolicy do ] end - def expect_allowed(*permissions) - permissions.each { |p| is_expected.to be_allowed(p) } - end - - def expect_disallowed(*permissions) - permissions.each { |p| is_expected.not_to be_allowed(p) } - end - context 'group board' do subject { described_class.new(user, group_board) } diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb index 92bdaa8b8b8..dc98baca6dc 100644 --- a/spec/policies/group_policy_spec.rb +++ b/spec/policies/group_policy_spec.rb @@ -1,63 +1,7 @@ require 'spec_helper' describe GroupPolicy do - let(:guest) { create(:user) } - let(:reporter) { create(:user) } - let(:developer) { create(:user) } - let(:maintainer) { create(:user) } - let(:owner) { create(:user) } - let(:admin) { create(:admin) } - let(:group) { create(:group, :private) } - - let(:guest_permissions) do - [:read_label, :read_group, :upload_file, :read_namespace, :read_group_activity, - :read_group_issues, :read_group_boards, :read_group_labels, :read_group_milestones, - :read_group_merge_requests] - end - - let(:reporter_permissions) { [:admin_label] } - - let(:developer_permissions) { [:admin_milestone] } - - let(:maintainer_permissions) do - [ - :create_projects, - :read_cluster, - :create_cluster, - :update_cluster, - :admin_cluster, - :add_cluster - ] - end - - let(:owner_permissions) do - [ - :admin_group, - :admin_namespace, - :admin_group_member, - :change_visibility_level, - :set_note_created_at, - (Gitlab::Database.postgresql? ? :create_subgroup : nil) - ].compact - end - - before do - group.add_guest(guest) - group.add_reporter(reporter) - group.add_developer(developer) - group.add_maintainer(maintainer) - group.add_owner(owner) - end - - subject { described_class.new(current_user, group) } - - def expect_allowed(*permissions) - permissions.each { |p| is_expected.to be_allowed(p) } - end - - def expect_disallowed(*permissions) - permissions.each { |p| is_expected.not_to be_allowed(p) } - end + include_context 'GroupPolicy context' context 'with no user' do let(:group) { create(:group, :public) } diff --git a/spec/policies/namespace_policy_spec.rb b/spec/policies/namespace_policy_spec.rb index 1fdf95ad716..99fa8b1fe44 100644 --- a/spec/policies/namespace_policy_spec.rb +++ b/spec/policies/namespace_policy_spec.rb @@ -30,7 +30,7 @@ describe NamespacePolicy do context 'user who has exceeded project limit' do let(:owner) { create(:user, projects_limit: 0) } - it { is_expected.not_to be_allowed(:create_projects) } + it { is_expected.to be_disallowed(:create_projects) } end end diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index 772d1fbee2b..726ccba8807 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -1,96 +1,7 @@ require 'spec_helper' describe ProjectPolicy do - set(:guest) { create(:user) } - set(:reporter) { create(:user) } - set(:developer) { create(:user) } - set(:maintainer) { create(:user) } - set(:owner) { create(:user) } - set(:admin) { create(:admin) } - let(:project) { create(:project, :public, namespace: owner.namespace) } - - let(:base_guest_permissions) do - %i[ - read_project read_board read_list read_wiki read_issue - read_project_for_iids read_issue_iid read_label - read_milestone read_project_snippet read_project_member read_note - create_project create_issue create_note upload_file create_merge_request_in - award_emoji read_release - ] - end - - let(:base_reporter_permissions) do - %i[ - download_code fork_project create_project_snippet update_issue - admin_issue admin_label admin_list read_commit_status read_build - read_container_image read_pipeline read_environment read_deployment - read_merge_request download_wiki_code read_sentry_issue - ] - end - - let(:team_member_reporter_permissions) do - %i[build_download_code build_read_container_image] - end - - let(:developer_permissions) do - %i[ - admin_milestone admin_merge_request update_merge_request create_commit_status - update_commit_status create_build update_build create_pipeline - update_pipeline create_merge_request_from create_wiki push_code - resolve_note create_container_image update_container_image - create_environment create_deployment create_release update_release - ] - end - - let(:base_maintainer_permissions) do - %i[ - push_to_delete_protected_branch update_project_snippet update_environment - update_deployment admin_project_snippet admin_project_member admin_note admin_wiki admin_project - admin_commit_status admin_build admin_container_image - admin_pipeline admin_environment admin_deployment destroy_release add_cluster - daily_statistics - ] - end - - let(:public_permissions) do - %i[ - download_code fork_project read_commit_status read_pipeline - read_container_image build_download_code build_read_container_image - download_wiki_code read_release - ] - end - - let(:owner_permissions) do - %i[ - change_namespace change_visibility_level rename_project remove_project - archive_project remove_fork_project destroy_merge_request destroy_issue - set_issue_iid set_issue_created_at set_note_created_at - ] - end - - # Used in EE specs - let(:additional_guest_permissions) { [] } - let(:additional_reporter_permissions) { [] } - let(:additional_maintainer_permissions) { [] } - - let(:guest_permissions) { base_guest_permissions + additional_guest_permissions } - let(:reporter_permissions) { base_reporter_permissions + additional_reporter_permissions } - let(:maintainer_permissions) { base_maintainer_permissions + additional_maintainer_permissions } - - before do - project.add_guest(guest) - project.add_maintainer(maintainer) - project.add_developer(developer) - project.add_reporter(reporter) - end - - def expect_allowed(*permissions) - permissions.each { |p| is_expected.to be_allowed(p) } - end - - def expect_disallowed(*permissions) - permissions.each { |p| is_expected.not_to be_allowed(p) } - end + include_context 'ProjectPolicy context' it 'does not include the read_issue permission when the issue author is not a member of the private project' do project = create(:project, :private) @@ -140,7 +51,7 @@ describe ProjectPolicy do end it 'disables boards and lists permissions' do - expect_disallowed :read_board, :create_board, :update_board, :admin_board + expect_disallowed :read_board, :create_board, :update_board expect_disallowed :read_list, :create_list, :update_list, :admin_list end @@ -237,237 +148,6 @@ describe ProjectPolicy do end end - shared_examples 'archived project policies' do - let(:feature_write_abilities) do - described_class::READONLY_FEATURES_WHEN_ARCHIVED.flat_map do |feature| - described_class.create_update_admin_destroy(feature) - end - end - - let(:other_write_abilities) do - %i[ - create_merge_request_in - create_merge_request_from - push_to_delete_protected_branch - push_code - request_access - upload_file - resolve_note - award_emoji - ] - end - - context 'when the project is archived' do - before do - project.archived = true - end - - it 'disables write actions on all relevant project features' do - expect_disallowed(*feature_write_abilities) - end - - it 'disables some other important write actions' do - expect_disallowed(*other_write_abilities) - end - - it 'does not disable other abilities' do - expect_allowed(*(regular_abilities - feature_write_abilities - other_write_abilities)) - end - end - end - - shared_examples 'project policies as anonymous' do - context 'abilities for public projects' do - context 'when a project has pending invites' do - let(:group) { create(:group, :public) } - let(:project) { create(:project, :public, namespace: group) } - let(:user_permissions) { [:create_merge_request_in, :create_project, :create_issue, :create_note, :upload_file, :award_emoji] } - let(:anonymous_permissions) { guest_permissions - user_permissions } - - subject { described_class.new(nil, project) } - - before do - create(:group_member, :invited, group: group) - end - - it 'does not grant owner access' do - expect_allowed(*anonymous_permissions) - expect_disallowed(*user_permissions) - end - - it_behaves_like 'archived project policies' do - let(:regular_abilities) { anonymous_permissions } - end - end - end - - context 'abilities for non-public projects' do - let(:project) { create(:project, namespace: owner.namespace) } - - subject { described_class.new(nil, project) } - - it { is_expected.to be_banned } - end - end - - shared_examples 'project policies as guest' do - subject { described_class.new(guest, project) } - - context 'abilities for non-public projects' do - let(:project) { create(:project, namespace: owner.namespace) } - let(:reporter_public_build_permissions) do - reporter_permissions - [:read_build, :read_pipeline] - end - - it do - expect_allowed(*guest_permissions) - expect_disallowed(*reporter_public_build_permissions) - expect_disallowed(*team_member_reporter_permissions) - expect_disallowed(*developer_permissions) - expect_disallowed(*maintainer_permissions) - expect_disallowed(*owner_permissions) - end - - it_behaves_like 'archived project policies' do - let(:regular_abilities) { guest_permissions } - end - - context 'public builds enabled' do - it do - expect_allowed(*guest_permissions) - expect_allowed(:read_build, :read_pipeline) - end - end - - context 'when public builds disabled' do - before do - project.update(public_builds: false) - end - - it do - expect_allowed(*guest_permissions) - expect_disallowed(:read_build, :read_pipeline) - end - end - - context 'when builds are disabled' do - before do - project.project_feature.update(builds_access_level: ProjectFeature::DISABLED) - end - - it do - expect_disallowed(:read_build) - expect_allowed(:read_pipeline) - end - end - end - end - - shared_examples 'project policies as reporter' do - context 'abilities for non-public projects' do - let(:project) { create(:project, namespace: owner.namespace) } - - subject { described_class.new(reporter, project) } - - it do - expect_allowed(*guest_permissions) - expect_allowed(*reporter_permissions) - expect_allowed(*team_member_reporter_permissions) - expect_disallowed(*developer_permissions) - expect_disallowed(*maintainer_permissions) - expect_disallowed(*owner_permissions) - end - - it_behaves_like 'archived project policies' do - let(:regular_abilities) { reporter_permissions } - end - end - end - - shared_examples 'project policies as developer' do - context 'abilities for non-public projects' do - let(:project) { create(:project, namespace: owner.namespace) } - - subject { described_class.new(developer, project) } - - it do - expect_allowed(*guest_permissions) - expect_allowed(*reporter_permissions) - expect_allowed(*team_member_reporter_permissions) - expect_allowed(*developer_permissions) - expect_disallowed(*maintainer_permissions) - expect_disallowed(*owner_permissions) - end - - it_behaves_like 'archived project policies' do - let(:regular_abilities) { developer_permissions } - end - end - end - - shared_examples 'project policies as maintainer' do - context 'abilities for non-public projects' do - let(:project) { create(:project, namespace: owner.namespace) } - - subject { described_class.new(maintainer, project) } - - it do - expect_allowed(*guest_permissions) - expect_allowed(*reporter_permissions) - expect_allowed(*team_member_reporter_permissions) - expect_allowed(*developer_permissions) - expect_allowed(*maintainer_permissions) - expect_disallowed(*owner_permissions) - end - - it_behaves_like 'archived project policies' do - let(:regular_abilities) { maintainer_permissions } - end - end - end - - shared_examples 'project policies as owner' do - context 'abilities for non-public projects' do - let(:project) { create(:project, namespace: owner.namespace) } - - subject { described_class.new(owner, project) } - - it do - expect_allowed(*guest_permissions) - expect_allowed(*reporter_permissions) - expect_allowed(*team_member_reporter_permissions) - expect_allowed(*developer_permissions) - expect_allowed(*maintainer_permissions) - expect_allowed(*owner_permissions) - end - - it_behaves_like 'archived project policies' do - let(:regular_abilities) { owner_permissions } - end - end - end - - shared_examples 'project policies as admin' do - context 'abilities for non-public projects' do - let(:project) { create(:project, namespace: owner.namespace) } - - subject { described_class.new(admin, project) } - - it do - expect_allowed(*guest_permissions) - expect_allowed(*reporter_permissions) - expect_disallowed(*team_member_reporter_permissions) - expect_allowed(*developer_permissions) - expect_allowed(*maintainer_permissions) - expect_allowed(*owner_permissions) - end - - it_behaves_like 'archived project policies' do - let(:regular_abilities) { owner_permissions } - end - end - end - it_behaves_like 'project policies as anonymous' it_behaves_like 'project policies as guest' it_behaves_like 'project policies as reporter' diff --git a/spec/policies/project_snippet_policy_spec.rb b/spec/policies/project_snippet_policy_spec.rb index d6329e84579..2e9ef1e89fd 100644 --- a/spec/policies/project_snippet_policy_spec.rb +++ b/spec/policies/project_snippet_policy_spec.rb @@ -5,7 +5,7 @@ describe ProjectSnippetPolicy do let(:regular_user) { create(:user) } let(:external_user) { create(:user, :external) } let(:project) { create(:project, :public) } - + let(:snippet) { create(:project_snippet, snippet_visibility, project: project) } let(:author_permissions) do [ :update_project_snippet, @@ -13,23 +13,13 @@ describe ProjectSnippetPolicy do ] end - def abilities(user, snippet_visibility) - snippet = create(:project_snippet, snippet_visibility, project: project) - - described_class.new(user, snippet) - end - - def expect_allowed(*permissions) - permissions.each { |p| is_expected.to be_allowed(p) } - end - - def expect_disallowed(*permissions) - permissions.each { |p| is_expected.not_to be_allowed(p) } - end + subject { described_class.new(current_user, snippet) } context 'public snippet' do + let(:snippet_visibility) { :public } + context 'no user' do - subject { abilities(nil, :public) } + let(:current_user) { nil } it do expect_allowed(:read_project_snippet) @@ -38,7 +28,7 @@ describe ProjectSnippetPolicy do end context 'regular user' do - subject { abilities(regular_user, :public) } + let(:current_user) { regular_user } it do expect_allowed(:read_project_snippet, :create_note) @@ -47,7 +37,7 @@ describe ProjectSnippetPolicy do end context 'external user' do - subject { abilities(external_user, :public) } + let(:current_user) { external_user } it do expect_allowed(:read_project_snippet, :create_note) @@ -57,8 +47,10 @@ describe ProjectSnippetPolicy do end context 'internal snippet' do + let(:snippet_visibility) { :internal } + context 'no user' do - subject { abilities(nil, :internal) } + let(:current_user) { nil } it do expect_disallowed(:read_project_snippet) @@ -67,7 +59,7 @@ describe ProjectSnippetPolicy do end context 'regular user' do - subject { abilities(regular_user, :internal) } + let(:current_user) { regular_user } it do expect_allowed(:read_project_snippet, :create_note) @@ -76,31 +68,31 @@ describe ProjectSnippetPolicy do end context 'external user' do - subject { abilities(external_user, :internal) } + let(:current_user) { external_user } it do expect_disallowed(:read_project_snippet, :create_note) expect_disallowed(*author_permissions) end - end - context 'project team member external user' do - subject { abilities(external_user, :internal) } - - before do - project.add_developer(external_user) - end + context 'project team member' do + before do + project.add_developer(external_user) + end - it do - expect_allowed(:read_project_snippet, :create_note) - expect_disallowed(*author_permissions) + it do + expect_allowed(:read_project_snippet, :create_note) + expect_disallowed(*author_permissions) + end end end end context 'private snippet' do + let(:snippet_visibility) { :private } + context 'no user' do - subject { abilities(nil, :private) } + let(:current_user) { nil } it do expect_disallowed(:read_project_snippet) @@ -109,53 +101,52 @@ describe ProjectSnippetPolicy do end context 'regular user' do - subject { abilities(regular_user, :private) } + let(:current_user) { regular_user } it do expect_disallowed(:read_project_snippet, :create_note) expect_disallowed(*author_permissions) end - end - - context 'snippet author' do - let(:snippet) { create(:project_snippet, :private, author: regular_user, project: project) } - subject { described_class.new(regular_user, snippet) } + context 'snippet author' do + let(:snippet) { create(:project_snippet, :private, author: regular_user, project: project) } - it do - expect_allowed(:read_project_snippet, :create_note) - expect_allowed(*author_permissions) + it do + expect_allowed(:read_project_snippet, :create_note) + expect_allowed(*author_permissions) + end end - end - context 'project team member normal user' do - subject { abilities(regular_user, :private) } - - before do - project.add_developer(regular_user) - end + context 'project team member normal user' do + before do + project.add_developer(regular_user) + end - it do - expect_allowed(:read_project_snippet, :create_note) - expect_disallowed(*author_permissions) + it do + expect_allowed(:read_project_snippet, :create_note) + expect_disallowed(*author_permissions) + end end end - context 'project team member external user' do - subject { abilities(external_user, :private) } + context 'external user' do + context 'project team member' do + let(:current_user) { external_user } - before do - project.add_developer(external_user) - end + before do + project.add_developer(external_user) + end - it do - expect_allowed(:read_project_snippet, :create_note) - expect_disallowed(*author_permissions) + it do + expect_allowed(:read_project_snippet, :create_note) + expect_disallowed(*author_permissions) + end end end context 'admin user' do - subject { abilities(create(:admin), :private) } + let(:snippet_visibility) { :private } + let(:current_user) { create(:admin) } it do expect_allowed(:read_project_snippet, :create_note) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e8d7b18bf04..b3bd453ebd6 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -96,6 +96,7 @@ RSpec.configure do |config| config.include MigrationsHelpers, :migration config.include RedisHelpers config.include Rails.application.routes.url_helpers, type: :routing + config.include PolicyHelpers, type: :policy if ENV['CI'] # This includes the first try, i.e. tests will be run 4 times before failing. diff --git a/spec/support/helpers/policy_helpers.rb b/spec/support/helpers/policy_helpers.rb new file mode 100644 index 00000000000..3d780eb5fb1 --- /dev/null +++ b/spec/support/helpers/policy_helpers.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module PolicyHelpers + def expect_allowed(*permissions) + permissions.each { |p| is_expected.to be_allowed(p) } + end + + def expect_disallowed(*permissions) + permissions.each { |p| is_expected.not_to be_allowed(p) } + end +end diff --git a/spec/support/shared_context/policies/project_policy_shared_context.rb b/spec/support/shared_context/policies/project_policy_shared_context.rb new file mode 100644 index 00000000000..8bcd26ec0cd --- /dev/null +++ b/spec/support/shared_context/policies/project_policy_shared_context.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +RSpec.shared_context 'ProjectPolicy context' do + set(:guest) { create(:user) } + set(:reporter) { create(:user) } + set(:developer) { create(:user) } + set(:maintainer) { create(:user) } + set(:owner) { create(:user) } + set(:admin) { create(:admin) } + let(:project) { create(:project, :public, namespace: owner.namespace) } + + let(:base_guest_permissions) do + %i[ + read_project read_board read_list read_wiki read_issue + read_project_for_iids read_issue_iid read_label + read_milestone read_project_snippet read_project_member read_note + create_project create_issue create_note upload_file create_merge_request_in + award_emoji read_release + ] + end + + let(:base_reporter_permissions) do + %i[ + download_code fork_project create_project_snippet update_issue + admin_issue admin_label admin_list read_commit_status read_build + read_container_image read_pipeline read_environment read_deployment + read_merge_request download_wiki_code read_sentry_issue + ] + end + + let(:team_member_reporter_permissions) do + %i[build_download_code build_read_container_image] + end + + let(:developer_permissions) do + %i[ + admin_milestone admin_merge_request update_merge_request create_commit_status + update_commit_status create_build update_build create_pipeline + update_pipeline create_merge_request_from create_wiki push_code + resolve_note create_container_image update_container_image + create_environment create_deployment create_release update_release + ] + end + + let(:base_maintainer_permissions) do + %i[ + push_to_delete_protected_branch update_project_snippet update_environment + update_deployment admin_project_snippet admin_project_member admin_note admin_wiki admin_project + admin_commit_status admin_build admin_container_image + admin_pipeline admin_environment admin_deployment destroy_release add_cluster + daily_statistics + ] + end + + let(:public_permissions) do + %i[ + download_code fork_project read_commit_status read_pipeline + read_container_image build_download_code build_read_container_image + download_wiki_code read_release + ] + end + + let(:base_owner_permissions) do + %i[ + change_namespace change_visibility_level rename_project remove_project + archive_project remove_fork_project destroy_merge_request destroy_issue + set_issue_iid set_issue_created_at set_note_created_at + ] + end + + # Used in EE specs + let(:additional_guest_permissions) { [] } + let(:additional_reporter_permissions) { [] } + let(:additional_maintainer_permissions) { [] } + let(:additional_owner_permissions) { [] } + + let(:guest_permissions) { base_guest_permissions + additional_guest_permissions } + let(:reporter_permissions) { base_reporter_permissions + additional_reporter_permissions } + let(:maintainer_permissions) { base_maintainer_permissions + additional_maintainer_permissions } + let(:owner_permissions) { base_owner_permissions + additional_owner_permissions } + + before do + project.add_guest(guest) + project.add_maintainer(maintainer) + project.add_developer(developer) + project.add_reporter(reporter) + end +end diff --git a/spec/support/shared_contexts/policies/group_policy_shared_context.rb b/spec/support/shared_contexts/policies/group_policy_shared_context.rb new file mode 100644 index 00000000000..b4808ac0068 --- /dev/null +++ b/spec/support/shared_contexts/policies/group_policy_shared_context.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +RSpec.shared_context 'GroupPolicy context' do + let(:guest) { create(:user) } + let(:reporter) { create(:user) } + let(:developer) { create(:user) } + let(:maintainer) { create(:user) } + let(:owner) { create(:user) } + let(:admin) { create(:admin) } + let(:group) { create(:group, :private) } + + let(:guest_permissions) do + %i[ + read_label read_group upload_file read_namespace read_group_activity + read_group_issues read_group_boards read_group_labels read_group_milestones + read_group_merge_requests + ] + end + let(:reporter_permissions) { [:admin_label] } + let(:developer_permissions) { [:admin_milestone] } + let(:maintainer_permissions) do + %i[ + create_projects + read_cluster create_cluster update_cluster admin_cluster add_cluster + ] + end + let(:owner_permissions) do + [ + :admin_group, + :admin_namespace, + :admin_group_member, + :change_visibility_level, + :set_note_created_at, + (Gitlab::Database.postgresql? ? :create_subgroup : nil) + ].compact + end + + before do + group.add_guest(guest) + group.add_reporter(reporter) + group.add_developer(developer) + group.add_maintainer(maintainer) + group.add_owner(owner) + end + + subject { described_class.new(current_user, group) } +end diff --git a/spec/support/shared_examples/policies/project_policy_shared_examples.rb b/spec/support/shared_examples/policies/project_policy_shared_examples.rb new file mode 100644 index 00000000000..7a71e2ee370 --- /dev/null +++ b/spec/support/shared_examples/policies/project_policy_shared_examples.rb @@ -0,0 +1,231 @@ +# frozen_string_literal: true + +RSpec.shared_examples 'archived project policies' do + let(:feature_write_abilities) do + described_class::READONLY_FEATURES_WHEN_ARCHIVED.flat_map do |feature| + described_class.create_update_admin_destroy(feature) + end + additional_reporter_permissions + additional_maintainer_permissions + end + + let(:other_write_abilities) do + %i[ + create_merge_request_in + create_merge_request_from + push_to_delete_protected_branch + push_code + request_access + upload_file + resolve_note + award_emoji + ] + end + + context 'when the project is archived' do + before do + project.archived = true + end + + it 'disables write actions on all relevant project features' do + expect_disallowed(*feature_write_abilities) + end + + it 'disables some other important write actions' do + expect_disallowed(*other_write_abilities) + end + + it 'does not disable other abilities' do + expect_allowed(*(regular_abilities - feature_write_abilities - other_write_abilities)) + end + end +end + +RSpec.shared_examples 'project policies as anonymous' do + context 'abilities for public projects' do + context 'when a project has pending invites' do + let(:group) { create(:group, :public) } + let(:project) { create(:project, :public, namespace: group) } + let(:user_permissions) { [:create_merge_request_in, :create_project, :create_issue, :create_note, :upload_file, :award_emoji] } + let(:anonymous_permissions) { guest_permissions - user_permissions } + + subject { described_class.new(nil, project) } + + before do + create(:group_member, :invited, group: group) + end + + it 'does not grant owner access' do + expect_allowed(*anonymous_permissions) + expect_disallowed(*user_permissions) + end + + it_behaves_like 'archived project policies' do + let(:regular_abilities) { anonymous_permissions } + end + end + end + + context 'abilities for non-public projects' do + let(:project) { create(:project, namespace: owner.namespace) } + + subject { described_class.new(nil, project) } + + it { is_expected.to be_banned } + end +end + +RSpec.shared_examples 'project policies as guest' do + subject { described_class.new(guest, project) } + + context 'abilities for non-public projects' do + let(:project) { create(:project, namespace: owner.namespace) } + let(:reporter_public_build_permissions) do + reporter_permissions - [:read_build, :read_pipeline] + end + + it do + expect_allowed(*guest_permissions) + expect_disallowed(*reporter_public_build_permissions) + expect_disallowed(*team_member_reporter_permissions) + expect_disallowed(*developer_permissions) + expect_disallowed(*maintainer_permissions) + expect_disallowed(*owner_permissions) + end + + it_behaves_like 'archived project policies' do + let(:regular_abilities) { guest_permissions } + end + + context 'public builds enabled' do + it do + expect_allowed(*guest_permissions) + expect_allowed(:read_build, :read_pipeline) + end + end + + context 'when public builds disabled' do + before do + project.update(public_builds: false) + end + + it do + expect_allowed(*guest_permissions) + expect_disallowed(:read_build, :read_pipeline) + end + end + + context 'when builds are disabled' do + before do + project.project_feature.update(builds_access_level: ProjectFeature::DISABLED) + end + + it do + expect_disallowed(:read_build) + expect_allowed(:read_pipeline) + end + end + end +end + +RSpec.shared_examples 'project policies as reporter' do + context 'abilities for non-public projects' do + let(:project) { create(:project, namespace: owner.namespace) } + + subject { described_class.new(reporter, project) } + + it do + expect_allowed(*guest_permissions) + expect_allowed(*reporter_permissions) + expect_allowed(*team_member_reporter_permissions) + expect_disallowed(*developer_permissions) + expect_disallowed(*maintainer_permissions) + expect_disallowed(*owner_permissions) + end + + it_behaves_like 'archived project policies' do + let(:regular_abilities) { reporter_permissions } + end + end +end + +RSpec.shared_examples 'project policies as developer' do + context 'abilities for non-public projects' do + let(:project) { create(:project, namespace: owner.namespace) } + subject { described_class.new(developer, project) } + + it do + expect_allowed(*guest_permissions) + expect_allowed(*reporter_permissions) + expect_allowed(*team_member_reporter_permissions) + expect_allowed(*developer_permissions) + expect_disallowed(*maintainer_permissions) + expect_disallowed(*owner_permissions) + end + + it_behaves_like 'archived project policies' do + let(:regular_abilities) { developer_permissions } + end + end +end + +RSpec.shared_examples 'project policies as maintainer' do + context 'abilities for non-public projects' do + let(:project) { create(:project, namespace: owner.namespace) } + + subject { described_class.new(maintainer, project) } + + it do + expect_allowed(*guest_permissions) + expect_allowed(*reporter_permissions) + expect_allowed(*team_member_reporter_permissions) + expect_allowed(*developer_permissions) + expect_allowed(*maintainer_permissions) + expect_disallowed(*owner_permissions) + end + + it_behaves_like 'archived project policies' do + let(:regular_abilities) { maintainer_permissions } + end + end +end + +RSpec.shared_examples 'project policies as owner' do + context 'abilities for non-public projects' do + let(:project) { create(:project, namespace: owner.namespace) } + + subject { described_class.new(owner, project) } + + it do + expect_allowed(*guest_permissions) + expect_allowed(*reporter_permissions) + expect_allowed(*team_member_reporter_permissions) + expect_allowed(*developer_permissions) + expect_allowed(*maintainer_permissions) + expect_allowed(*owner_permissions) + end + + it_behaves_like 'archived project policies' do + let(:regular_abilities) { owner_permissions } + end + end +end + +RSpec.shared_examples 'project policies as admin' do + context 'abilities for non-public projects' do + let(:project) { create(:project, namespace: owner.namespace) } + + subject { described_class.new(admin, project) } + + it do + expect_allowed(*guest_permissions) + expect_allowed(*reporter_permissions) + expect_disallowed(*team_member_reporter_permissions) + expect_allowed(*developer_permissions) + expect_allowed(*maintainer_permissions) + expect_allowed(*owner_permissions) + end + + it_behaves_like 'archived project policies' do + let(:regular_abilities) { owner_permissions } + end + end +end |