Commit c1cdae05 authored by Jan Provaznik's avatar Jan Provaznik

Merge branch 'prevent-delete-groups-with-subscription' into 'master'

Disable Remove Group Button for Group with Subscription

See merge request gitlab-org/gitlab!57170
parents 0673d411 079bb4e2
...@@ -343,6 +343,10 @@ class Namespace < ApplicationRecord ...@@ -343,6 +343,10 @@ class Namespace < ApplicationRecord
Plan.default Plan.default
end end
def paid?
root? && actual_plan.paid?
end
def actual_limits def actual_limits
# We default to PlanLimits.new otherwise a lot of specs would fail # We default to PlanLimits.new otherwise a lot of specs would fail
# On production each plan should already have associated limits record # On production each plan should already have associated limits record
......
...@@ -5,4 +5,5 @@ ...@@ -5,4 +5,5 @@
= _('Removing this group also removes all child projects, including archived projects, and their resources.') = _('Removing this group also removes all child projects, including archived projects, and their resources.')
%br %br
%strong= _('Removed group can not be restored!') %strong= _('Removed group can not be restored!')
= button_to _('Remove group'), '#', class: 'btn gl-button btn-danger js-confirm-danger', data: { 'confirm-danger-message' => remove_group_message(group) }
= render 'groups/settings/remove_button', group: group
- if group.paid?
.gl-alert.gl-alert-info.gl-mb-5{ data: { testid: 'group-has-linked-subscription-alert' } }
= sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
.gl-alert-body
= html_escape(_("This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group.")) % { linkStart: "<a href=\"#{help_page_path('subscriptions/index', anchor: 'change-the-linked-namespace')}\">".html_safe, linkEnd: '</a>'.html_safe }
= button_to _('Remove group'), '#', class: ['btn gl-button btn-danger js-confirm-danger', ('disabled' if group.paid?)], data: { 'confirm-danger-message' => remove_group_message(group), 'testid' => 'remove-group-button' }
...@@ -11,6 +11,7 @@ module EE ...@@ -11,6 +11,7 @@ module EE
alias_method :ee_authorize_admin_group!, :authorize_admin_group! alias_method :ee_authorize_admin_group!, :authorize_admin_group!
before_action :ee_authorize_admin_group!, only: [:restore] before_action :ee_authorize_admin_group!, only: [:restore]
before_action :check_subscription!, only: [:destroy]
feature_category :subgroups, [:restore] feature_category :subgroups, [:restore]
end end
...@@ -58,6 +59,14 @@ module EE ...@@ -58,6 +59,14 @@ module EE
private private
def check_subscription!
if group.paid?
redirect_to edit_group_path(group),
status: :found,
alert: _('This group is linked to a subscription')
end
end
def group_params_ee def group_params_ee
[ [
:membership_lock, :membership_lock,
......
...@@ -10,4 +10,4 @@ ...@@ -10,4 +10,4 @@
%li= _("The group will be placed in 'pending removal' state") %li= _("The group will be placed in 'pending removal' state")
%li= _("The group can be fully restored") %li= _("The group can be fully restored")
= button_to _('Remove group'), '#', class: 'gl-button btn btn-danger js-confirm-danger', data: { 'confirm-danger-message' => remove_group_message(group) } = render 'groups/settings/remove_button', group: group
---
title: Prevent deletion of groups with a subscription
merge_request: 57170
author:
type: fixed
...@@ -768,6 +768,22 @@ RSpec.describe Namespace do ...@@ -768,6 +768,22 @@ RSpec.describe Namespace do
end end
end end
describe '#paid?' do
it 'returns true for a root namespace with a paid plan' do
create(:gitlab_subscription, :ultimate, namespace: namespace)
expect(namespace.paid?).to eq(true)
end
it 'returns false for a subgroup of a group with a paid plan' do
group = create(:group)
subgroup = create(:group, parent: group)
create(:gitlab_subscription, :ultimate, namespace: group)
expect(subgroup.paid?).to eq(false)
end
end
describe '#actual_plan_name' do describe '#actual_plan_name' do
context 'when namespace does not have a subscription associated' do context 'when namespace does not have a subscription associated' do
it 'returns default plan' do it 'returns default plan' do
......
...@@ -334,4 +334,30 @@ RSpec.describe GroupsController, type: :request do ...@@ -334,4 +334,30 @@ RSpec.describe GroupsController, type: :request do
end end
end end
end end
describe 'DELETE #destroy' do
before do
group.add_owner(user)
login_as(user)
end
it 'does not delete a group with a gitlab.com subscription' do
create(:gitlab_subscription, :ultimate, namespace: group)
Sidekiq::Testing.fake! do
expect { delete(group_path(group)) }.not_to change(GroupDestroyWorker.jobs, :size)
expect(response).to redirect_to(edit_group_path(group))
end
end
it 'deletes a subgroup with a parent group with a gitlab.com subscription' do
create(:gitlab_subscription, :ultimate, namespace: group)
subgroup = create(:group, parent: group)
Sidekiq::Testing.fake! do
expect { delete(group_path(subgroup)) }.to change(GroupDestroyWorker.jobs, :size).by(1)
expect(response).to redirect_to(root_path)
end
end
end
end end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'groups/settings/_remove.html.haml' do
describe 'render' do
let(:group) { create(:group) }
it 'enables the Remove group button and does not show an alert for a group' do
render 'groups/settings/remove', group: group
expect(rendered).to have_selector '[data-testid="remove-group-button"]'
expect(rendered).not_to have_selector '[data-testid="remove-group-button"].disabled'
expect(rendered).not_to have_selector '[data-testid="group-has-linked-subscription-alert"]'
end
it 'disables the Remove group button and shows an alert for a group with a paid gitlab.com plan' do
create(:gitlab_subscription, :ultimate, namespace: group)
render 'groups/settings/remove', group: group
expect(rendered).to have_selector '[data-testid="remove-group-button"].disabled'
expect(rendered).to have_selector '[data-testid="group-has-linked-subscription-alert"]'
end
it 'disables the Remove group button and shows an alert for a group with a legacy paid gitlab.com plan' do
create(:gitlab_subscription, :gold, namespace: group)
render 'groups/settings/remove', group: group
expect(rendered).to have_selector '[data-testid="remove-group-button"].disabled'
expect(rendered).to have_selector '[data-testid="group-has-linked-subscription-alert"]'
end
it 'enables the Remove group button and does not show an alert for a subgroup' do
create(:gitlab_subscription, :ultimate, namespace: group)
subgroup = create(:group, parent: group)
render 'groups/settings/remove', group: subgroup
expect(rendered).to have_selector '[data-testid="remove-group-button"]'
expect(rendered).not_to have_selector '[data-testid="remove-group-button"].disabled'
expect(rendered).not_to have_selector '[data-testid="group-has-linked-subscription-alert"]'
end
context 'when delayed deletes are enabled' do
before do
stub_licensed_features(adjourned_deletion_for_projects_and_groups: true)
end
it 'enables the Remove group button and does not show an alert for a group without a paid gitlab.com plan' do
render 'groups/settings/remove', group: group
expect(rendered).to have_selector '[data-testid="remove-group-button"]'
expect(rendered).not_to have_selector '[data-testid="remove-group-button"].disabled'
expect(rendered).not_to have_selector '[data-testid="group-has-linked-subscription-alert"]'
end
it 'disables the Remove group button and shows an alert for a group with a paid gitlab.com plan' do
create(:gitlab_subscription, :ultimate, namespace: group)
render 'groups/settings/remove', group: group
expect(rendered).to have_selector '[data-testid="remove-group-button"].disabled'
expect(rendered).to have_selector '[data-testid="group-has-linked-subscription-alert"]'
end
it 'enables the Remove group button and does not show an alert for a subgroup' do
create(:gitlab_subscription, :ultimate, namespace: group)
subgroup = create(:group, parent: group)
render 'groups/settings/remove', group: subgroup
expect(rendered).to have_selector '[data-testid="remove-group-button"]'
expect(rendered).not_to have_selector '[data-testid="remove-group-button"].disabled'
expect(rendered).not_to have_selector '[data-testid="group-has-linked-subscription-alert"]'
end
end
end
end
...@@ -31064,6 +31064,9 @@ msgstr "" ...@@ -31064,6 +31064,9 @@ msgstr ""
msgid "This group" msgid "This group"
msgstr "" msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO" msgid "This group cannot be invited to a project inside a group with enforced SSO"
msgstr "" msgstr ""
...@@ -31073,6 +31076,9 @@ msgstr "" ...@@ -31073,6 +31076,9 @@ msgstr ""
msgid "This group has been scheduled for permanent removal on %{date}" msgid "This group has been scheduled for permanent removal on %{date}"
msgstr "" msgstr ""
msgid "This group is linked to a subscription"
msgstr ""
msgid "This group, including all subgroups, projects and git repositories, will be reachable from only the specified IP address ranges." msgid "This group, including all subgroups, projects and git repositories, will be reachable from only the specified IP address ranges."
msgstr "" msgstr ""
......
...@@ -1415,6 +1415,12 @@ RSpec.describe Namespace do ...@@ -1415,6 +1415,12 @@ RSpec.describe Namespace do
end end
end end
describe '#paid?' do
it 'returns false for a root namespace with a free plan' do
expect(namespace.paid?).to eq(false)
end
end
describe '#shared_runners_setting' do describe '#shared_runners_setting' do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'groups/settings/_remove.html.haml' do
describe 'render' do
it 'enables the Remove group button for a group' do
group = build(:group)
render 'groups/settings/remove', group: group
expect(rendered).to have_selector '[data-testid="remove-group-button"]'
expect(rendered).not_to have_selector '[data-testid="remove-group-button"].disabled'
expect(rendered).not_to have_selector '[data-testid="group-has-linked-subscription-alert"]'
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment