From 754df1ea61f69b34d4f296fe0f7c91c49378008a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=B7=AF=E5=B0=8F=E9=B9=BF?= <1551755561@qq.com>
Date: Mon, 16 Dec 2024 22:20:27 +0800
Subject: [PATCH] Fix spec of RepositoryLimit::LimitAlertComponent

---
 .../limit_alert_component_spec.rb             | 199 ++++++++++++++++++
 1 file changed, 199 insertions(+)
 create mode 100644 jh/spec/components/namespaces/storage/repository_limit/limit_alert_component_spec.rb

diff --git a/jh/spec/components/namespaces/storage/repository_limit/limit_alert_component_spec.rb b/jh/spec/components/namespaces/storage/repository_limit/limit_alert_component_spec.rb
new file mode 100644
index 000000000000..d603ee15648d
--- /dev/null
+++ b/jh/spec/components/namespaces/storage/repository_limit/limit_alert_component_spec.rb
@@ -0,0 +1,199 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe Namespaces::Storage::RepositoryLimit::LimitAlertComponent, :saas, type: :component, feature_category: :consumables_cost_management do
+  let(:group) { build_stubbed(:group) }
+  let(:project_over_limit) { build_stubbed(:project, namespace: group) }
+  let(:project_under_limit) { build_stubbed(:project, namespace: group) }
+  let(:user) { build_stubbed(:user) }
+  let(:alert_title) { /You have used \d+% of the purchased storage for #{group.name}/ }
+  let(:alert_title_over_storage_limit) { "You have used all available storage for #{group.name}" }
+  let(:alert_title_free_tier) { "You have reached the free storage limit of 10 GiB on 1 project" }
+
+  let(:alert_message_below_limit) do
+    "If a project reaches 100% of the storage quota (10 GiB) the project will be in a read-only state, " \
+      "and you won't be able to push to your repository or add large files. To reduce storage usage, " \
+      "reduce git repository and git LFS storage. For more information about storage limits, see our FAQ."
+  end
+
+  let(:alert_message_above_limit_no_purchased_storage) do
+    "You have consumed all available storage and you can't push or add large files to projects over the " \
+      "free tier limit (10 GiB). To remove the read-only state, reduce git repository and git LFS storage, " \
+      "or purchase more storage. For more information about storage limits, see our FAQ."
+  end
+
+  let(:alert_message_above_limit_with_purchased_storage) do
+    "You have consumed all available storage and you can't push or add large files to projects over the " \
+      "free tier limit (10 GiB). To remove the read-only state, reduce git repository and git LFS storage, " \
+      "or purchase more storage. For more information about storage limits, see our FAQ."
+  end
+
+  let(:alert_message_non_owner_copy) do
+    "contact a user with the owner role for this namespace and ask them to purchase more storage"
+  end
+
+  before do
+    allow(group).to receive(:actual_plan).and_return(::Plan.free)
+  end
+
+  subject(:component) { described_class.new(context: project_over_limit, user: user) }
+
+  describe 'repository enforcement' do
+    before do
+      stub_ee_application_setting(repository_size_limit: 10.gigabytes)
+      stub_ee_application_setting(should_check_namespace_plan: true)
+      stub_ee_application_setting(automatic_purchased_storage_allocation: true)
+      stub_feature_flags(namespace_storage_limit: false)
+
+      allow(Ability).to receive(:allowed?).with(user, :owner_access, group).and_return(true)
+      allow(Ability).to receive(:allowed?).with(user, :owner_access, project_over_limit).and_return(true)
+      allow(Ability).to receive(:allowed?).with(user, :read_limit_alert, project_over_limit).and_return(true)
+
+      allow(project_over_limit).to receive(:repository_size_excess).and_return(1)
+    end
+
+    context 'when namespace has no additional storage and is above size limit' do
+      before do
+        allow(group).to receive_messages(repository_size_excess_project_count: 1, additional_purchased_storage_size: 0)
+        allow_next_instance_of(::Namespaces::Storage::RootExcessSize) do |size_checker|
+          allow(size_checker).to receive_messages(usage_ratio: 1, above_size_limit?: true)
+        end
+      end
+
+      it 'renders the alert title' do
+        render_inline(component)
+        expect(page).to have_content(alert_title_free_tier)
+      end
+
+      it 'renders the alert message' do
+        render_inline(component)
+        expect(page).to have_content(alert_message_above_limit_no_purchased_storage)
+      end
+
+      it 'renders the correct callout data' do
+        render_inline(component)
+        expect(page).to have_css("[data-feature-id='project_repository_limit_alert_error_threshold']")
+        expect(page).to have_css("[data-dismiss-endpoint='#{group_callouts_path}']")
+        expect(page).to have_css("[data-group-id='#{group.root_ancestor.id}']")
+      end
+    end
+
+    context 'when namespace has additional storage' do
+      context 'and under storage size limit' do
+        before do
+          allow(group).to receive(:additional_purchased_storage_size).and_return(1)
+          allow_next_instance_of(::Namespaces::Storage::RootExcessSize) do |size_checker|
+            allow(size_checker).to receive(:usage_ratio).and_return(0.75)
+          end
+        end
+
+        it 'renders the alert title' do
+          render_inline(component)
+          expect(page).to have_content(alert_title)
+        end
+
+        it 'renders the alert message' do
+          render_inline(component)
+          expect(page).to have_content(alert_message_below_limit)
+        end
+      end
+
+      context 'and above storage size limit' do
+        before do
+          allow(group).to receive(:additional_purchased_storage_size).and_return(1)
+          allow_next_instance_of(::Namespaces::Storage::RootExcessSize) do |size_checker|
+            allow(size_checker).to receive_messages(usage_ratio: 1, above_size_limit?: true)
+          end
+        end
+
+        it 'renders the alert title' do
+          render_inline(component)
+          expect(page).to have_content(alert_title_over_storage_limit)
+        end
+
+        it 'renders the alert message' do
+          render_inline(component)
+          expect(page).to have_content(alert_message_above_limit_with_purchased_storage)
+        end
+      end
+    end
+
+    context 'when user is not an owner' do
+      before do
+        allow(Ability).to receive(:allowed?).with(user, :owner_access, group).and_return(false)
+        allow(Ability).to receive(:allowed?).with(user, :owner_access, project_over_limit).and_return(false)
+        allow_next_instance_of(::Namespaces::Storage::RootExcessSize) do |size_checker|
+          allow(size_checker).to receive_messages(usage_ratio: 1, above_size_limit?: true)
+        end
+      end
+
+      it 'renders the non-owner copy' do
+        render_inline(component)
+        expect(page).to have_content(alert_message_non_owner_copy)
+      end
+    end
+
+    context 'when project is not over limit' do
+      subject(:component) { described_class.new(context: project_under_limit, user: user) }
+
+      before do
+        allow(project_under_limit).to receive(:repository_size_excess).and_return(0)
+
+        allow(Ability).to receive(:allowed?).with(user, :owner_access, project_under_limit).and_return(true)
+        allow(Ability).to receive(:allowed?).with(user, :read_limit_alert, project_under_limit).and_return(true)
+        allow(group).to receive_messages(repository_size_excess_project_count: 1, additional_purchased_storage_size: 0)
+        allow_next_instance_of(::Namespaces::Storage::RootExcessSize) do |size_checker|
+          allow(size_checker).to receive_messages(usage_ratio: 1, above_size_limit?: true)
+        end
+      end
+
+      it 'does not render the alert' do
+        render_inline(component)
+        expect(page).not_to have_content(alert_title_free_tier)
+      end
+    end
+
+    context 'when context is a group' do
+      subject(:component) { described_class.new(context: group, user: user) }
+
+      before do
+        root_storage_size = ::Namespaces::Storage::RootExcessSize.new(group)
+
+        allow(root_storage_size).to receive_messages(usage_ratio: 1, above_size_limit?: true)
+        allow(group).to receive_messages(repository_size_excess_project_count: 1, additional_purchased_storage_size: 0)
+        allow(group.root_ancestor).to receive(:root_storage_size).and_return(root_storage_size)
+
+        allow(Ability).to receive(:allowed?).with(user, :owner_access, group).and_return(true)
+        allow(Ability).to receive(:allowed?).with(user, :owner_access, group).and_return(true)
+        allow(Ability).to receive(:allowed?).with(user, :read_limit_alert, group).and_return(true)
+      end
+
+      it 'does not render the alert' do
+        render_inline(component)
+        expect(page).not_to have_content(alert_title_free_tier)
+      end
+
+      context 'when group is a user namespace' do
+        let(:group) { build_stubbed(:user_namespace) }
+
+        it 'renders the alert' do
+          render_inline(component)
+          expect(page).to have_content(alert_title_free_tier)
+        end
+      end
+
+      context 'when in group usage quotas page' do
+        before do
+          allow(component).to receive(:current_page?)
+            .with(group_usage_quotas_path(group)).and_return(true)
+        end
+
+        it 'renders the alert' do
+          render_inline(component)
+          expect(page).to have_content(alert_title_free_tier)
+        end
+      end
+    end
+  end
+end
-- 
GitLab