From 96987bc545adb80d710176227db565be8c0be6a4 Mon Sep 17 00:00:00 2001 From: Hitesh Raghuvanshi Date: Wed, 15 Jan 2025 09:58:14 +0530 Subject: [PATCH 1/6] Mutation for destroying compliance control Changelog: added EE: true --- doc/api/graphql/reference/index.md | 28 +++++ doc/user/compliance/audit_event_types.md | 1 + ee/app/graphql/ee/types/mutation_type.rb | 2 + .../destroy.rb | 30 +++++ .../compliance_requirements_control_policy.rb | 9 ++ .../destroy_service.rb | 50 ++++++++ ...stroyed_compliance_requirement_control.yml | 10 ++ .../destroy_spec.rb | 74 ++++++++++++ .../destroy_spec.rb | 70 +++++++++++ .../destroy_service_spec.rb | 114 ++++++++++++++++++ locale/gitlab.pot | 9 ++ 11 files changed, 397 insertions(+) create mode 100644 ee/app/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy.rb create mode 100644 ee/app/policies/compliance_management/compliance_framework/compliance_requirements_control_policy.rb create mode 100644 ee/app/services/compliance_management/compliance_framework/compliance_requirements_controls/destroy_service.rb create mode 100644 ee/config/audit_events/types/destroyed_compliance_requirement_control.yml create mode 100644 ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb create mode 100644 ee/spec/requests/api/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb create mode 100644 ee/spec/services/compliance_management/compliance_framework/compliance_requirements_controls/destroy_service_spec.rb diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index b1fb1f542e7c07..6714ed029bd0a9 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -4867,6 +4867,28 @@ Input type: `DestroyComplianceRequirementInput` | `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | | `errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | +### `Mutation.destroyComplianceRequirementsControl` + +DETAILS: +**Introduced** in GitLab 17.9. +**Status**: Experiment. + +Input type: `DestroyComplianceRequirementsControlInput` + +#### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | +| `id` | [`ComplianceManagementComplianceFrameworkComplianceRequirementsControlID!`](#compliancemanagementcomplianceframeworkcompliancerequirementscontrolid) | Global ID of the compliance requirement control to destroy. | + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | +| `errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | + ### `Mutation.destroyContainerRepository` Input type: `DestroyContainerRepositoryInput` @@ -42516,6 +42538,12 @@ A `ComplianceManagementComplianceFrameworkComplianceRequirementID` is a global I An example `ComplianceManagementComplianceFrameworkComplianceRequirementID` is: `"gid://gitlab/ComplianceManagement::ComplianceFramework::ComplianceRequirement/1"`. +### `ComplianceManagementComplianceFrameworkComplianceRequirementsControlID` + +A `ComplianceManagementComplianceFrameworkComplianceRequirementsControlID` is a global ID. It is encoded as a string. + +An example `ComplianceManagementComplianceFrameworkComplianceRequirementsControlID` is: `"gid://gitlab/ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl/1"`. + ### `ComplianceManagementFrameworkID` A `ComplianceManagementFrameworkID` is a global ID. It is encoded as a string. diff --git a/doc/user/compliance/audit_event_types.md b/doc/user/compliance/audit_event_types.md index 4feaf5ffe54917..09a4244d7bb3fc 100644 --- a/doc/user/compliance/audit_event_types.md +++ b/doc/user/compliance/audit_event_types.md @@ -151,6 +151,7 @@ Audit event types belong to the following product categories. | [`delete_status_check`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84624) | An external status check is deleted | **{check-circle}** Yes | GitLab [15.9](https://gitlab.com/gitlab-org/gitlab/-/issues/355805) | Project | | [`destroy_compliance_framework`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74292) | A compliance framework is successfully deleted | **{check-circle}** Yes | GitLab [14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/340649) | Group | | [`destroyed_compliance_requirement`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/170380) | A compliance framework requirement is destroyed | **{check-circle}** Yes | GitLab [17.7](https://gitlab.com/gitlab-org/gitlab/-/issues/470695) | Group | +| [`destroyed_compliance_requirement_control`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177557) | A compliance requirement control is destroyed. | **{check-circle}** Yes | GitLab [17.9](https://gitlab.com/gitlab-org/gitlab/-/issues/512381) | Group | | [`email_created`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114546) | An email is created | **{check-circle}** Yes | GitLab [15.11](https://gitlab.com/gitlab-org/gitlab/-/issues/374107) | User | | [`email_destroyed`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114546) | An email is destroyed | **{check-circle}** Yes | GitLab [15.11](https://gitlab.com/gitlab-org/gitlab/-/issues/374107) | User | | [`external_status_check_name_updated`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106095) | The name of an external status check is updated | **{check-circle}** Yes | GitLab [15.7](https://gitlab.com/gitlab-org/gitlab/-/issues/369333) | Project | diff --git a/ee/app/graphql/ee/types/mutation_type.rb b/ee/app/graphql/ee/types/mutation_type.rb index 55f115170559ec..46816c64fb86ee 100644 --- a/ee/app/graphql/ee/types/mutation_type.rb +++ b/ee/app/graphql/ee/types/mutation_type.rb @@ -265,6 +265,8 @@ def self.authorization_scopes experiment: { milestone: '17.7' } mount_mutation ::Mutations::Ai::SelfHostedModels::ConnectionCheck, experiment: { milestone: '17.7' } + mount_mutation ::Mutations::ComplianceManagement::ComplianceFramework::ComplianceRequirementsControls::Destroy, + experiment: { milestone: '17.9' } prepend(Types::DeprecatedMutations) end diff --git a/ee/app/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy.rb b/ee/app/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy.rb new file mode 100644 index 00000000000000..09d87e10a4fe3c --- /dev/null +++ b/ee/app/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Mutations + module ComplianceManagement + module ComplianceFramework + module ComplianceRequirementsControls + class Destroy < BaseMutation + graphql_name 'DestroyComplianceRequirementsControl' + + authorize :admin_compliance_framework + + argument :id, ::Types::GlobalIDType[ + ::ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl + ], + required: true, + description: 'Global ID of the compliance requirement control to destroy.' + + def resolve(id:) + control = authorized_find!(id: id) + + result = ::ComplianceManagement::ComplianceFramework::ComplianceRequirementsControls::DestroyService.new( + control: control, current_user: current_user).execute + + { errors: result.success? ? [] : Array.wrap(result.message) } + end + end + end + end + end +end diff --git a/ee/app/policies/compliance_management/compliance_framework/compliance_requirements_control_policy.rb b/ee/app/policies/compliance_management/compliance_framework/compliance_requirements_control_policy.rb new file mode 100644 index 00000000000000..96be3ca8ea65f5 --- /dev/null +++ b/ee/app/policies/compliance_management/compliance_framework/compliance_requirements_control_policy.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module ComplianceManagement + module ComplianceFramework + class ComplianceRequirementsControlPolicy < BasePolicy + delegate { @subject.compliance_requirement.framework } + end + end +end diff --git a/ee/app/services/compliance_management/compliance_framework/compliance_requirements_controls/destroy_service.rb b/ee/app/services/compliance_management/compliance_framework/compliance_requirements_controls/destroy_service.rb new file mode 100644 index 00000000000000..3c5e00fdf6c2a4 --- /dev/null +++ b/ee/app/services/compliance_management/compliance_framework/compliance_requirements_controls/destroy_service.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module ComplianceManagement + module ComplianceFramework + module ComplianceRequirementsControls + class DestroyService < BaseService + attr_reader :current_user, :control + + def initialize(control:, current_user:) + @control = control + @current_user = current_user + end + + def execute + return ServiceResponse.error(message: _('Not permitted to destroy requirement control')) unless permitted? + + control.destroy ? success : error + end + + private + + def permitted? + can? current_user, :admin_compliance_framework, control.compliance_requirement.framework + end + + def success + audit_destroy + + ServiceResponse.success(message: _('Compliance requirement control successfully deleted')) + end + + def audit_destroy + audit_context = { + name: 'destroyed_compliance_requirement_control', + author: current_user, + scope: control.namespace, + target: control, + message: "Destroyed compliance requirement control #{control.name}" + } + + ::Gitlab::Audit::Auditor.audit(audit_context) + end + + def error + ServiceResponse.error(message: _('Failed to destroy compliance requirement control'), payload: control.errors) + end + end + end + end +end diff --git a/ee/config/audit_events/types/destroyed_compliance_requirement_control.yml b/ee/config/audit_events/types/destroyed_compliance_requirement_control.yml new file mode 100644 index 00000000000000..71cfa132d5618c --- /dev/null +++ b/ee/config/audit_events/types/destroyed_compliance_requirement_control.yml @@ -0,0 +1,10 @@ +--- +name: destroyed_compliance_requirement_control +description: A compliance requirement control is destroyed. +introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/512381 +introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177557 +milestone: '17.9' +feature_category: compliance_management +saved_to_database: true +streamed: true +scope: [Group] diff --git a/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb b/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb new file mode 100644 index 00000000000000..eef4c1fc5e7290 --- /dev/null +++ b/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Mutations::ComplianceManagement::ComplianceFramework::ComplianceRequirementsControls::Destroy, + feature_category: :compliance_management do + include GraphqlHelpers + + let_it_be(:namespace) { create(:group) } + let_it_be(:requirement) do + create(:compliance_requirement, framework: create(:compliance_framework, namespace: namespace)) + end + + let_it_be(:control) { create(:compliance_requirements_control, compliance_requirement: requirement) } + + let_it_be(:current_user) { create(:user) } + let(:mutation) { described_class.new(object: nil, context: query_context, field: nil) } + + subject { mutation.resolve(id: global_id_of(control)) } + + before_all do + namespace.add_owner(current_user) + end + + shared_examples 'a compliance requirement control that cannot be found' do + it 'raises an error' do + expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) + end + end + + shared_examples 'one compliance requirement control was destroyed' do + it 'destroys a compliance requirement control' do + expect { subject }.to change { + ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.exists?(id: control.id) + }.from(true).to(false) + end + + it 'expects zero errors in the response' do + expect(subject[:errors]).to be_empty + end + end + + context 'when feature is unlicensed' do + before do + stub_licensed_features(custom_compliance_frameworks: false) + end + + it_behaves_like 'a compliance requirement control that cannot be found' + end + + context 'when feature is licensed' do + before do + stub_licensed_features(custom_compliance_frameworks: true) + end + + context 'when current_user is namespace owner' do + it_behaves_like 'one compliance requirement control was destroyed' + end + + context 'when current_user is group owner' do + # let_it_be(:group) { create(:group) } + # let_it_be(:current_user) { create(:user) } + # let_it_be(:requirement) do + # create(:compliance_requirement, framework: create(:compliance_framework, namespace: namespace)) + # end + + before_all do + namespace.add_owner(current_user) + end + + it_behaves_like 'one compliance requirement control was destroyed' + end + end +end diff --git a/ee/spec/requests/api/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb b/ee/spec/requests/api/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb new file mode 100644 index 00000000000000..3989e90d370eb6 --- /dev/null +++ b/ee/spec/requests/api/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Destroy a Compliance Requirement Control', feature_category: :compliance_management do + include GraphqlHelpers + + let_it_be(:namespace) { create(:group) } + let_it_be(:requirement) do + create(:compliance_requirement, framework: create(:compliance_framework, namespace: namespace)) + end + + let_it_be(:control) { create(:compliance_requirements_control, compliance_requirement: requirement) } + + let_it_be(:current_user) { create(:user) } + let(:mutation) { graphql_mutation(:destroy_compliance_requirements_control, { id: global_id_of(control) }) } + + subject(:mutate) { post_graphql_mutation(mutation, current_user: current_user) } + + def mutation_response + graphql_mutation_response(:destroy_compliance_requirements_control) + end + + context 'when feature is unlicensed' do + before do + stub_licensed_features(custom_compliance_frameworks: false) + end + + it 'does not destroy a compliance requirement control' do + expect { mutate }.not_to change { ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.count } + end + + it_behaves_like 'a mutation that returns top-level errors', + errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR] + end + + context 'when licensed' do + before do + stub_licensed_features(custom_compliance_frameworks: true) + end + + context 'when current_user is namespace owner' do + before_all do + namespace.add_owner(current_user) + end + + it 'has no errors' do + mutate + + expect(mutation_response['errors']).to be_empty + end + + it 'destroys a compliance requirement control' do + expect { mutate }.to change { + ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.exists?(id: control.id) + }.from(true).to(false) + end + end + + context 'when current_user is not namespace owner' do + it_behaves_like 'a mutation that returns top-level errors', + errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR] + + it 'does not destroy a compliance requirement control' do + expect { mutate } + .not_to change { ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.count } + end + end + end +end diff --git a/ee/spec/services/compliance_management/compliance_framework/compliance_requirements_controls/destroy_service_spec.rb b/ee/spec/services/compliance_management/compliance_framework/compliance_requirements_controls/destroy_service_spec.rb new file mode 100644 index 00000000000000..18ccd241f189ee --- /dev/null +++ b/ee/spec/services/compliance_management/compliance_framework/compliance_requirements_controls/destroy_service_spec.rb @@ -0,0 +1,114 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ComplianceManagement::ComplianceFramework::ComplianceRequirementsControls::DestroyService, + feature_category: :compliance_management do + let_it_be_with_refind(:namespace) { create(:group) } + let_it_be(:requirement) do + create(:compliance_requirement, framework: create(:compliance_framework, namespace: namespace)) + end + + let_it_be(:control) { create(:compliance_requirements_control, compliance_requirement: requirement) } + let_it_be(:owner) { create(:user, owner_of: namespace) } + let_it_be(:non_owner) { create(:user) } + + shared_examples 'unsuccessful destruction' do |error_message| + it 'does not destroy the compliance requirement control' do + expect { service.execute } + .not_to change { ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.count } + end + + it 'is unsuccessful' do + result = service.execute + + expect(result.success?).to be false + expect(result.message).to eq _(error_message) + end + + it 'does not audit the destruction' do + service.execute + + expect(::Gitlab::Audit::Auditor).not_to have_received(:audit) + end + end + + context 'when feature is disabled' do + before do + stub_licensed_features(custom_compliance_frameworks: false) + allow(::Gitlab::Audit::Auditor).to receive(:audit) + end + + context 'when current user is namespace owner' do + subject(:service) { described_class.new(control: control, current_user: owner) } + + it_behaves_like 'unsuccessful destruction', 'Not permitted to destroy requirement control' + end + + context 'when current user is not the namespace owner' do + subject(:service) { described_class.new(control: control, current_user: non_owner) } + + it_behaves_like 'unsuccessful destruction', 'Not permitted to destroy requirement control' + end + end + + context 'when feature is enabled' do + before do + stub_licensed_features(custom_compliance_frameworks: true) + allow(::Gitlab::Audit::Auditor).to receive(:audit) + end + + context 'when current user is namespace owner' do + subject(:service) { described_class.new(control: control, current_user: owner) } + + it 'destroys the compliance requirement control' do + expect { service.execute }.to change { + ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.exists?(id: control.id) + }.from(true).to(false) + end + + it 'is successful' do + result = service.execute + + expect(result.success?).to be true + expect(result.message).to eq _('Compliance requirement control successfully deleted') + end + + it 'audits the destruction' do + service.execute + + expect(::Gitlab::Audit::Auditor).to have_received(:audit).with( + name: 'destroyed_compliance_requirement_control', + author: owner, + scope: control.namespace, + target: control, + message: "Destroyed compliance requirement control #{control.name}" + ) + end + + context 'when destruction fails' do + before do + allow(control).to receive(:destroy).and_return(false) + end + + it 'is unsuccessful' do + result = service.execute + + expect(result.success?).to be false + expect(result.message).to eq _('Failed to destroy compliance requirement control') + end + end + end + + context 'when current user is not the namespace owner' do + subject(:service) { described_class.new(control: control, current_user: non_owner) } + + it 'does not destroy the compliance requirement control' do + expect { service.execute } + .not_to change { ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.count } + end + + it_behaves_like 'unsuccessful destruction', 'Not permitted to destroy requirement control' + end + end +end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index c051346b11ef85..b8467fb53c2bd2 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -14393,6 +14393,9 @@ msgstr "" msgid "Compliance frameworks" msgstr "" +msgid "Compliance requirement control successfully deleted" +msgstr "" + msgid "Compliance requirement successfully deleted" msgstr "" @@ -23838,6 +23841,9 @@ msgstr "" msgid "Failed to destroy compliance requirement" msgstr "" +msgid "Failed to destroy compliance requirement control" +msgstr "" + msgid "Failed to enqueue the rebase operation, possibly due to a long-lived transaction. Try again later." msgstr "" @@ -37826,6 +37832,9 @@ msgstr "" msgid "Not permitted to destroy requirement" msgstr "" +msgid "Not permitted to destroy requirement control" +msgstr "" + msgid "Not permitted to reset user feed token" msgstr "" -- GitLab From 8877c5decd6d4b5f3f44e666ba805b4341ad7920 Mon Sep 17 00:00:00 2001 From: Hitesh Raghuvanshi Date: Wed, 15 Jan 2025 10:23:36 +0530 Subject: [PATCH 2/6] Updated MR url --- .../types/destroyed_compliance_requirement_control.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ee/config/audit_events/types/destroyed_compliance_requirement_control.yml b/ee/config/audit_events/types/destroyed_compliance_requirement_control.yml index 71cfa132d5618c..da2a413c87d34a 100644 --- a/ee/config/audit_events/types/destroyed_compliance_requirement_control.yml +++ b/ee/config/audit_events/types/destroyed_compliance_requirement_control.yml @@ -2,7 +2,7 @@ name: destroyed_compliance_requirement_control description: A compliance requirement control is destroyed. introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/512381 -introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177557 +introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177878 milestone: '17.9' feature_category: compliance_management saved_to_database: true -- GitLab From a617385551a0e0bbdad85444c3ebdb0dc0c0ca57 Mon Sep 17 00:00:00 2001 From: Hitesh Raghuvanshi Date: Wed, 15 Jan 2025 10:56:00 +0530 Subject: [PATCH 3/6] Updated audit event docs --- doc/user/compliance/audit_event_types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/compliance/audit_event_types.md b/doc/user/compliance/audit_event_types.md index 09a4244d7bb3fc..31c1a4409443b1 100644 --- a/doc/user/compliance/audit_event_types.md +++ b/doc/user/compliance/audit_event_types.md @@ -151,7 +151,7 @@ Audit event types belong to the following product categories. | [`delete_status_check`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84624) | An external status check is deleted | **{check-circle}** Yes | GitLab [15.9](https://gitlab.com/gitlab-org/gitlab/-/issues/355805) | Project | | [`destroy_compliance_framework`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74292) | A compliance framework is successfully deleted | **{check-circle}** Yes | GitLab [14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/340649) | Group | | [`destroyed_compliance_requirement`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/170380) | A compliance framework requirement is destroyed | **{check-circle}** Yes | GitLab [17.7](https://gitlab.com/gitlab-org/gitlab/-/issues/470695) | Group | -| [`destroyed_compliance_requirement_control`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177557) | A compliance requirement control is destroyed. | **{check-circle}** Yes | GitLab [17.9](https://gitlab.com/gitlab-org/gitlab/-/issues/512381) | Group | +| [`destroyed_compliance_requirement_control`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177878) | A compliance requirement control is destroyed. | **{check-circle}** Yes | GitLab [17.9](https://gitlab.com/gitlab-org/gitlab/-/issues/512381) | Group | | [`email_created`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114546) | An email is created | **{check-circle}** Yes | GitLab [15.11](https://gitlab.com/gitlab-org/gitlab/-/issues/374107) | User | | [`email_destroyed`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114546) | An email is destroyed | **{check-circle}** Yes | GitLab [15.11](https://gitlab.com/gitlab-org/gitlab/-/issues/374107) | User | | [`external_status_check_name_updated`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106095) | The name of an external status check is updated | **{check-circle}** Yes | GitLab [15.7](https://gitlab.com/gitlab-org/gitlab/-/issues/369333) | Project | -- GitLab From 7b66000b2a50bcd233700ef750f7177f3326d639 Mon Sep 17 00:00:00 2001 From: Hitesh Raghuvanshi Date: Wed, 15 Jan 2025 08:20:40 +0000 Subject: [PATCH 4/6] Removed commented code --- .../compliance_requirements_controls/destroy_spec.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb b/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb index eef4c1fc5e7290..be2a6469531003 100644 --- a/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb +++ b/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb @@ -58,12 +58,6 @@ end context 'when current_user is group owner' do - # let_it_be(:group) { create(:group) } - # let_it_be(:current_user) { create(:user) } - # let_it_be(:requirement) do - # create(:compliance_requirement, framework: create(:compliance_framework, namespace: namespace)) - # end - before_all do namespace.add_owner(current_user) end -- GitLab From fd942400be2142b0a824babea944ebadd8868624 Mon Sep 17 00:00:00 2001 From: Hitesh Raghuvanshi Date: Thu, 23 Jan 2025 16:44:24 +0530 Subject: [PATCH 5/6] Removed repeated test case --- .../destroy_spec.rb | 36 +++++-------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb b/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb index be2a6469531003..c09ef1151efabc 100644 --- a/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb +++ b/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb @@ -22,30 +22,14 @@ namespace.add_owner(current_user) end - shared_examples 'a compliance requirement control that cannot be found' do - it 'raises an error' do - expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) - end - end - - shared_examples 'one compliance requirement control was destroyed' do - it 'destroys a compliance requirement control' do - expect { subject }.to change { - ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.exists?(id: control.id) - }.from(true).to(false) - end - - it 'expects zero errors in the response' do - expect(subject[:errors]).to be_empty - end - end - context 'when feature is unlicensed' do before do stub_licensed_features(custom_compliance_frameworks: false) end - it_behaves_like 'a compliance requirement control that cannot be found' + it 'raises an error' do + expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) + end end context 'when feature is licensed' do @@ -53,16 +37,14 @@ stub_licensed_features(custom_compliance_frameworks: true) end - context 'when current_user is namespace owner' do - it_behaves_like 'one compliance requirement control was destroyed' + it 'destroys a compliance requirement control' do + expect { subject }.to change { + ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.exists?(id: control.id) + }.from(true).to(false) end - context 'when current_user is group owner' do - before_all do - namespace.add_owner(current_user) - end - - it_behaves_like 'one compliance requirement control was destroyed' + it 'expects zero errors in the response' do + expect(subject[:errors]).to be_empty end end end -- GitLab From 80d9f513e37d95df358298d4ad55706fcccf9496 Mon Sep 17 00:00:00 2001 From: Hitesh Raghuvanshi Date: Mon, 27 Jan 2025 19:32:01 +0530 Subject: [PATCH 6/6] Fixed rubocop issues in spec --- .../compliance_requirements_controls/destroy_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb b/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb index c09ef1151efabc..952a3e03319a70 100644 --- a/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb +++ b/ee/spec/graphql/mutations/compliance_management/compliance_framework/compliance_requirements_controls/destroy_spec.rb @@ -16,7 +16,7 @@ let_it_be(:current_user) { create(:user) } let(:mutation) { described_class.new(object: nil, context: query_context, field: nil) } - subject { mutation.resolve(id: global_id_of(control)) } + subject(:mutate) { mutation.resolve(id: global_id_of(control)) } before_all do namespace.add_owner(current_user) @@ -28,7 +28,7 @@ end it 'raises an error' do - expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) + expect { mutate }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) end end @@ -38,13 +38,13 @@ end it 'destroys a compliance requirement control' do - expect { subject }.to change { + expect { mutate }.to change { ComplianceManagement::ComplianceFramework::ComplianceRequirementsControl.exists?(id: control.id) }.from(true).to(false) end it 'expects zero errors in the response' do - expect(subject[:errors]).to be_empty + expect(mutate[:errors]).to be_empty end end end -- GitLab