From c1d4ac251994b4463fb0cfcc263af26ded0d8eac Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Mon, 10 Oct 2022 09:09:04 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .../javascripts/diffs/components/app.vue | 2 +- app/models/user.rb | 4 + app/policies/ci/runner_policy.rb | 11 +- .../shared/_create_protected_tag.html.haml | 2 +- ...agement_timeline_event_created_monthly.yml | 26 +++ ...nagement_timeline_event_edited_monthly.yml | 26 +++ ...agement_timeline_event_deleted_monthly.yml | 26 +++ ...nagement_timeline_event_created_weekly.yml | 26 +++ ...anagement_timeline_event_edited_weekly.yml | 26 +++ ...nagement_timeline_event_deleted_weekly.yml | 26 +++ lib/api/alert_management_alerts.rb | 3 +- .../usage_data_counters/hll_redis_counter.rb | 2 +- .../known_events/common.yml | 23 --- spec/lib/gitlab/git_access_snippet_spec.rb | 1 + .../hll_redis_counter_spec.rb | 1 - spec/lib/gitlab/user_access_snippet_spec.rb | 2 +- spec/models/project_spec.rb | 1 + spec/policies/blob_policy_spec.rb | 1 + spec/policies/ci/runner_policy_spec.rb | 159 ++++++++++-------- spec/policies/issue_policy_spec.rb | 1 + spec/policies/wiki_page_policy_spec.rb | 45 +++-- .../merge_requests/refresh_service_spec.rb | 2 +- spec/support/helpers/project_helpers.rb | 16 -- spec/support/helpers/user_helpers.rb | 33 ++++ .../policies/wiki_policies_shared_examples.rb | 2 +- 25 files changed, 325 insertions(+), 142 deletions(-) create mode 100644 config/metrics/counts_28d/20220906065651_incident_management_timeline_event_created_monthly.yml create mode 100644 config/metrics/counts_28d/20220906070355_incident_management_timeline_event_edited_monthly.yml create mode 100644 config/metrics/counts_28d/20220906070634_incident_management_timeline_event_deleted_monthly.yml create mode 100644 config/metrics/counts_7d/20220906065645_incident_management_timeline_event_created_weekly.yml create mode 100644 config/metrics/counts_7d/20220906070351_incident_management_timeline_event_edited_weekly.yml create mode 100644 config/metrics/counts_7d/20220906070629_incident_management_timeline_event_deleted_weekly.yml create mode 100644 spec/support/helpers/user_helpers.rb diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue index 380aa137a7c..2c330d8c851 100644 --- a/app/assets/javascripts/diffs/components/app.vue +++ b/app/assets/javascripts/diffs/components/app.vue @@ -471,7 +471,7 @@ export default { }, fetchData(toggleTree = true) { this.fetchDiffFilesMeta() - .then(({ real_size }) => { + .then(({ real_size = 0 }) => { this.diffFilesLength = parseInt(real_size, 10); if (toggleTree) { this.setTreeDisplay(); diff --git a/app/models/user.rb b/app/models/user.rb index e1186abb6c1..9ddb19b56df 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -168,6 +168,10 @@ class User < ApplicationRecord through: :group_members, source: :group alias_attribute :masters_groups, :maintainers_groups + has_many :developer_maintainer_owned_groups, + -> { where(members: { access_level: [Gitlab::Access::DEVELOPER, Gitlab::Access::MAINTAINER, Gitlab::Access::OWNER] }) }, + through: :group_members, + source: :group has_many :reporter_developer_maintainer_owned_groups, -> { where(members: { access_level: [Gitlab::Access::REPORTER, Gitlab::Access::DEVELOPER, Gitlab::Access::MAINTAINER, Gitlab::Access::OWNER] }) }, through: :group_members, diff --git a/app/policies/ci/runner_policy.rb b/app/policies/ci/runner_policy.rb index a52dac446ea..1c23b367489 100644 --- a/app/policies/ci/runner_policy.rb +++ b/app/policies/ci/runner_policy.rb @@ -20,8 +20,8 @@ module Ci end with_options scope: :user, score: 5 - condition(:any_developer_groups_inheriting_shared_runners) do - @user.developer_groups.with_shared_runners_enabled.any? + condition(:any_developer_maintainer_owned_groups_inheriting_shared_runners) do + @user.developer_maintainer_owned_groups.with_shared_runners_enabled.any? end with_options scope: :user, score: 5 @@ -31,7 +31,7 @@ module Ci with_options score: 10 condition(:any_associated_projects_in_group_runner_inheriting_group_runners) do - # Check if any projects where user is a developer are inheriting group runners + # Check if any projects where user is a developer+ are inheriting group runners @subject.groups&.any? do |group| group.all_projects .with_group_runners_enabled @@ -48,13 +48,10 @@ module Ci rule { admin | owned_runner }.policy do enable :read_builds - end - - rule { admin | owned_runner }.policy do enable :read_runner end - rule { is_instance_runner & any_developer_groups_inheriting_shared_runners }.policy do + rule { is_instance_runner & any_developer_maintainer_owned_groups_inheriting_shared_runners }.policy do enable :read_runner end diff --git a/app/views/projects/protected_tags/shared/_create_protected_tag.html.haml b/app/views/projects/protected_tags/shared/_create_protected_tag.html.haml index 4d57c832bb4..9ea7f397c0a 100644 --- a/app/views/projects/protected_tags/shared/_create_protected_tag.html.haml +++ b/app/views/projects/protected_tags/shared/_create_protected_tag.html.haml @@ -1,6 +1,6 @@ = form_for [@project, @protected_tag], html: { class: 'new-protected-tag js-new-protected-tag' } do |f| %input{ type: 'hidden', name: 'update_section', value: 'js-protected-tags-settings' } - = render Pajamas::CardComponent.new do |c| + = render Pajamas::CardComponent.new(card_options: { class: 'gl-mb-5' }) do |c| - c.header do = _('Protect a tag') - c.body do diff --git a/config/metrics/counts_28d/20220906065651_incident_management_timeline_event_created_monthly.yml b/config/metrics/counts_28d/20220906065651_incident_management_timeline_event_created_monthly.yml new file mode 100644 index 00000000000..86b11489af0 --- /dev/null +++ b/config/metrics/counts_28d/20220906065651_incident_management_timeline_event_created_monthly.yml @@ -0,0 +1,26 @@ +--- +key_path: redis_hll_counters.incident_management.incident_management_timeline_event_created_monthly +description: Count of unique users created timeline events +product_section: ops +product_stage: monitor +product_group: respond +product_category: incident_management +value_type: number +status: active +milestone: "15.5" +introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97006" +time_frame: 28d +data_source: redis_hll +data_category: optional +instrumentation_class: RedisHLLMetric +performance_indicator_type: [] +options: + events: + - incident_management_timeline_event_created +distribution: + - ce + - ee +tier: + - free + - premium + - ultimate diff --git a/config/metrics/counts_28d/20220906070355_incident_management_timeline_event_edited_monthly.yml b/config/metrics/counts_28d/20220906070355_incident_management_timeline_event_edited_monthly.yml new file mode 100644 index 00000000000..31815426918 --- /dev/null +++ b/config/metrics/counts_28d/20220906070355_incident_management_timeline_event_edited_monthly.yml @@ -0,0 +1,26 @@ +--- +key_path: redis_hll_counters.incident_management.incident_management_timeline_event_edited_monthly +description: Count of unique users edited timeline events +product_section: ops +product_stage: monitor +product_group: respond +product_category: incident_management +value_type: number +status: active +milestone: "15.5" +introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97006" +time_frame: 28d +data_source: redis_hll +data_category: optional +instrumentation_class: RedisHLLMetric +performance_indicator_type: [] +options: + events: + - incident_management_timeline_event_edited +distribution: + - ce + - ee +tier: + - free + - premium + - ultimate diff --git a/config/metrics/counts_28d/20220906070634_incident_management_timeline_event_deleted_monthly.yml b/config/metrics/counts_28d/20220906070634_incident_management_timeline_event_deleted_monthly.yml new file mode 100644 index 00000000000..dbc3ac61071 --- /dev/null +++ b/config/metrics/counts_28d/20220906070634_incident_management_timeline_event_deleted_monthly.yml @@ -0,0 +1,26 @@ +--- +key_path: redis_hll_counters.incident_management.incident_management_timeline_event_deleted_monthly +description: Count of unique users deleted timeline events +product_section: ops +product_stage: monitor +product_group: respond +product_category: incident_management +value_type: number +status: active +milestone: "15.5" +introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97006" +time_frame: 28d +data_source: redis_hll +data_category: optional +instrumentation_class: RedisHLLMetric +performance_indicator_type: [] +options: + events: + - incident_management_timeline_event_deleted +distribution: + - ce + - ee +tier: + - free + - premium + - ultimate diff --git a/config/metrics/counts_7d/20220906065645_incident_management_timeline_event_created_weekly.yml b/config/metrics/counts_7d/20220906065645_incident_management_timeline_event_created_weekly.yml new file mode 100644 index 00000000000..e249dade5ca --- /dev/null +++ b/config/metrics/counts_7d/20220906065645_incident_management_timeline_event_created_weekly.yml @@ -0,0 +1,26 @@ +--- +key_path: redis_hll_counters.incident_management.incident_management_timeline_event_created_weekly +description: Count of unique users created timeline events +product_section: ops +product_stage: monitor +product_group: respond +product_category: incident_management +value_type: number +status: active +milestone: "15.5" +introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97006" +time_frame: 7d +data_source: redis_hll +data_category: optional +instrumentation_class: RedisHLLMetric +performance_indicator_type: [] +options: + events: + - incident_management_timeline_event_created +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate diff --git a/config/metrics/counts_7d/20220906070351_incident_management_timeline_event_edited_weekly.yml b/config/metrics/counts_7d/20220906070351_incident_management_timeline_event_edited_weekly.yml new file mode 100644 index 00000000000..82be8c1d859 --- /dev/null +++ b/config/metrics/counts_7d/20220906070351_incident_management_timeline_event_edited_weekly.yml @@ -0,0 +1,26 @@ +--- +key_path: redis_hll_counters.incident_management.incident_management_timeline_event_edited_weekly +description: Count of unique users edited timeline events +product_section: ops +product_stage: monitor +product_group: respond +product_category: incident_management +value_type: number +status: active +milestone: "15.5" +introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97006" +time_frame: 7d +data_source: redis_hll +data_category: optional +instrumentation_class: RedisHLLMetric +performance_indicator_type: [] +options: + events: + - incident_management_timeline_event_edited +distribution: + - ce + - ee +tier: + - free + - premium + - ultimate diff --git a/config/metrics/counts_7d/20220906070629_incident_management_timeline_event_deleted_weekly.yml b/config/metrics/counts_7d/20220906070629_incident_management_timeline_event_deleted_weekly.yml new file mode 100644 index 00000000000..dbe8ad10298 --- /dev/null +++ b/config/metrics/counts_7d/20220906070629_incident_management_timeline_event_deleted_weekly.yml @@ -0,0 +1,26 @@ +--- +key_path: redis_hll_counters.incident_management.incident_management_timeline_event_deleted_weekly +description: Count of unique users deleted timeline events +product_section: ops +product_stage: monitor +product_group: respond +product_category: incident_management +value_type: number +status: active +milestone: "15.5" +introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97006" +time_frame: 7d +data_source: redis_hll +data_category: optional +instrumentation_class: RedisHLLMetric +performance_indicator_type: [] +options: + events: + - incident_management_timeline_event_deleted +distribution: + - ce + - ee +tier: + - free + - premium + - ultimate diff --git a/lib/api/alert_management_alerts.rb b/lib/api/alert_management_alerts.rb index bbb7e7280c9..f03f133f6f7 100644 --- a/lib/api/alert_management_alerts.rb +++ b/lib/api/alert_management_alerts.rb @@ -32,7 +32,8 @@ module API success Entities::MetricImage end params do - requires :file, type: ::API::Validations::Types::WorkhorseFile, desc: 'The image file to be uploaded' + requires :file, type: ::API::Validations::Types::WorkhorseFile, desc: 'The image file to be uploaded', + documentation: { type: 'file' } optional :url, type: String, desc: 'The url to view more metric info' optional :url_text, type: String, desc: 'A description of the image or URL' end diff --git a/lib/gitlab/usage_data_counters/hll_redis_counter.rb b/lib/gitlab/usage_data_counters/hll_redis_counter.rb index 6863fc0bb4c..56b6832f702 100644 --- a/lib/gitlab/usage_data_counters/hll_redis_counter.rb +++ b/lib/gitlab/usage_data_counters/hll_redis_counter.rb @@ -23,7 +23,6 @@ module Gitlab compliance error_tracking ide_edit - incident_management pipeline_authoring ].freeze @@ -35,6 +34,7 @@ module Gitlab error_tracking ide_edit importer + incident_management incident_management_alerts issues_edit kubernetes_agent diff --git a/lib/gitlab/usage_data_counters/known_events/common.yml b/lib/gitlab/usage_data_counters/known_events/common.yml index a16af3b0d77..4fb2e2266ee 100644 --- a/lib/gitlab/usage_data_counters/known_events/common.yml +++ b/lib/gitlab/usage_data_counters/known_events/common.yml @@ -84,11 +84,6 @@ redis_slot: incident_management category: incident_management aggregation: weekly -- name: incident_management_incident_published - redis_slot: incident_management - category: incident_management - aggregation: weekly - feature_flag: usage_data_incident_management_incident_published - name: incident_management_incident_relate redis_slot: incident_management category: incident_management @@ -114,29 +109,11 @@ redis_slot: incident_management category: incident_management aggregation: weekly -# Incident management linked resources -- name: incident_management_issuable_resource_link_created - redis_slot: incident_management - category: incident_management - aggregation: weekly -- name: incident_management_issuable_resource_link_deleted - redis_slot: incident_management - category: incident_management - aggregation: weekly -- name: incident_management_issuable_resource_link_visited - redis_slot: incident_management - category: incident_management - aggregation: weekly # Incident management alerts - name: incident_management_alert_create_incident redis_slot: incident_management category: incident_management_alerts aggregation: weekly -# Incident management on-call -- name: i_incident_management_oncall_notification_sent - redis_slot: incident_management - category: incident_management_oncall - aggregation: weekly # Testing category - name: i_testing_test_case_parsed category: testing diff --git a/spec/lib/gitlab/git_access_snippet_spec.rb b/spec/lib/gitlab/git_access_snippet_spec.rb index a7036a4f20a..0d069d36e48 100644 --- a/spec/lib/gitlab/git_access_snippet_spec.rb +++ b/spec/lib/gitlab/git_access_snippet_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe Gitlab::GitAccessSnippet do include ProjectHelpers + include UserHelpers include TermsHelper include AdminModeHelper include_context 'ProjectPolicyTable context' diff --git a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb index 282ff2ccb95..cbce867cb98 100644 --- a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb @@ -96,7 +96,6 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s 'source_code', 'incident_management', 'incident_management_alerts', - 'incident_management_oncall', 'testing', 'issues_edit', 'snippets', diff --git a/spec/lib/gitlab/user_access_snippet_spec.rb b/spec/lib/gitlab/user_access_snippet_spec.rb index 4143a3017e8..916e920e2ac 100644 --- a/spec/lib/gitlab/user_access_snippet_spec.rb +++ b/spec/lib/gitlab/user_access_snippet_spec.rb @@ -49,7 +49,7 @@ RSpec.describe Gitlab::UserAccessSnippet do end describe '#can_push_to_branch?' do - include ProjectHelpers + include UserHelpers [:anonymous, :non_member, :guest, :reporter, :maintainer, :admin, :author].each do |membership| context membership.to_s do diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 4850dd92a7e..cf1fd115882 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -4609,6 +4609,7 @@ RSpec.describe Project, factory_default: :keep do describe '.filter_by_feature_visibility' do include_context 'ProjectPolicyTable context' include ProjectHelpers + include UserHelpers let_it_be(:group) { create(:group) } let_it_be_with_reload(:project) { create(:project, namespace: group) } diff --git a/spec/policies/blob_policy_spec.rb b/spec/policies/blob_policy_spec.rb index 1be2318a0fe..c1df4e66677 100644 --- a/spec/policies/blob_policy_spec.rb +++ b/spec/policies/blob_policy_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe BlobPolicy do include_context 'ProjectPolicyTable context' include ProjectHelpers + include UserHelpers let_it_be_with_reload(:project) { create(:project, :repository) } diff --git a/spec/policies/ci/runner_policy_spec.rb b/spec/policies/ci/runner_policy_spec.rb index 880ff0722fa..773d3d9a01d 100644 --- a/spec/policies/ci/runner_policy_spec.rb +++ b/spec/policies/ci/runner_policy_spec.rb @@ -6,42 +6,64 @@ RSpec.describe Ci::RunnerPolicy do describe 'ability :read_runner' do let_it_be(:guest) { create(:user) } let_it_be(:developer) { create(:user) } + let_it_be(:maintainer) { create(:user) } let_it_be(:owner) { create(:user) } - let_it_be(:group1) { create(:group, name: 'top-level', path: 'top-level') } - let_it_be(:subgroup1) { create(:group, name: 'subgroup1', path: 'subgroup1', parent: group1) } - let_it_be(:project1) { create(:project, group: subgroup1) } + let_it_be_with_reload(:group) { create(:group, name: 'top-level', path: 'top-level') } + let_it_be_with_reload(:subgroup) { create(:group, name: 'subgroup', path: 'subgroup', parent: group) } + let_it_be_with_reload(:project) { create(:project, group: subgroup) } + let_it_be(:instance_runner) { create(:ci_runner, :instance) } - let_it_be(:group1_runner) { create(:ci_runner, :group, groups: [group1]) } - let_it_be(:project1_runner) { create(:ci_runner, :project, projects: [project1]) } + let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group]) } + let_it_be(:project_runner) { create(:ci_runner, :project, projects: [project]) } subject(:policy) { described_class.new(user, runner) } - before do - group1.add_guest(guest) - group1.add_developer(developer) - group1.add_owner(owner) + before_all do + group.add_guest(guest) + group.add_developer(developer) + group.add_maintainer(maintainer) + group.add_owner(owner) end - shared_context 'on hierarchy with shared runners disabled' do - around do |example| - group1.update!(shared_runners_enabled: false) - project1.update!(shared_runners_enabled: false) + shared_examples 'a policy allowing reading instance runner depending on runner sharing' do + context 'with instance runner' do + let(:runner) { instance_runner } - example.run - ensure - project1.update!(shared_runners_enabled: true) - group1.update!(shared_runners_enabled: true) + it { expect_allowed :read_runner } + + context 'with shared runners disabled on projects' do + before do + project.update!(shared_runners_enabled: false) + end + + it { expect_allowed :read_runner } + end + + context 'with shared runners disabled for groups and projects' do + before do + group.update!(shared_runners_enabled: false) + project.update!(shared_runners_enabled: false) + end + + it { expect_disallowed :read_runner } + end end end - shared_context 'on hierarchy with group runners disabled' do - around do |example| - project1.update!(group_runners_enabled: false) + shared_examples 'a policy allowing reading group runner depending on runner sharing' do + context 'with group runner' do + let(:runner) { group_runner } - example.run - ensure - project1.update!(group_runners_enabled: true) + it { expect_allowed :read_runner } + + context 'with sharing of group runners disabled' do + before do + project.update!(group_runners_enabled: false) + end + + it { expect_disallowed :read_runner } + end end end @@ -51,27 +73,32 @@ RSpec.describe Ci::RunnerPolicy do it { expect_disallowed :read_runner } - context 'with shared runners disabled' do - include_context 'on hierarchy with shared runners disabled' do - it { expect_disallowed :read_runner } + context 'with shared runners disabled for groups and projects' do + before do + group.update!(shared_runners_enabled: false) + project.update!(shared_runners_enabled: false) end + + it { expect_disallowed :read_runner } end end context 'with group runner' do - let(:runner) { group1_runner } + let(:runner) { group_runner } it { expect_disallowed :read_runner } - context 'with group runner disabled' do - include_context 'on hierarchy with group runners disabled' do - it { expect_disallowed :read_runner } + context 'with sharing of group runners disabled' do + before do + project.update!(group_runners_enabled: false) end + + it { expect_disallowed :read_runner } end end context 'with project runner' do - let(:runner) { project1_runner } + let(:runner) { project_runner } it { expect_disallowed :read_runner } end @@ -92,66 +119,52 @@ RSpec.describe Ci::RunnerPolicy do context 'with developer access' do let(:user) { developer } - context 'with instance runner' do - let(:runner) { instance_runner } + it_behaves_like 'a policy allowing reading instance runner depending on runner sharing' - it { expect_allowed :read_runner } - - context 'with shared runners disabled' do - include_context 'on hierarchy with shared runners disabled' do - it { expect_disallowed :read_runner } - end - end - end - - context 'with group runner' do - let(:runner) { group1_runner } - - it { expect_allowed :read_runner } - - context 'with group runner disabled' do - include_context 'on hierarchy with group runners disabled' do - it { expect_disallowed :read_runner } - end - end - end + it_behaves_like 'a policy allowing reading group runner depending on runner sharing' context 'with project runner' do - let(:runner) { project1_runner } + let(:runner) { project_runner } it { expect_disallowed :read_runner } end end + context 'with maintainer access' do + let(:user) { maintainer } + + it_behaves_like 'a policy allowing reading instance runner depending on runner sharing' + + it_behaves_like 'a policy allowing reading group runner depending on runner sharing' + + context 'with project runner' do + let(:runner) { project_runner } + + it { expect_allowed :read_runner } + end + end + context 'with owner access' do let(:user) { owner } - context 'with instance runner' do - let(:runner) { instance_runner } - - context 'with shared runners disabled' do - include_context 'on hierarchy with shared runners disabled' do - it { expect_disallowed :read_runner } - end - end - - it { expect_allowed :read_runner } - end + it_behaves_like 'a policy allowing reading instance runner depending on runner sharing' context 'with group runner' do - let(:runner) { group1_runner } - - context 'with group runners disabled' do - include_context 'on hierarchy with group runners disabled' do - it { expect_allowed :read_runner } - end - end + let(:runner) { group_runner } it { expect_allowed :read_runner } + + context 'with sharing of group runners disabled' do + before do + project.update!(group_runners_enabled: false) + end + + it { expect_allowed :read_runner } + end end context 'with project runner' do - let(:runner) { project1_runner } + let(:runner) { project_runner } it { expect_allowed :read_runner } end diff --git a/spec/policies/issue_policy_spec.rb b/spec/policies/issue_policy_spec.rb index 4d492deb54c..49c0fd004bc 100644 --- a/spec/policies/issue_policy_spec.rb +++ b/spec/policies/issue_policy_spec.rb @@ -6,6 +6,7 @@ RSpec.describe IssuePolicy do include_context 'ProjectPolicyTable context' include ExternalAuthorizationServiceHelpers include ProjectHelpers + include UserHelpers let(:guest) { create(:user) } let(:author) { create(:user) } diff --git a/spec/policies/wiki_page_policy_spec.rb b/spec/policies/wiki_page_policy_spec.rb index a2fa7f29135..2712026035c 100644 --- a/spec/policies/wiki_page_policy_spec.rb +++ b/spec/policies/wiki_page_policy_spec.rb @@ -5,28 +5,43 @@ require 'spec_helper' RSpec.describe WikiPagePolicy do include_context 'ProjectPolicyTable context' include ProjectHelpers + include UserHelpers using RSpec::Parameterized::TableSyntax - let(:project) { create(:project, :wiki_repo, project_level) } - let(:user) { create_user_from_membership(project, membership) } - let(:wiki_page) { create(:wiki_page, wiki: project.wiki) } + let(:group) { build(:group, :public) } + let(:project) { build(:project, :wiki_repo, project_level, group: group) } + let(:wiki_page) { build(:wiki_page, container: project) } - subject(:policy) { described_class.new(user, wiki_page) } + shared_context 'with :read_wiki_page policy' do + subject(:policy) { described_class.new(user, wiki_page) } - where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do - permission_table_for_guest_feature_access - end + where(:project_level, :feature_access_level, :membership, :admin_mode, :expected_count) do + permission_table_for_guest_feature_access + end - with_them do - it "grants permission" do - enable_admin_mode!(user) if admin_mode - update_feature_access_level(project, feature_access_level) + with_them do + it 'grants the expected permissions' do + enable_admin_mode!(user) if admin_mode + update_feature_access_level(project, feature_access_level) - if expected_count == 1 - expect(policy).to be_allowed(:read_wiki_page) - else - expect(policy).to be_disallowed(:read_wiki_page) + if expected_count == 1 + expect(policy).to be_allowed(:read_wiki_page) + else + expect(policy).to be_disallowed(:read_wiki_page) + end end end end + + context 'when user is a direct project member' do + let(:user) { build_user_from_membership(project, membership) } + + include_context 'with :read_wiki_page policy' + end + + context 'when user is an inherited member from the group' do + let(:user) { build_user_from_membership(group, membership) } + + include_context 'with :read_wiki_page policy' + end end diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb index 5a4b3454b84..02fe45e60db 100644 --- a/spec/services/merge_requests/refresh_service_spec.rb +++ b/spec/services/merge_requests/refresh_service_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe MergeRequests::RefreshService do include ProjectForksHelper - include ProjectHelpers + include UserHelpers let(:project) { create(:project, :repository) } let(:user) { create(:user) } diff --git a/spec/support/helpers/project_helpers.rb b/spec/support/helpers/project_helpers.rb index 2427ed2bcc9..daa07e385ea 100644 --- a/spec/support/helpers/project_helpers.rb +++ b/spec/support/helpers/project_helpers.rb @@ -1,22 +1,6 @@ # frozen_string_literal: true module ProjectHelpers - # @params target [Project] membership target - # @params membership [Symbol] accepts the membership levels :guest, :reporter... - # and phony levels :non_member and :anonymous - def create_user_from_membership(target, membership) - case membership - when :anonymous - nil - when :non_member - create(:user, name: membership) - when :admin - create(:user, :admin, name: 'admin') - else - create(:user, name: membership).tap { |u| target.add_member(u, membership) } - end - end - def update_feature_access_level(project, access_level, additional_params = {}) features = ProjectFeature::FEATURES.dup features.delete(:pages) diff --git a/spec/support/helpers/user_helpers.rb b/spec/support/helpers/user_helpers.rb new file mode 100644 index 00000000000..30fa5b3ad8d --- /dev/null +++ b/spec/support/helpers/user_helpers.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module UserHelpers + def create_user_from_membership(target, membership) + generate_user_from_membership(:create, target, membership) + end + + def build_user_from_membership(target, membership) + generate_user_from_membership(:build, target, membership) + end + + private + + # @param method [Symbol] FactoryBot methods :create, :build, :build_stubbed + # @param target [Project, Group] membership target + # @param membership [Symbol] accepts the membership levels :guest, :reporter... + # and pseudo levels :non_member and :anonymous + def generate_user_from_membership(method, target, membership) + case membership + when :anonymous + nil + when :non_member + FactoryBot.send(method, :user, name: membership) + when :admin + FactoryBot.send(method, :user, :admin, name: 'admin') + else + # `.tap` can only be used with `create`, and if we want to `build` a user, + # it is more performant than creating a `project_member` or `group_member` + # with a built user + create(:user, name: membership).tap { |u| target.add_member(u, membership) } + end + end +end diff --git a/spec/support/shared_examples/policies/wiki_policies_shared_examples.rb b/spec/support/shared_examples/policies/wiki_policies_shared_examples.rb index 991d6289373..b9d4709efd5 100644 --- a/spec/support/shared_examples/policies/wiki_policies_shared_examples.rb +++ b/spec/support/shared_examples/policies/wiki_policies_shared_examples.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.shared_examples 'model with wiki policies' do - include ProjectHelpers + include UserHelpers include AdminModeHelper let(:container) { raise NotImplementedError }