From a9b94e02c9d0e9722d767b4aeeeada54b7ada0df Mon Sep 17 00:00:00 2001 From: Hunter Stewart <hustewart@gitlab.com> Date: Thu, 4 Apr 2024 17:00:26 +0000 Subject: [PATCH] Add canApprove field to ApprovalRuleForSummaryType The functionality is already in Authorizable. This commit exposes whether or not the current_user in the graphQL request is permitted to deploy per rule. --- doc/api/graphql/reference/index.md | 1 + .../approval_rule_for_summary_type.rb | 8 ++++ .../approval_rule_for_summary_type_spec.rb | 40 ++++++++++++++++++- .../approval_rule_spec.rb | 18 ++------- .../protected_environments/approval_rule.rb | 28 +++++++++++++ 5 files changed, 78 insertions(+), 17 deletions(-) create mode 100644 spec/support/shared_contexts/models/protected_environments/approval_rule.rb diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 6aae76d335a0..f8d415038aea 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -27561,6 +27561,7 @@ Which group, user or role is allowed to approve deployments to the environment. | <a id="protectedenvironmentapprovalruleforsummaryaccesslevel"></a>`accessLevel` | [`AccessLevel`](#accesslevel) | Role details. Present if it's role specific access control. | | <a id="protectedenvironmentapprovalruleforsummaryapprovals"></a>`approvals` | [`[DeploymentApproval!]`](#deploymentapproval) | Current approvals of the deployment. | | <a id="protectedenvironmentapprovalruleforsummaryapprovedcount"></a>`approvedCount` | [`Int`](#int) | Approved count. | +| <a id="protectedenvironmentapprovalruleforsummarycanapprove"></a>`canApprove` | [`Boolean`](#boolean) | Indicates whether a user is authorized to approve. | | <a id="protectedenvironmentapprovalruleforsummarygroup"></a>`group` | [`Group`](#group) | Group details. Present if it's group specific access control. | | <a id="protectedenvironmentapprovalruleforsummarypendingapprovalcount"></a>`pendingApprovalCount` | [`Int`](#int) | Pending approval count. | | <a id="protectedenvironmentapprovalruleforsummaryrequiredapprovals"></a>`requiredApprovals` | [`Int`](#int) | Number of required approvals. | diff --git a/ee/app/graphql/types/protected_environments/approval_rule_for_summary_type.rb b/ee/app/graphql/types/protected_environments/approval_rule_for_summary_type.rb index be01e9bc8cd0..5ad74e7da8f7 100644 --- a/ee/app/graphql/types/protected_environments/approval_rule_for_summary_type.rb +++ b/ee/app/graphql/types/protected_environments/approval_rule_for_summary_type.rb @@ -24,6 +24,14 @@ class ApprovalRuleForSummaryType < ApprovalRuleType type: [::Types::Deployments::ApprovalType], description: 'Current approvals of the deployment.', method: :approvals_for_summary + + field :can_approve, + type: GraphQL::Types::Boolean, + description: 'Indicates whether a user is authorized to approve.' + + def can_approve + object.check_access(current_user) + end end # rubocop:enable Graphql/AuthorizeTypes end diff --git a/ee/spec/graphql/types/protected_environments/approval_rule_for_summary_type_spec.rb b/ee/spec/graphql/types/protected_environments/approval_rule_for_summary_type_spec.rb index 70ad98f755e1..eb166c6db8ff 100644 --- a/ee/spec/graphql/types/protected_environments/approval_rule_for_summary_type_spec.rb +++ b/ee/spec/graphql/types/protected_environments/approval_rule_for_summary_type_spec.rb @@ -2,14 +2,50 @@ require 'spec_helper' -RSpec.describe GitlabSchema.types['ProtectedEnvironmentApprovalRuleForSummary'] do +RSpec.describe GitlabSchema.types['ProtectedEnvironmentApprovalRuleForSummary'], + feature_category: :deployment_management do specify { expect(described_class.graphql_name).to eq('ProtectedEnvironmentApprovalRuleForSummary') } it 'includes the expected fields' do expected_fields = %w[ - approved_count pending_approval_count required_approvals status approvals + approvals + approved_count + can_approve + pending_approval_count + required_approvals + status ] expect(described_class).to include_graphql_fields(*expected_fields) end + + describe '#can_approve' do + include_context 'with an approval rule and approver' + + subject(:result) do + described_class.send( + :new, approval_rule, { current_user: user_being_checked } + ).can_approve + end + + context 'when user can approve' do + let_it_be(:user_being_checked) { approver } + + it { is_expected.to eq(true) } + end + + context 'when user cannot approve' do + include_context 'with a non approver' + + let_it_be(:user_being_checked) { non_approver } + + it { is_expected.to eq(false) } + end + + context 'when user is nil' do + let_it_be(:user_being_checked) { nil } + + it { is_expected.to eq(false) } + end + end end diff --git a/ee/spec/models/protected_environments/approval_rule_spec.rb b/ee/spec/models/protected_environments/approval_rule_spec.rb index 36a23c752343..852cc5fc1d44 100644 --- a/ee/spec/models/protected_environments/approval_rule_spec.rb +++ b/ee/spec/models/protected_environments/approval_rule_spec.rb @@ -1,21 +1,9 @@ # frozen_string_literal: true require 'spec_helper' -RSpec.describe ProtectedEnvironments::ApprovalRule do - let_it_be(:project) { create(:project, :repository) } - let_it_be(:environment) { create(:environment, project: project) } - let_it_be(:approver) { create(:user) } - - let!(:protected_environment) { create(:protected_environment, project: project, name: environment.name) } - - let!(:approval_rule) do - create( - :protected_environment_approval_rule, - protected_environment: protected_environment, - user: approver, - required_approvals: 1 - ) - end +RSpec.describe ProtectedEnvironments::ApprovalRule, + feature_category: :deployment_management do + include_context 'with an approval rule and approver' describe 'associations' do it { is_expected.to have_many(:deployment_approvals).class_name('Deployments::Approval').inverse_of(:approval_rule) } diff --git a/spec/support/shared_contexts/models/protected_environments/approval_rule.rb b/spec/support/shared_contexts/models/protected_environments/approval_rule.rb new file mode 100644 index 000000000000..76f4d4380da6 --- /dev/null +++ b/spec/support/shared_contexts/models/protected_environments/approval_rule.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +RSpec.shared_context 'with an approval rule and approver' do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:environment) { create(:environment, project: project) } + let_it_be(:approver) { create(:user) } + + let!(:protected_environment) do + create( + :protected_environment, + project: project, + name: environment.name + ) + end + + let!(:approval_rule) do + create( + :protected_environment_approval_rule, + protected_environment: protected_environment, + user: approver, + required_approvals: 1 + ) + end +end + +RSpec.shared_context 'with a non approver' do + let_it_be(:non_approver) { create(:user) } +end -- GitLab