From 94a7a6cf3f1f84beb102ad19851fe25654f4f845 Mon Sep 17 00:00:00 2001 From: Harsh Date: Fri, 5 Sep 2025 17:55:46 +0530 Subject: [PATCH 1/4] Refactor TrialDurationService to use Rails.cache Replace ReactiveCaching with Rails.cache for simpler caching. Adds race_condition_ttl to prevent cache stampede while preserving all existing functionality and fallback behavior. Changelog: changed EE: true --- .../trial_duration_service.rb | 22 +++--------- .../trial_duration_service_spec.rb | 35 ++++++++++++++++--- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/ee/app/services/gitlab_subscriptions/trial_duration_service.rb b/ee/app/services/gitlab_subscriptions/trial_duration_service.rb index aca3f3ad2e66f8..865bf68167178e 100644 --- a/ee/app/services/gitlab_subscriptions/trial_duration_service.rb +++ b/ee/app/services/gitlab_subscriptions/trial_duration_service.rb @@ -2,7 +2,8 @@ module GitlabSubscriptions class TrialDurationService - include ReactiveCaching + CACHE_EXPIRY = 1.hour + CACHE_KEY = 'gitlab_subscriptions_trial_duration_service' DEFAULT_DURATIONS = { GitlabSubscriptions::Trials::FREE_TRIAL_TYPE => { duration_days: 30 }, @@ -11,12 +12,6 @@ class TrialDurationService attr_reader :trial_type - self.reactive_cache_key = ->(_record) { model_name.singular } - self.reactive_cache_refresh_interval = 1.hour - self.reactive_cache_lifetime = 1.hour - self.reactive_cache_work_type = :external_dependency - self.reactive_cache_worker_finder = ->(trial_type, *_args) { new(trial_type) } - def initialize(trial_type = GitlabSubscriptions::Trials::FREE_TRIAL_TYPE) @trial_type = trial_type end @@ -32,25 +27,18 @@ def execute duration[:duration_days] end - # Required for ReactiveCaching - def id - trial_type - end - private def find_trial_types - with_reactive_cache { |data| data } || {} + Rails.cache.fetch(CACHE_KEY, expires_in: CACHE_EXPIRY, race_condition_ttl: 30.seconds) do + trial_types_request + end || {} end def default_duration DEFAULT_DURATIONS[trial_type] || DEFAULT_DURATIONS[GitlabSubscriptions::Trials::FREE_TRIAL_TYPE] end - def calculate_reactive_cache - trial_types_request - end - def client Gitlab::SubscriptionPortal::Client end diff --git a/ee/spec/services/gitlab_subscriptions/trial_duration_service_spec.rb b/ee/spec/services/gitlab_subscriptions/trial_duration_service_spec.rb index d3f841b653ace9..1e80a0c1dfdebc 100644 --- a/ee/spec/services/gitlab_subscriptions/trial_duration_service_spec.rb +++ b/ee/spec/services/gitlab_subscriptions/trial_duration_service_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe GitlabSubscriptions::TrialDurationService, feature_category: :acquisition do - describe '#execute', :saas, :sidekiq_inline, :use_clean_rails_memory_store_caching do + describe '#execute', :saas, :use_clean_rails_memory_store_caching do let_it_be(:free_duration) { 1 } let_it_be(:premium_duration) { 2 } let_it_be(:premium_next_duration) { 3 } @@ -44,14 +44,41 @@ allow(Gitlab::SubscriptionPortal::Client).to receive(:namespace_trial_types).and_return(response) end - it 'returns default duration, makes a request, caches it, and returns correct duration on the next execution' do - expect(service.execute).to eq(default_free_duration) # first execution to spawn the worker + it 'makes a request, caches it, and returns correct duration' do + expect(Gitlab::SubscriptionPortal::Client).to receive(:namespace_trial_types).once.and_return(response) expect(service.execute).to eq(free_duration) end + it 'uses cache on subsequent calls' do + service.execute + + expect(Gitlab::SubscriptionPortal::Client).not_to receive(:namespace_trial_types) + expect(service.execute).to eq(free_duration) + end + + it 'uses Rails cache with correct key and expiry' do + expect(Rails.cache).to receive(:fetch) + .with('gitlab_subscriptions_trial_duration_service', expires_in: 1.hour, race_condition_ttl: 30.seconds) + .and_call_original + + service.execute + end + + context 'when cache fails' do + before do + allow(Rails.cache).to receive(:fetch) + .with('gitlab_subscriptions_trial_duration_service', expires_in: 1.hour, race_condition_ttl: 30.seconds) + .and_return(nil) + end + + it 'falls back to empty hash and returns default duration' do + expect(service.execute).to eq(default_free_duration) + end + end + context 'when trial type is specified' do before do - service.execute # first execution to spawn the worker + service.execute # first execution to populate cache end subject(:service) { described_class.new(trial_type) } -- GitLab From 66ab919fd936fa08b2488acbf97a935777df22f2 Mon Sep 17 00:00:00 2001 From: Harsh Date: Mon, 8 Sep 2025 14:39:15 +0530 Subject: [PATCH 2/4] Add SubscriptionPortalStubHelpers to prevent HTTP calls in EE tests - Create new SubscriptionPortalStubHelpers module to stub subscription portal API calls in test environment - Add stub_subscription_portal_trial_types helper method with support for custom trial types and API failure simulation - Include helper in 9 EE spec files to prevent real HTTP requests during test execution - Replace direct Gitlab::SubscriptionPortal::Client stubbing with centralized helper method in TrialDurationService spec This ensures tests run reliably without external dependencies and provides consistent stubbing behavior across the EE test suite. Changelog: added EE: true --- .../ultimate_component_spec.rb | 2 + .../enforcement_alert_component_spec.rb | 3 ++ ...forcement_at_limit_alert_component_spec.rb | 3 ++ ee/spec/helpers/ee/groups_helper_spec.rb | 2 + .../trials_helper_spec.rb | 5 ++ .../registrations/company_helper_spec.rb | 2 + .../namespaces/free_user_cap_mailer_spec.rb | 2 + .../trial_registrations_controller_spec.rb | 2 + .../trial_duration_service_spec.rb | 7 ++- .../subscription_portal_stub_helpers.rb | 47 +++++++++++++++++++ 10 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 ee/spec/support/helpers/subscription_portal_stub_helpers.rb diff --git a/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/ultimate_component_spec.rb b/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/ultimate_component_spec.rb index d56ffeeb13b400..596ecbf7e0904b 100644 --- a/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/ultimate_component_spec.rb +++ b/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/ultimate_component_spec.rb @@ -4,6 +4,7 @@ RSpec.describe GitlabSubscriptions::DuoEnterpriseAlert::UltimateComponent, :saas, :aggregate_failures, type: :component, feature_category: :acquisition do + include SubscriptionPortalStubHelpers let(:namespace) { build(:group, id: non_existing_record_id) } let(:user) { build(:user) } let(:title) { 'Introducing GitLab Duo Enterprise' } @@ -14,6 +15,7 @@ before do build(:gitlab_subscription, :ultimate, namespace: namespace) + stub_subscription_portal_trial_types end context 'when gold plan' do diff --git a/ee/spec/components/namespaces/free_user_cap/enforcement_alert_component_spec.rb b/ee/spec/components/namespaces/free_user_cap/enforcement_alert_component_spec.rb index 7626b9ad803d30..7e595d08ad4685 100644 --- a/ee/spec/components/namespaces/free_user_cap/enforcement_alert_component_spec.rb +++ b/ee/spec/components/namespaces/free_user_cap/enforcement_alert_component_spec.rb @@ -4,6 +4,7 @@ RSpec.describe Namespaces::FreeUserCap::EnforcementAlertComponent, :saas, :aggregate_failures, type: :component, feature_category: :seat_cost_management do + include SubscriptionPortalStubHelpers let_it_be(:namespace, reload: true) { create(:group) } let_it_be(:user, refind: true) { create(:user) } let(:content_class) { '_content_class_' } @@ -21,6 +22,8 @@ allow_next_instance_of(::Namespaces::FreeUserCap::Enforcement) do |free_user_cap| allow(free_user_cap).to receive(:over_limit?).and_return(free_user_cap_over_limit?) end + + stub_subscription_portal_trial_types end context 'when user is authorized to see alert' do diff --git a/ee/spec/components/namespaces/free_user_cap/enforcement_at_limit_alert_component_spec.rb b/ee/spec/components/namespaces/free_user_cap/enforcement_at_limit_alert_component_spec.rb index ce461de8194f4f..b04676c6ad0cb3 100644 --- a/ee/spec/components/namespaces/free_user_cap/enforcement_at_limit_alert_component_spec.rb +++ b/ee/spec/components/namespaces/free_user_cap/enforcement_at_limit_alert_component_spec.rb @@ -4,6 +4,7 @@ RSpec.describe Namespaces::FreeUserCap::EnforcementAtLimitAlertComponent, :saas, :aggregate_failures, type: :component, feature_category: :seat_cost_management do + include SubscriptionPortalStubHelpers let(:namespace) { build_stubbed(:group) } let(:content_class) { '_content_class_' } let(:user) { build_stubbed(:user) } @@ -26,6 +27,8 @@ allow(Ability).to receive(:allowed?) .with(user, :owner_access, namespace) .and_return(owner_access?) + + stub_subscription_portal_trial_types end context 'when user is authorized to see alert' do diff --git a/ee/spec/helpers/ee/groups_helper_spec.rb b/ee/spec/helpers/ee/groups_helper_spec.rb index 4c28f571a91437..eee60e2caef92e 100644 --- a/ee/spec/helpers/ee/groups_helper_spec.rb +++ b/ee/spec/helpers/ee/groups_helper_spec.rb @@ -4,6 +4,7 @@ RSpec.describe GroupsHelper, feature_category: :source_code_management do using RSpec::Parameterized::TableSyntax + include SubscriptionPortalStubHelpers let(:owner) { create(:user, group_view: :security_dashboard) } let(:current_user) { owner } @@ -262,6 +263,7 @@ before do stub_ee_application_setting(dashboard_limit: 10) + stub_subscription_portal_trial_types expect_next_instance_of(::Namespaces::FreeUserCap::Enforcement, group) do |instance| expect(instance).to receive(:enforce_cap?).and_return(enforcement_free_user_cap) diff --git a/ee/spec/helpers/gitlab_subscriptions/trials_helper_spec.rb b/ee/spec/helpers/gitlab_subscriptions/trials_helper_spec.rb index 0e24d3e0261d7f..35cda18471ab16 100644 --- a/ee/spec/helpers/gitlab_subscriptions/trials_helper_spec.rb +++ b/ee/spec/helpers/gitlab_subscriptions/trials_helper_spec.rb @@ -5,6 +5,7 @@ RSpec.describe GitlabSubscriptions::TrialsHelper, feature_category: :acquisition do using RSpec::Parameterized::TableSyntax include Devise::Test::ControllerHelpers + include SubscriptionPortalStubHelpers describe '#show_tier_badge_for_new_trial?' do where(:trials_available?, :paid?, :private?, :never_had_trial?, :authorized, :result) do @@ -47,6 +48,10 @@ describe '#trial_duration' do let(:trial_duration) { 30 } + before do + stub_subscription_portal_trial_types + end + subject { helper.trial_duration } it { is_expected.to eq(trial_duration) } diff --git a/ee/spec/helpers/registrations/company_helper_spec.rb b/ee/spec/helpers/registrations/company_helper_spec.rb index 6c1afc96669542..ebbcb55c56f388 100644 --- a/ee/spec/helpers/registrations/company_helper_spec.rb +++ b/ee/spec/helpers/registrations/company_helper_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' RSpec.describe Registrations::CompanyHelper, feature_category: :onboarding do + include SubscriptionPortalStubHelpers describe '#create_company_form_data' do let(:user) { build_stubbed(:user, onboarding_status_registration_type: 'trial') } let(:trial_duration) { 30 } @@ -18,6 +19,7 @@ before do allow(helper).to receive_messages(params: params, current_user: user) + stub_subscription_portal_trial_types end subject(:form_data) { helper.create_company_form_data(::Onboarding::StatusPresenter.new({}, {}, user)) } diff --git a/ee/spec/mailers/namespaces/free_user_cap_mailer_spec.rb b/ee/spec/mailers/namespaces/free_user_cap_mailer_spec.rb index 542b258df7ee7f..907785e7f3cc92 100644 --- a/ee/spec/mailers/namespaces/free_user_cap_mailer_spec.rb +++ b/ee/spec/mailers/namespaces/free_user_cap_mailer_spec.rb @@ -4,6 +4,7 @@ RSpec.describe Namespaces::FreeUserCapMailer, feature_category: :seat_cost_management do include EmailSpec::Matchers + include SubscriptionPortalStubHelpers describe '#over_limit_email' do let(:namespace) { build(:namespace) } @@ -13,6 +14,7 @@ it 'creates an email message namespace being over free user cap', :aggregate_failures do stub_ee_application_setting(dashboard_limit: 5) + stub_subscription_portal_trial_types result = format( s_('FreeUserCap|Action required: %{namespace_name} group has been placed into a read-only state'), diff --git a/ee/spec/requests/trial_registrations_controller_spec.rb b/ee/spec/requests/trial_registrations_controller_spec.rb index bd4844944385e3..33253c286c33b7 100644 --- a/ee/spec/requests/trial_registrations_controller_spec.rb +++ b/ee/spec/requests/trial_registrations_controller_spec.rb @@ -4,11 +4,13 @@ RSpec.describe TrialRegistrationsController, :with_current_organization, feature_category: :onboarding do include FullNameHelper + include SubscriptionPortalStubHelpers let(:onboarding_enabled?) { true } before do stub_saas_features(onboarding: onboarding_enabled?) + stub_subscription_portal_trial_types end describe 'GET new' do diff --git a/ee/spec/services/gitlab_subscriptions/trial_duration_service_spec.rb b/ee/spec/services/gitlab_subscriptions/trial_duration_service_spec.rb index 1e80a0c1dfdebc..9f67d362cbd6b5 100644 --- a/ee/spec/services/gitlab_subscriptions/trial_duration_service_spec.rb +++ b/ee/spec/services/gitlab_subscriptions/trial_duration_service_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' RSpec.describe GitlabSubscriptions::TrialDurationService, feature_category: :acquisition do + include SubscriptionPortalStubHelpers describe '#execute', :saas, :use_clean_rails_memory_store_caching do let_it_be(:free_duration) { 1 } let_it_be(:premium_duration) { 2 } @@ -41,7 +42,7 @@ subject(:service) { described_class.new } before do - allow(Gitlab::SubscriptionPortal::Client).to receive(:namespace_trial_types).and_return(response) + stub_subscription_portal_trial_types(trial_types: trial_types) end it 'makes a request, caches it, and returns correct duration' do @@ -111,7 +112,9 @@ end context 'with an unsuccessful CustomersDot query' do - let(:response) { { success: false } } + before do + stub_subscription_portal_trial_types(success: false) + end it { expect(service.execute).to eq(default_free_duration) } diff --git a/ee/spec/support/helpers/subscription_portal_stub_helpers.rb b/ee/spec/support/helpers/subscription_portal_stub_helpers.rb new file mode 100644 index 00000000000000..b32163ce34a72a --- /dev/null +++ b/ee/spec/support/helpers/subscription_portal_stub_helpers.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module SubscriptionPortalStubHelpers + # Stubs the subscription portal client to prevent real HTTP calls in tests + # This is needed because TrialDurationService makes HTTP requests to fetch trial types + # + # @param trial_types [Hash] Custom trial types to return. Defaults to standard trial types. + # @param success [Boolean] Whether the API call should be successful. Defaults to true. + # + # @example Basic usage + # stub_subscription_portal_trial_types + # + # @example Custom trial types + # stub_subscription_portal_trial_types( + # trial_types: { + # 'free' => { duration_days: 14 }, + # 'premium' => { duration_days: 60 } + # } + # ) + # + # @example Simulate API failure + # stub_subscription_portal_trial_types(success: false) + def stub_subscription_portal_trial_types(trial_types: nil, success: true) + default_trial_types = { + GitlabSubscriptions::Trials::FREE_TRIAL_TYPE => { duration_days: 30 }, + GitlabSubscriptions::Trials::DUO_ENTERPRISE_TRIAL_TYPE => { duration_days: 60 } + } + + response = if success + { + success: true, + data: { + trial_types: trial_types || default_trial_types + } + } + else + { + success: false, + data: { + errors: ['API Error'] + } + } + end + + allow(Gitlab::SubscriptionPortal::Client).to receive(:namespace_trial_types).and_return(response) + end +end -- GitLab From 8043620277b8f1f3797df6ff532da1a89ef1656d Mon Sep 17 00:00:00 2001 From: Harsh Date: Tue, 9 Sep 2025 16:42:13 +0530 Subject: [PATCH 3/4] Consolidate subscription portal test helpers Merge SubscriptionPortalStubHelpers into SubscriptionPortalHelpers and rename stub_subscription_portal_trial_types to stub_subscription_trial_types. This reduces code duplication by providing a single location for subscription portal test utilities. --- .../ultimate_component_spec.rb | 4 +- .../enforcement_alert_component_spec.rb | 4 +- ...forcement_at_limit_alert_component_spec.rb | 4 +- .../controllers/ee/groups_controller_spec.rb | 2 + .../features/billings/billing_plans_spec.rb | 1 + .../qrtly_reconciliation_alert_spec.rb | 1 + .../google_analytics_datalayer_spec.rb | 2 + .../features/groups/group_overview_spec.rb | 2 + .../groups/members/list_members_spec.rb | 2 + .../groups/usage_quotas/pipelines_tab_spec.rb | 2 + .../groups/usage_quotas/storage_tab_spec.rb | 1 + ...ty_policy_rules_licence_compliance_spec.rb | 2 + .../projects/members/manage_members_spec.rb | 1 + .../features/projects/show_project_spec.rb | 5 ++ ee/spec/features/projects/show_spec.rb | 6 +++ .../identity_verification_spec.rb | 2 + .../company_information_spec.rb | 2 + ee/spec/helpers/ee/groups_helper_spec.rb | 4 +- .../trials_helper_spec.rb | 4 +- .../registrations/company_helper_spec.rb | 4 +- .../namespaces/free_user_cap_mailer_spec.rb | 4 +- ee/spec/requests/groups/usage_quotas_spec.rb | 2 + .../trial_registrations_controller_spec.rb | 4 +- .../ee/members/create_service_spec.rb | 2 + .../trial_duration_service_spec.rb | 6 +-- .../notify_over_limit_service_spec.rb | 5 ++ .../helpers/subscription_portal_helpers.rb | 44 +++++++++++++++++ .../subscription_portal_stub_helpers.rb | 47 ------------------- .../ultimate_trial_callout_shared_examples.rb | 3 ++ .../groups/billings/index.html.haml_spec.rb | 1 + .../company/new.html.haml_spec.rb | 2 + ...oup_over_limit_notification_worker_spec.rb | 2 + spec/mailers/previews_spec.rb | 2 + .../groups/usage_quotas_controller_spec.rb | 2 + 34 files changed, 115 insertions(+), 66 deletions(-) delete mode 100644 ee/spec/support/helpers/subscription_portal_stub_helpers.rb diff --git a/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/ultimate_component_spec.rb b/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/ultimate_component_spec.rb index 596ecbf7e0904b..6cd5c9ec2a4331 100644 --- a/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/ultimate_component_spec.rb +++ b/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/ultimate_component_spec.rb @@ -4,7 +4,7 @@ RSpec.describe GitlabSubscriptions::DuoEnterpriseAlert::UltimateComponent, :saas, :aggregate_failures, type: :component, feature_category: :acquisition do - include SubscriptionPortalStubHelpers + include SubscriptionPortalHelpers let(:namespace) { build(:group, id: non_existing_record_id) } let(:user) { build(:user) } let(:title) { 'Introducing GitLab Duo Enterprise' } @@ -15,7 +15,7 @@ before do build(:gitlab_subscription, :ultimate, namespace: namespace) - stub_subscription_portal_trial_types + stub_subscription_trial_types end context 'when gold plan' do diff --git a/ee/spec/components/namespaces/free_user_cap/enforcement_alert_component_spec.rb b/ee/spec/components/namespaces/free_user_cap/enforcement_alert_component_spec.rb index 7e595d08ad4685..d7848775c0c8d6 100644 --- a/ee/spec/components/namespaces/free_user_cap/enforcement_alert_component_spec.rb +++ b/ee/spec/components/namespaces/free_user_cap/enforcement_alert_component_spec.rb @@ -4,7 +4,7 @@ RSpec.describe Namespaces::FreeUserCap::EnforcementAlertComponent, :saas, :aggregate_failures, type: :component, feature_category: :seat_cost_management do - include SubscriptionPortalStubHelpers + include SubscriptionPortalHelpers let_it_be(:namespace, reload: true) { create(:group) } let_it_be(:user, refind: true) { create(:user) } let(:content_class) { '_content_class_' } @@ -23,7 +23,7 @@ allow(free_user_cap).to receive(:over_limit?).and_return(free_user_cap_over_limit?) end - stub_subscription_portal_trial_types + stub_subscription_trial_types end context 'when user is authorized to see alert' do diff --git a/ee/spec/components/namespaces/free_user_cap/enforcement_at_limit_alert_component_spec.rb b/ee/spec/components/namespaces/free_user_cap/enforcement_at_limit_alert_component_spec.rb index b04676c6ad0cb3..17d9d078a110fb 100644 --- a/ee/spec/components/namespaces/free_user_cap/enforcement_at_limit_alert_component_spec.rb +++ b/ee/spec/components/namespaces/free_user_cap/enforcement_at_limit_alert_component_spec.rb @@ -4,7 +4,7 @@ RSpec.describe Namespaces::FreeUserCap::EnforcementAtLimitAlertComponent, :saas, :aggregate_failures, type: :component, feature_category: :seat_cost_management do - include SubscriptionPortalStubHelpers + include SubscriptionPortalHelpers let(:namespace) { build_stubbed(:group) } let(:content_class) { '_content_class_' } let(:user) { build_stubbed(:user) } @@ -28,7 +28,7 @@ .with(user, :owner_access, namespace) .and_return(owner_access?) - stub_subscription_portal_trial_types + stub_subscription_trial_types end context 'when user is authorized to see alert' do diff --git a/ee/spec/controllers/ee/groups_controller_spec.rb b/ee/spec/controllers/ee/groups_controller_spec.rb index ffd7b7f24da5ba..8d42b3c912e407 100644 --- a/ee/spec/controllers/ee/groups_controller_spec.rb +++ b/ee/spec/controllers/ee/groups_controller_spec.rb @@ -4,6 +4,7 @@ RSpec.describe GroupsController, :with_current_organization, feature_category: :groups_and_projects do include ExternalAuthorizationServiceHelpers + include SubscriptionPortalHelpers using RSpec::Parameterized::TableSyntax let_it_be(:user) { create(:user, organizations: [current_organization]) } @@ -36,6 +37,7 @@ before do stub_ee_application_setting(dashboard_limit_enabled: true) stub_ee_application_setting(dashboard_limit: 5) + stub_subscription_trial_types end it 'avoids extra user count queries', :request_store do diff --git a/ee/spec/features/billings/billing_plans_spec.rb b/ee/spec/features/billings/billing_plans_spec.rb index 2268c2d85f99bb..e90fb5cb5c7ce7 100644 --- a/ee/spec/features/billings/billing_plans_spec.rb +++ b/ee/spec/features/billings/billing_plans_spec.rb @@ -26,6 +26,7 @@ stub_billing_plans(namespace.id, plan.name, plans_data.to_json) stub_subscription_management_data(namespace.id) stub_temporary_extension_data(namespace.id) + stub_subscription_trial_types sign_in(user) end diff --git a/ee/spec/features/billings/qrtly_reconciliation_alert_spec.rb b/ee/spec/features/billings/qrtly_reconciliation_alert_spec.rb index 98115f04351f83..1f2b7a649cb019 100644 --- a/ee/spec/features/billings/qrtly_reconciliation_alert_spec.rb +++ b/ee/spec/features/billings/qrtly_reconciliation_alert_spec.rb @@ -27,6 +27,7 @@ .to_return(status: 200, body: plans_data.to_json) stub_subscription_management_data(namespace.id) stub_temporary_extension_data(namespace.id) + stub_subscription_trial_types create(:callout, user: user, feature_name: :duo_chat_callout) sign_in(user) end diff --git a/ee/spec/features/google_analytics_datalayer_spec.rb b/ee/spec/features/google_analytics_datalayer_spec.rb index b3433763dd84e6..517af692daaa28 100644 --- a/ee/spec/features/google_analytics_datalayer_spec.rb +++ b/ee/spec/features/google_analytics_datalayer_spec.rb @@ -4,6 +4,7 @@ RSpec.describe 'GitLab.com Google Analytics DataLayer', :saas, :js, feature_category: :application_instrumentation do include JavascriptFormHelper + include SubscriptionPortalHelpers let(:google_tag_manager_id) { 'GTM-WWKMTWS' } let(:new_user) { build(:user) } @@ -13,6 +14,7 @@ before do stub_application_setting(require_admin_approval_after_user_signup: false) stub_config(extra: { google_tag_manager_id: google_tag_manager_id, google_tag_manager_nonce_id: google_tag_manager_id }) + stub_subscription_trial_types end context 'on account sign up pages' do diff --git a/ee/spec/features/groups/group_overview_spec.rb b/ee/spec/features/groups/group_overview_spec.rb index efdf420f52042c..3c889742ad232b 100644 --- a/ee/spec/features/groups/group_overview_spec.rb +++ b/ee/spec/features/groups/group_overview_spec.rb @@ -4,6 +4,7 @@ RSpec.describe 'Group information', :js, :aggregate_failures, feature_category: :groups_and_projects do include BillableMembersHelpers + include SubscriptionPortalHelpers using RSpec::Parameterized::TableSyntax let_it_be(:user) { create(:user) } @@ -16,6 +17,7 @@ before do group.add_member(user, role) sign_in(user) + stub_subscription_trial_types end context 'when the default value of "Group information content" preference is used' do diff --git a/ee/spec/features/groups/members/list_members_spec.rb b/ee/spec/features/groups/members/list_members_spec.rb index bd3f4c75560e88..b55bc254d2ae60 100644 --- a/ee/spec/features/groups/members/list_members_spec.rb +++ b/ee/spec/features/groups/members/list_members_spec.rb @@ -4,6 +4,7 @@ RSpec.describe 'Groups > Members > List members', feature_category: :groups_and_projects do include Features::MembersHelpers include Features::InviteMembersModalHelpers + include SubscriptionPortalHelpers let_it_be(:user1) { create(:user, name: 'John Doe') } let_it_be(:user2) { create(:user, name: 'Mary Jane') } @@ -134,6 +135,7 @@ before do group.add_member(user, role) sign_in(user) + stub_subscription_trial_types end it_behaves_like 'over the free user limit alert' diff --git a/ee/spec/features/groups/usage_quotas/pipelines_tab_spec.rb b/ee/spec/features/groups/usage_quotas/pipelines_tab_spec.rb index c832f1d85ac6bb..4eb5d154aa9d18 100644 --- a/ee/spec/features/groups/usage_quotas/pipelines_tab_spec.rb +++ b/ee/spec/features/groups/usage_quotas/pipelines_tab_spec.rb @@ -20,6 +20,7 @@ stub_signing_key stub_ee_application_setting(should_check_namespace_plan: gitlab_dot_com) stub_subscription_permissions_data(group.id) + stub_subscription_trial_types group.add_owner(user) sign_in(user) @@ -258,6 +259,7 @@ stub_signing_key stub_subscription_permissions_data(group.id, can_add_seats: false) stub_ee_application_setting(should_check_namespace_plan: gitlab_dot_com) + stub_subscription_trial_types group.add_owner(user) sign_in(user) diff --git a/ee/spec/features/groups/usage_quotas/storage_tab_spec.rb b/ee/spec/features/groups/usage_quotas/storage_tab_spec.rb index d1a1649525eca1..93e1b71b15b892 100644 --- a/ee/spec/features/groups/usage_quotas/storage_tab_spec.rb +++ b/ee/spec/features/groups/usage_quotas/storage_tab_spec.rb @@ -19,6 +19,7 @@ stub_application_setting(check_namespace_plan: true) create(:callout, user: user, feature_name: :duo_chat_callout, dismissed_at: Time.current) + stub_subscription_trial_types sign_in(user) end diff --git a/ee/spec/features/merge_request/user_sees_security_policy_rules_licence_compliance_spec.rb b/ee/spec/features/merge_request/user_sees_security_policy_rules_licence_compliance_spec.rb index 8d7ac1a54d72ff..45ee6852445d1a 100644 --- a/ee/spec/features/merge_request/user_sees_security_policy_rules_licence_compliance_spec.rb +++ b/ee/spec/features/merge_request/user_sees_security_policy_rules_licence_compliance_spec.rb @@ -6,6 +6,7 @@ :js, :sidekiq_inline, :use_clean_rails_memory_store_caching, feature_category: :security_policy_management do include Features::SecurityPolicyHelpers + include SubscriptionPortalHelpers let_it_be(:project) { create(:project, :repository) } let(:policy_management_project) { create(:project, :repository, creator: user, namespace: project.namespace) } @@ -15,6 +16,7 @@ before do allow(Gitlab::QueryLimiting::Transaction).to receive(:threshold).and_return(125) + stub_subscription_trial_types sign_in(user) end diff --git a/ee/spec/features/projects/members/manage_members_spec.rb b/ee/spec/features/projects/members/manage_members_spec.rb index 5f45f8b2a61fa2..de0d76f99f0480 100644 --- a/ee/spec/features/projects/members/manage_members_spec.rb +++ b/ee/spec/features/projects/members/manage_members_spec.rb @@ -21,6 +21,7 @@ stub_signing_key stub_reconciliation_request(true) stub_ee_application_setting(dashboard_limit_enabled: true) + stub_subscription_trial_types end context 'when at free user limit' do diff --git a/ee/spec/features/projects/show_project_spec.rb b/ee/spec/features/projects/show_project_spec.rb index 50da0d1a8504ad..d74bddbc6d108f 100644 --- a/ee/spec/features/projects/show_project_spec.rb +++ b/ee/spec/features/projects/show_project_spec.rb @@ -4,9 +4,14 @@ RSpec.describe 'Project show page', :feature, feature_category: :groups_and_projects do include BillableMembersHelpers + include SubscriptionPortalHelpers let_it_be(:user) { create(:user) } + before do + stub_subscription_trial_types + end + describe 'stat button existence' do describe 'populated project' do let(:project) { create(:project, :public, :repository) } diff --git a/ee/spec/features/projects/show_spec.rb b/ee/spec/features/projects/show_spec.rb index f0419438a7c43a..c2cb2c60b98fb2 100644 --- a/ee/spec/features/projects/show_spec.rb +++ b/ee/spec/features/projects/show_spec.rb @@ -3,10 +3,16 @@ require 'spec_helper' RSpec.describe 'Project show page', :js, :saas, feature_category: :groups_and_projects do + include SubscriptionPortalHelpers + let_it_be(:user) { create(:user) } let(:path) { project_path(project) } + before do + stub_subscription_trial_types + end + context "with free tier badge" do let(:tier_badge_selector) { '[data-testid="tier-badge"]' } let(:tier_badge_element) { page.find(tier_badge_selector) } diff --git a/ee/spec/features/registrations/identity_verification_spec.rb b/ee/spec/features/registrations/identity_verification_spec.rb index c11f3a38c4c7b8..ba06ca7b86e572 100644 --- a/ee/spec/features/registrations/identity_verification_spec.rb +++ b/ee/spec/features/registrations/identity_verification_spec.rb @@ -4,6 +4,7 @@ RSpec.describe 'Identity Verification', :js, :with_current_organization, feature_category: :instance_resiliency do include IdentityVerificationHelpers + include SubscriptionPortalHelpers before do stub_saas_features(identity_verification: true) @@ -15,6 +16,7 @@ telesign_customer_xid: 'customer_id', telesign_api_key: 'private_key' ) + stub_subscription_trial_types end let(:user_email) { 'onboardinguser@example.com' } diff --git a/ee/spec/features/trial_registrations/company_information_spec.rb b/ee/spec/features/trial_registrations/company_information_spec.rb index 0027d72d2cd0b5..f8a97462f34d82 100644 --- a/ee/spec/features/trial_registrations/company_information_spec.rb +++ b/ee/spec/features/trial_registrations/company_information_spec.rb @@ -4,6 +4,7 @@ RSpec.describe 'Company Information', :js, feature_category: :activation do include SaasRegistrationHelpers + include SubscriptionPortalHelpers let_it_be(:user) do create(:user, onboarding_in_progress: true, onboarding_status_registration_type: 'trial', @@ -20,6 +21,7 @@ before do stub_saas_features(onboarding: true) + stub_subscription_trial_types sign_in(user) visit new_users_sign_up_company_path diff --git a/ee/spec/helpers/ee/groups_helper_spec.rb b/ee/spec/helpers/ee/groups_helper_spec.rb index eee60e2caef92e..ddf70cddd84e7e 100644 --- a/ee/spec/helpers/ee/groups_helper_spec.rb +++ b/ee/spec/helpers/ee/groups_helper_spec.rb @@ -4,7 +4,7 @@ RSpec.describe GroupsHelper, feature_category: :source_code_management do using RSpec::Parameterized::TableSyntax - include SubscriptionPortalStubHelpers + include SubscriptionPortalHelpers let(:owner) { create(:user, group_view: :security_dashboard) } let(:current_user) { owner } @@ -263,7 +263,7 @@ before do stub_ee_application_setting(dashboard_limit: 10) - stub_subscription_portal_trial_types + stub_subscription_trial_types expect_next_instance_of(::Namespaces::FreeUserCap::Enforcement, group) do |instance| expect(instance).to receive(:enforce_cap?).and_return(enforcement_free_user_cap) diff --git a/ee/spec/helpers/gitlab_subscriptions/trials_helper_spec.rb b/ee/spec/helpers/gitlab_subscriptions/trials_helper_spec.rb index 35cda18471ab16..29dae6a0217ef2 100644 --- a/ee/spec/helpers/gitlab_subscriptions/trials_helper_spec.rb +++ b/ee/spec/helpers/gitlab_subscriptions/trials_helper_spec.rb @@ -5,7 +5,7 @@ RSpec.describe GitlabSubscriptions::TrialsHelper, feature_category: :acquisition do using RSpec::Parameterized::TableSyntax include Devise::Test::ControllerHelpers - include SubscriptionPortalStubHelpers + include SubscriptionPortalHelpers describe '#show_tier_badge_for_new_trial?' do where(:trials_available?, :paid?, :private?, :never_had_trial?, :authorized, :result) do @@ -49,7 +49,7 @@ let(:trial_duration) { 30 } before do - stub_subscription_portal_trial_types + stub_subscription_trial_types end subject { helper.trial_duration } diff --git a/ee/spec/helpers/registrations/company_helper_spec.rb b/ee/spec/helpers/registrations/company_helper_spec.rb index ebbcb55c56f388..83dc403051321f 100644 --- a/ee/spec/helpers/registrations/company_helper_spec.rb +++ b/ee/spec/helpers/registrations/company_helper_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Registrations::CompanyHelper, feature_category: :onboarding do - include SubscriptionPortalStubHelpers + include SubscriptionPortalHelpers describe '#create_company_form_data' do let(:user) { build_stubbed(:user, onboarding_status_registration_type: 'trial') } let(:trial_duration) { 30 } @@ -19,7 +19,7 @@ before do allow(helper).to receive_messages(params: params, current_user: user) - stub_subscription_portal_trial_types + stub_subscription_trial_types end subject(:form_data) { helper.create_company_form_data(::Onboarding::StatusPresenter.new({}, {}, user)) } diff --git a/ee/spec/mailers/namespaces/free_user_cap_mailer_spec.rb b/ee/spec/mailers/namespaces/free_user_cap_mailer_spec.rb index 907785e7f3cc92..90eae81964b7ba 100644 --- a/ee/spec/mailers/namespaces/free_user_cap_mailer_spec.rb +++ b/ee/spec/mailers/namespaces/free_user_cap_mailer_spec.rb @@ -4,7 +4,7 @@ RSpec.describe Namespaces::FreeUserCapMailer, feature_category: :seat_cost_management do include EmailSpec::Matchers - include SubscriptionPortalStubHelpers + include SubscriptionPortalHelpers describe '#over_limit_email' do let(:namespace) { build(:namespace) } @@ -14,7 +14,7 @@ it 'creates an email message namespace being over free user cap', :aggregate_failures do stub_ee_application_setting(dashboard_limit: 5) - stub_subscription_portal_trial_types + stub_subscription_trial_types result = format( s_('FreeUserCap|Action required: %{namespace_name} group has been placed into a read-only state'), diff --git a/ee/spec/requests/groups/usage_quotas_spec.rb b/ee/spec/requests/groups/usage_quotas_spec.rb index 910e937a190c5e..6846feeaa13e14 100644 --- a/ee/spec/requests/groups/usage_quotas_spec.rb +++ b/ee/spec/requests/groups/usage_quotas_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' RSpec.describe 'view usage quotas', feature_category: :consumables_cost_management do + include SubscriptionPortalHelpers let_it_be(:namespace) { create(:group) } let_it_be(:user) { create(:user) } let_it_be(:subscription_history) do @@ -27,6 +28,7 @@ before do login_as(user) + stub_subscription_trial_types end context 'when storage size is over limit' do diff --git a/ee/spec/requests/trial_registrations_controller_spec.rb b/ee/spec/requests/trial_registrations_controller_spec.rb index 33253c286c33b7..32188859a4d159 100644 --- a/ee/spec/requests/trial_registrations_controller_spec.rb +++ b/ee/spec/requests/trial_registrations_controller_spec.rb @@ -4,13 +4,13 @@ RSpec.describe TrialRegistrationsController, :with_current_organization, feature_category: :onboarding do include FullNameHelper - include SubscriptionPortalStubHelpers + include SubscriptionPortalHelpers let(:onboarding_enabled?) { true } before do stub_saas_features(onboarding: onboarding_enabled?) - stub_subscription_portal_trial_types + stub_subscription_trial_types end describe 'GET new' do diff --git a/ee/spec/services/ee/members/create_service_spec.rb b/ee/spec/services/ee/members/create_service_spec.rb index 22b02ca28300cc..d775cba0936d59 100644 --- a/ee/spec/services/ee/members/create_service_spec.rb +++ b/ee/spec/services/ee/members/create_service_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' RSpec.describe Members::CreateService, feature_category: :groups_and_projects do + include SubscriptionPortalHelpers let_it_be(:user) { create(:user) } let_it_be(:root_ancestor, reload: true) { create(:group) } let_it_be(:project, reload: true) { create(:project, group: root_ancestor) } @@ -292,6 +293,7 @@ before do stub_ee_application_setting(dashboard_limit: 3) stub_ee_application_setting(dashboard_limit_enabled: dashboard_limit_enabled) + stub_subscription_trial_types end subject(:execute_service) { described_class.new(user, params.merge({ source: invited_group })).execute } diff --git a/ee/spec/services/gitlab_subscriptions/trial_duration_service_spec.rb b/ee/spec/services/gitlab_subscriptions/trial_duration_service_spec.rb index 9f67d362cbd6b5..c1009537362f3c 100644 --- a/ee/spec/services/gitlab_subscriptions/trial_duration_service_spec.rb +++ b/ee/spec/services/gitlab_subscriptions/trial_duration_service_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe GitlabSubscriptions::TrialDurationService, feature_category: :acquisition do - include SubscriptionPortalStubHelpers + include SubscriptionPortalHelpers describe '#execute', :saas, :use_clean_rails_memory_store_caching do let_it_be(:free_duration) { 1 } let_it_be(:premium_duration) { 2 } @@ -42,7 +42,7 @@ subject(:service) { described_class.new } before do - stub_subscription_portal_trial_types(trial_types: trial_types) + stub_subscription_trial_types(trial_types: trial_types) end it 'makes a request, caches it, and returns correct duration' do @@ -113,7 +113,7 @@ context 'with an unsuccessful CustomersDot query' do before do - stub_subscription_portal_trial_types(success: false) + stub_subscription_trial_types(success: false) end it { expect(service.execute).to eq(default_free_duration) } diff --git a/ee/spec/services/namespaces/free_user_cap/notify_over_limit_service_spec.rb b/ee/spec/services/namespaces/free_user_cap/notify_over_limit_service_spec.rb index 4dbcd7748de476..d0e32471d29024 100644 --- a/ee/spec/services/namespaces/free_user_cap/notify_over_limit_service_spec.rb +++ b/ee/spec/services/namespaces/free_user_cap/notify_over_limit_service_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' RSpec.describe Namespaces::FreeUserCap::NotifyOverLimitService, feature_category: :seat_cost_management do + include SubscriptionPortalHelpers let_it_be(:group) { create(:group) } before_all do @@ -10,6 +11,10 @@ group.add_owner(create(:owner)) end + before do + stub_subscription_trial_types + end + describe '#execute', :saas do subject(:execute) { described_class.new(group).execute } diff --git a/ee/spec/support/helpers/subscription_portal_helpers.rb b/ee/spec/support/helpers/subscription_portal_helpers.rb index 5cc49ad70f0a31..60fb405fc44d10 100644 --- a/ee/spec/support/helpers/subscription_portal_helpers.rb +++ b/ee/spec/support/helpers/subscription_portal_helpers.rb @@ -106,6 +106,50 @@ def stub_temporary_extension_data(namespace_id) }.to_json) end + # Stubs the subscription portal client to prevent real HTTP calls in tests + # This is needed because TrialDurationService makes HTTP requests to fetch trial types + # + # @param trial_types [Hash] Custom trial types to return. Defaults to standard trial types. + # @param success [Boolean] Whether the API call should be successful. Defaults to true. + # + # @example Basic usage + # stub_subscription_trial_types + # + # @example Custom trial types + # stub_subscription_trial_types( + # trial_types: { + # 'free' => { duration_days: 14 }, + # 'premium' => { duration_days: 60 } + # } + # ) + # + # @example Simulate API failure + # stub_subscription_trial_types(success: false) + def stub_subscription_trial_types(trial_types: nil, success: true) + default_trial_types = { + GitlabSubscriptions::Trials::FREE_TRIAL_TYPE => { duration_days: 30 }, + GitlabSubscriptions::Trials::DUO_ENTERPRISE_TRIAL_TYPE => { duration_days: 60 } + } + + response = if success + { + success: true, + data: { + trial_types: trial_types || default_trial_types + } + } + else + { + success: false, + data: { + errors: ['API Error'] + } + } + end + + allow(Gitlab::SubscriptionPortal::Client).to receive(:namespace_trial_types).and_return(response) + end + private def plans_fixture diff --git a/ee/spec/support/helpers/subscription_portal_stub_helpers.rb b/ee/spec/support/helpers/subscription_portal_stub_helpers.rb deleted file mode 100644 index b32163ce34a72a..00000000000000 --- a/ee/spec/support/helpers/subscription_portal_stub_helpers.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -module SubscriptionPortalStubHelpers - # Stubs the subscription portal client to prevent real HTTP calls in tests - # This is needed because TrialDurationService makes HTTP requests to fetch trial types - # - # @param trial_types [Hash] Custom trial types to return. Defaults to standard trial types. - # @param success [Boolean] Whether the API call should be successful. Defaults to true. - # - # @example Basic usage - # stub_subscription_portal_trial_types - # - # @example Custom trial types - # stub_subscription_portal_trial_types( - # trial_types: { - # 'free' => { duration_days: 14 }, - # 'premium' => { duration_days: 60 } - # } - # ) - # - # @example Simulate API failure - # stub_subscription_portal_trial_types(success: false) - def stub_subscription_portal_trial_types(trial_types: nil, success: true) - default_trial_types = { - GitlabSubscriptions::Trials::FREE_TRIAL_TYPE => { duration_days: 30 }, - GitlabSubscriptions::Trials::DUO_ENTERPRISE_TRIAL_TYPE => { duration_days: 60 } - } - - response = if success - { - success: true, - data: { - trial_types: trial_types || default_trial_types - } - } - else - { - success: false, - data: { - errors: ['API Error'] - } - } - end - - allow(Gitlab::SubscriptionPortal::Client).to receive(:namespace_trial_types).and_return(response) - end -end diff --git a/ee/spec/support/shared_examples/features/ultimate_trial_callout_shared_examples.rb b/ee/spec/support/shared_examples/features/ultimate_trial_callout_shared_examples.rb index b1c0c91dd6eaa5..3c1b2870f2f28d 100644 --- a/ee/spec/support/shared_examples/features/ultimate_trial_callout_shared_examples.rb +++ b/ee/spec/support/shared_examples/features/ultimate_trial_callout_shared_examples.rb @@ -1,7 +1,10 @@ # frozen_string_literal: true RSpec.shared_examples 'dashboard ultimate trial callout' do + include SubscriptionPortalHelpers + before do + stub_subscription_trial_types sign_in(user) end diff --git a/ee/spec/views/groups/billings/index.html.haml_spec.rb b/ee/spec/views/groups/billings/index.html.haml_spec.rb index 89731e32d6dbc4..c8d529f6af648a 100644 --- a/ee/spec/views/groups/billings/index.html.haml_spec.rb +++ b/ee/spec/views/groups/billings/index.html.haml_spec.rb @@ -15,6 +15,7 @@ allow(view).to receive(:current_user).and_return(user) assign(:group, group) assign(:plans_data, plans_data) + stub_subscription_trial_types end context 'when the group is a subgroup' do diff --git a/ee/spec/views/registrations/company/new.html.haml_spec.rb b/ee/spec/views/registrations/company/new.html.haml_spec.rb index 45d290e4a70fed..2cfd33bcb8ca5a 100644 --- a/ee/spec/views/registrations/company/new.html.haml_spec.rb +++ b/ee/spec/views/registrations/company/new.html.haml_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' RSpec.describe 'registrations/company/new', feature_category: :onboarding do + include SubscriptionPortalHelpers let(:user) { build_stubbed(:user) } let(:show_company_form_side_column?) { false } let(:onboarding_status_presenter) do @@ -16,6 +17,7 @@ before do allow(view).to receive_messages(current_user: user, onboarding_status_presenter: onboarding_status_presenter) + stub_subscription_trial_types end describe 'Google Tag Manager' do diff --git a/ee/spec/workers/namespaces/free_user_cap/group_over_limit_notification_worker_spec.rb b/ee/spec/workers/namespaces/free_user_cap/group_over_limit_notification_worker_spec.rb index 36d2c981bf2688..167eac3c209761 100644 --- a/ee/spec/workers/namespaces/free_user_cap/group_over_limit_notification_worker_spec.rb +++ b/ee/spec/workers/namespaces/free_user_cap/group_over_limit_notification_worker_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' RSpec.describe Namespaces::FreeUserCap::GroupOverLimitNotificationWorker, :saas, feature_category: :seat_cost_management, type: :worker do + include SubscriptionPortalHelpers describe '#perform' do let_it_be(:owner) { create :owner } let_it_be(:group) { create(:group_with_plan, :private, plan: :free_plan, owners: owner) } @@ -40,6 +41,7 @@ before do stub_ee_application_setting(dashboard_limit_enabled: dashboard_limit_enabled) stub_ee_application_setting(dashboard_limit: 5) + stub_subscription_trial_types end subject(:perform) { described_class.new.perform(invited_group.id, added_member_ids) } diff --git a/spec/mailers/previews_spec.rb b/spec/mailers/previews_spec.rb index 201ce8c17d687d..36298f6c911437 100644 --- a/spec/mailers/previews_spec.rb +++ b/spec/mailers/previews_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' RSpec.describe 'Mailer previews', feature_category: :shared do + include SubscriptionPortalHelpers # Setup needed for email previews let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, :repository, :import_failed, group: group, import_last_error: 'some error') } @@ -50,6 +51,7 @@ with_them do it do + stub_subscription_trial_types issue_link = pending_failures["#{preview.name}##{email}"] pending "See #{issue_link}" if issue_link diff --git a/spec/requests/groups/usage_quotas_controller_spec.rb b/spec/requests/groups/usage_quotas_controller_spec.rb index 67aef23704a916..4920ddee2a2ede 100644 --- a/spec/requests/groups/usage_quotas_controller_spec.rb +++ b/spec/requests/groups/usage_quotas_controller_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' RSpec.describe Groups::UsageQuotasController, :with_license, feature_category: :consumables_cost_management do + include SubscriptionPortalHelpers let_it_be(:group) { create(:group) } let_it_be(:subgroup) { create(:group, parent: group) } let_it_be(:user) { create(:user) } @@ -17,6 +18,7 @@ context 'when user has read_usage_quotas permission' do before do group.add_owner(user) + stub_subscription_trial_types end it 'renders index with 200 status code' do -- GitLab From d7cffef61475ef93b5467b03cb65f1117f0bba82 Mon Sep 17 00:00:00 2001 From: Harsh Date: Wed, 10 Sep 2025 15:17:38 +0530 Subject: [PATCH 4/4] Add stub_subscription_trial_types to EE feature specs Fixes test failures by stubbing subscription trial types in EE feature specs that interact with subscription-related functionality. --- ee/spec/features/ci_shared_runner_warnings_spec.rb | 2 ++ ee/spec/features/groups/members/manage_members_spec.rb | 1 + ee/spec/features/groups/show_spec.rb | 3 +++ ee/spec/features/groups/usage_quotas/seats_tab_spec.rb | 1 + ee/spec/features/groups/usage_quotas/usage_quotas_spec.rb | 2 ++ ...eracts_with_unlimited_members_during_trial_alert_spec.rb | 1 + ee/spec/features/groups_spec.rb | 5 +++++ .../registrations/email_opt_in_registration_spec.rb | 6 ++++++ ...th_trial_from_external_site_without_confirmation_spec.rb | 2 ++ ee/spec/features/trial_registrations/signin_spec.rb | 6 ++++++ ee/spec/features/trial_registrations/signup_spec.rb | 3 +++ .../features/trials/duo_pro/trial_widget_in_sidebar_spec.rb | 1 + .../features/over_free_user_limit_shared_examples.rb | 3 +++ .../features/targeted_messages_shared_examples.rb | 3 +++ 14 files changed, 39 insertions(+) diff --git a/ee/spec/features/ci_shared_runner_warnings_spec.rb b/ee/spec/features/ci_shared_runner_warnings_spec.rb index c4bcab67762b55..45e5faa042a8da 100644 --- a/ee/spec/features/ci_shared_runner_warnings_spec.rb +++ b/ee/spec/features/ci_shared_runner_warnings_spec.rb @@ -5,6 +5,7 @@ RSpec.describe 'CI shared runner limits', feature_category: :runner do include UsageQuotasHelpers + include SubscriptionPortalHelpers include ::Ci::MinutesHelpers using RSpec::Parameterized::TableSyntax @@ -25,6 +26,7 @@ stub_ee_application_setting(should_check_namespace_plan: true) group.add_member(owner, :owner) group.add_member(developer, :developer) + stub_subscription_trial_types sign_in(owner) end diff --git a/ee/spec/features/groups/members/manage_members_spec.rb b/ee/spec/features/groups/members/manage_members_spec.rb index 4b40de1d301077..826a9a415dcf04 100644 --- a/ee/spec/features/groups/members/manage_members_spec.rb +++ b/ee/spec/features/groups/members/manage_members_spec.rb @@ -24,6 +24,7 @@ stub_signing_key stub_reconciliation_request(true) stub_subscription_request_seat_usage(true) + stub_subscription_trial_types stub_feature_flags(show_role_details_in_drawer: false) create(:callout, user: user1, feature_name: :duo_chat_callout) end diff --git a/ee/spec/features/groups/show_spec.rb b/ee/spec/features/groups/show_spec.rb index da9137431773a9..4adb676844afe8 100644 --- a/ee/spec/features/groups/show_spec.rb +++ b/ee/spec/features/groups/show_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'Group show page', :js, :saas, feature_category: :groups_and_projects do + include SubscriptionPortalHelpers + let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group, :private, owners: user) } @@ -12,6 +14,7 @@ before do sign_in(user) + stub_subscription_trial_types visit group_path(group) end diff --git a/ee/spec/features/groups/usage_quotas/seats_tab_spec.rb b/ee/spec/features/groups/usage_quotas/seats_tab_spec.rb index a713621c0fb88d..a1562ee3555c41 100644 --- a/ee/spec/features/groups/usage_quotas/seats_tab_spec.rb +++ b/ee/spec/features/groups/usage_quotas/seats_tab_spec.rb @@ -19,6 +19,7 @@ stub_signing_key stub_application_setting(check_namespace_plan: true) stub_subscription_permissions_data(group.id) + stub_subscription_trial_types group.add_owner(user) group.add_maintainer(maintainer) diff --git a/ee/spec/features/groups/usage_quotas/usage_quotas_spec.rb b/ee/spec/features/groups/usage_quotas/usage_quotas_spec.rb index 259445d0e1a5ed..0d47c4f029c0ec 100644 --- a/ee/spec/features/groups/usage_quotas/usage_quotas_spec.rb +++ b/ee/spec/features/groups/usage_quotas/usage_quotas_spec.rb @@ -4,6 +4,7 @@ RSpec.describe 'Groups > Usage quotas', :saas, feature_category: :consumables_cost_management do include ContentSecurityPolicyHelpers + include SubscriptionPortalHelpers let_it_be_with_reload(:user) { create(:user) } let_it_be_with_reload(:group) { create(:group) } @@ -55,6 +56,7 @@ one_trust_id: onetrust_id }) stub_saas_features(marketing_google_tag_manager: gtm_enabled) stub_feature_flags(ecomm_instrumentation: onetrust_enabled) + stub_subscription_trial_types visit group_usage_quotas_path(group) end diff --git a/ee/spec/features/groups/user_interacts_with_unlimited_members_during_trial_alert_spec.rb b/ee/spec/features/groups/user_interacts_with_unlimited_members_during_trial_alert_spec.rb index 3759aef3d35bf1..7fc398a1e2dd8d 100644 --- a/ee/spec/features/groups/user_interacts_with_unlimited_members_during_trial_alert_spec.rb +++ b/ee/spec/features/groups/user_interacts_with_unlimited_members_during_trial_alert_spec.rb @@ -12,6 +12,7 @@ before do stub_feature_flags(streamlined_first_product_experience: false) + stub_subscription_trial_types end context 'when group not in trial' do diff --git a/ee/spec/features/groups_spec.rb b/ee/spec/features/groups_spec.rb index 3f2a201256c531..3102052a42c9b8 100644 --- a/ee/spec/features/groups_spec.rb +++ b/ee/spec/features/groups_spec.rb @@ -5,6 +5,11 @@ RSpec.describe 'Group', :with_current_organization, feature_category: :groups_and_projects do include NamespaceStorageHelpers include FreeUserCapHelpers + include SubscriptionPortalHelpers + + before do + stub_subscription_trial_types + end describe 'group edit', :js do let_it_be(:user) { create(:user) } diff --git a/ee/spec/features/registrations/email_opt_in_registration_spec.rb b/ee/spec/features/registrations/email_opt_in_registration_spec.rb index 5d734cf9664e9d..5fe8fbd2da789d 100644 --- a/ee/spec/features/registrations/email_opt_in_registration_spec.rb +++ b/ee/spec/features/registrations/email_opt_in_registration_spec.rb @@ -3,7 +3,13 @@ require 'spec_helper' RSpec.describe 'Registration with the email opt in value', :js, :saas_registration, :with_current_organization, feature_category: :onboarding do + include SubscriptionPortalHelpers + shared_examples 'toggles email opt-in checkbox' do + before do + stub_subscription_trial_types + end + it 'toggles the omniauth form actions' do visit path diff --git a/ee/spec/features/registrations/sign_up_with_trial_from_external_site_without_confirmation_spec.rb b/ee/spec/features/registrations/sign_up_with_trial_from_external_site_without_confirmation_spec.rb index caf706ecb94db5..a14e01897e583f 100644 --- a/ee/spec/features/registrations/sign_up_with_trial_from_external_site_without_confirmation_spec.rb +++ b/ee/spec/features/registrations/sign_up_with_trial_from_external_site_without_confirmation_spec.rb @@ -5,6 +5,7 @@ RSpec.describe 'Sign up with trial from external site without confirmation', :saas, :js, :with_current_organization, feature_category: :onboarding do include SaasRegistrationHelpers + include SubscriptionPortalHelpers let_it_be(:glm_params) do { glm_source: 'some_source', glm_content: 'some_content' } @@ -13,6 +14,7 @@ before do stub_application_setting(require_admin_approval_after_user_signup: false) stub_application_setting(import_sources: %w[github gitlab_project]) + stub_subscription_trial_types # The groups_and_projects_controller (on `click_on 'Create project'`) is over # the query limit threshold, so we have to adjust it. diff --git a/ee/spec/features/trial_registrations/signin_spec.rb b/ee/spec/features/trial_registrations/signin_spec.rb index 2e8c120e5814b0..8002d747791179 100644 --- a/ee/spec/features/trial_registrations/signin_spec.rb +++ b/ee/spec/features/trial_registrations/signin_spec.rb @@ -3,8 +3,14 @@ require 'spec_helper' RSpec.describe 'Trial Sign In', feature_category: :subscription_management do + include SubscriptionPortalHelpers + let(:user) { create(:user) } + before do + stub_subscription_trial_types + end + describe 'on GitLab.com', :saas do it 'logs the user in' do url_params = { glm_source: 'any-source', glm_content: 'any-content' } diff --git a/ee/spec/features/trial_registrations/signup_spec.rb b/ee/spec/features/trial_registrations/signup_spec.rb index d363e367131a34..ec3b02d640faf9 100644 --- a/ee/spec/features/trial_registrations/signup_spec.rb +++ b/ee/spec/features/trial_registrations/signup_spec.rb @@ -3,8 +3,11 @@ require 'spec_helper' RSpec.describe 'Trial Sign Up', :with_current_organization, :saas, feature_category: :acquisition do + include SubscriptionPortalHelpers + before do stub_application_setting(require_admin_approval_after_user_signup: false) + stub_subscription_trial_types end let_it_be(:new_user) { build_stubbed(:user) } diff --git a/ee/spec/features/trials/duo_pro/trial_widget_in_sidebar_spec.rb b/ee/spec/features/trials/duo_pro/trial_widget_in_sidebar_spec.rb index 1a4214c2a6130a..19ec1a1ab72f1e 100644 --- a/ee/spec/features/trials/duo_pro/trial_widget_in_sidebar_spec.rb +++ b/ee/spec/features/trials/duo_pro/trial_widget_in_sidebar_spec.rb @@ -56,6 +56,7 @@ stub_application_setting(check_namespace_plan: true) stub_subscription_permissions_data(group.id) stub_licensed_features(code_suggestions: true) + stub_subscription_trial_types end it 'shows expired widget and dismisses it' do diff --git a/ee/spec/support/shared_examples/features/over_free_user_limit_shared_examples.rb b/ee/spec/support/shared_examples/features/over_free_user_limit_shared_examples.rb index 440667d7b10425..8dc7cb8dbf0508 100644 --- a/ee/spec/support/shared_examples/features/over_free_user_limit_shared_examples.rb +++ b/ee/spec/support/shared_examples/features/over_free_user_limit_shared_examples.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true RSpec.shared_examples_for 'over the free user limit alert' do + include SubscriptionPortalHelpers + let_it_be(:new_user) { create(:user) } let_it_be(:dismiss_button) do '[data-testid="user-over-limit-free-plan-dismiss"]' @@ -8,6 +10,7 @@ before do stub_ee_application_setting(dashboard_limit_enabled: true) + stub_subscription_trial_types end shared_context 'with over storage limit setup' do diff --git a/ee/spec/support/shared_examples/features/targeted_messages_shared_examples.rb b/ee/spec/support/shared_examples/features/targeted_messages_shared_examples.rb index 33c4788e57c881..0f9c2902115aa0 100644 --- a/ee/spec/support/shared_examples/features/targeted_messages_shared_examples.rb +++ b/ee/spec/support/shared_examples/features/targeted_messages_shared_examples.rb @@ -1,8 +1,11 @@ # frozen_string_literal: true RSpec.shared_examples 'targeted message interactions' do + include SubscriptionPortalHelpers + before do create(:targeted_message_namespace, namespace: group) + stub_subscription_trial_types sign_in(user) end -- GitLab