diff --git a/ee/app/services/gitlab_subscriptions/trial_duration_service.rb b/ee/app/services/gitlab_subscriptions/trial_duration_service.rb index aca3f3ad2e66f8707609894e35bf1ef0cdb1d5d1..865bf68167178ed7653f4faaa53480cde289c326 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/components/gitlab_subscriptions/duo_enterprise_alert/ultimate_component_spec.rb b/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/ultimate_component_spec.rb index d56ffeeb13b4009a42fdc5d89e35accf93b59fc9..6cd5c9ec2a433182c448878d31003ef746c17205 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 SubscriptionPortalHelpers 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_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 7626b9ad803d30d6a701b5c9c32f2d9051b4955f..d7848775c0c8d6cf15a0d3a82cdf70da148d2ee7 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 SubscriptionPortalHelpers 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_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 9e6c9138e7b779db28167d7d8e8da079e2487d1d..626ee67d4df8b403ee457ec1391a89631cab6bde 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 SubscriptionPortalHelpers 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_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 c9c723cde60bc820c21d7705e3f744da995aaf04..a0f684f7056686b135964ddc6edbe5f4865b12b4 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]) } @@ -38,6 +39,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 2268c2d85f99bb5494ef49d52eeaa2fb94bf8cdd..e90fb5cb5c7ce7eea0011e9b4eab0b4f95f62175 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 98115f04351f83155372b7d0a240d176391fc92e..1f2b7a649cb0194ba5aa1f9e0da6518678a42187 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/ci_shared_runner_warnings_spec.rb b/ee/spec/features/ci_shared_runner_warnings_spec.rb index c4bcab67762b55810f1e1a5a4e24b653c975281d..45e5faa042a8da81f87e138462cc4d2276e3aeed 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/google_analytics_datalayer_spec.rb b/ee/spec/features/google_analytics_datalayer_spec.rb index b3433763dd84e6e8764c6d7880ec2d307cdf2567..517af692daaa28d2da60eeda982e8e9ef57069a1 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 9469106d2386bc8496dd2a0042dc9a30b2b77a87..373c96e10a13d47afc8073c42515f1c06007b037 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 bd3f4c75560e88602bcf147ebf045fe6038ab2db..b55bc254d2ae6086c9b12932ed11f353d5c51814 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/members/manage_members_spec.rb b/ee/spec/features/groups/members/manage_members_spec.rb index 4b40de1d301077a254fbcbf1b82016d97fd4448d..826a9a415dcf0472be4d736212173ed4e3df5864 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 da9137431773a9a038aa9e0d682e5cfc6662ed28..4adb676844afe86c61d7726faa814c409b3131ad 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/pipelines_tab_spec.rb b/ee/spec/features/groups/usage_quotas/pipelines_tab_spec.rb index c832f1d85ac6bb4d1397d299b9d27b5a3d6b3f75..4eb5d154aa9d18319f9116addf941a93fa4432ca 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/seats_tab_spec.rb b/ee/spec/features/groups/usage_quotas/seats_tab_spec.rb index a713621c0fb88db38bb01cb742d7854bf65c29bb..a1562ee3555c41847f31a4da8de4176f88a631a0 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/storage_tab_spec.rb b/ee/spec/features/groups/usage_quotas/storage_tab_spec.rb index d1a1649525eca1d4c35a8e7a363590225cdc14c8..93e1b71b15b89272ac650ae30e32d3af39e86e51 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/groups/usage_quotas/usage_quotas_spec.rb b/ee/spec/features/groups/usage_quotas/usage_quotas_spec.rb index 259445d0e1a5edeb4e38855c24c11b9721116646..0d47c4f029c0ec26bdc7aef745951560abd0247f 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 3759aef3d35bf19b662d41642e611f93d67a4595..7fc398a1e2dd8d1068542a41b6cdafdd0141900b 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 3f2a201256c531d967ce561d83512db724bb2173..3102052a42c9b897e49dd2e13e7602525571aef7 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/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 8d7ac1a54d72ff2f8ee6b8efed54ce2a022ee3df..45ee6852445d1a933d016e368091357266b4e5f5 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 5f45f8b2a61fa2d4ea567526dba1980661f17f95..de0d76f99f04800e5787eda11c429c41639ac733 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 e74de2d4a5e003396919381b9161fdebb8c00d7f..6cb8d63d2e695b7a5964f474bab44ed9a0c342d5 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 f0419438a7c43a9eb713921aa7581a3defd0c6e9..c2cb2c60b98fb28265472c653aa761e5da68f957 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/email_opt_in_registration_spec.rb b/ee/spec/features/registrations/email_opt_in_registration_spec.rb index 5d734cf9664e9d31dbd6b31f980bb8b1461c6c6a..5fe8fbd2da789d92f60caa846c7a33862dd639d5 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/identity_verification_spec.rb b/ee/spec/features/registrations/identity_verification_spec.rb index c11f3a38c4c7b836346ce785ceb7f6eafa45025c..ba06ca7b86e572083d741cb5419b9b46fb6858e0 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/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 caf706ecb94db5bf6a85216a45b0fc0d1ac30cf6..a14e01897e583ff7c078bd7c6713c1a20d04f1ac 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/company_information_spec.rb b/ee/spec/features/trial_registrations/company_information_spec.rb index 0027d72d2cd0b56fcb2f164abf74ad0ebfb92786..f8a97462f34d821c3a863f57fbc46dd3da9e5570 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/features/trial_registrations/signin_spec.rb b/ee/spec/features/trial_registrations/signin_spec.rb index 2e8c120e5814b01d83b3a1386adf309b7b14356f..8002d747791179c0c5b8d0a186bab857a03a1021 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 e19c4e729b9b2139d2d2320a1a0500ca4e9db520..24f8fbb42700bec65134049d17d17695dc049009 100644 --- a/ee/spec/features/trial_registrations/signup_spec.rb +++ b/ee/spec/features/trial_registrations/signup_spec.rb @@ -3,10 +3,12 @@ require 'spec_helper' RSpec.describe 'Trial Sign Up', :with_current_organization, :saas, feature_category: :acquisition do + include SubscriptionPortalHelpers include IdentityVerificationHelpers 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 1a4214c2a6130a3c084eaa0424d50ce754a0ee71..19ec1a1ab72f1ee6bcd1cf1cf7902f084e862774 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/helpers/ee/groups_helper_spec.rb b/ee/spec/helpers/ee/groups_helper_spec.rb index 3e7ad4f9503b523a36b47f8b4c4110728440ba70..221ece3ba3dc3fe4d69b883653a18adfdba5346d 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 SubscriptionPortalHelpers let(:owner) { create(:user, group_view: :security_dashboard) } let(:current_user) { owner } @@ -261,6 +262,7 @@ before do stub_ee_application_setting(dashboard_limit: 10) + 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 0e24d3e0261d7fc46867a1c34b33093723d27a51..29dae6a0217ef237197f82f08396372c3b0bc681 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 SubscriptionPortalHelpers 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_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 6c1afc9666954255c2e3a3b7c304040bb16ab67d..83dc403051321fd2e3b7d8ebef45c8ce3ad7b7fb 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 SubscriptionPortalHelpers 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_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 542b258df7ee7fdc3e48f2a9413329fd5bf2c411..90eae81964b7ba3f13de059115ab52ca8e9cb412 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 SubscriptionPortalHelpers 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_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 60ef223cbb4b5076b94a27915ee9ddd41b8835bb..ba350679023c86d13f891e22114d1fe3ed7433bf 100644 --- a/ee/spec/requests/groups/usage_quotas_spec.rb +++ b/ee/spec/requests/groups/usage_quotas_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'view usage quotas', :saas, 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 +29,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 d969dd516645103defe57f0f0b086b716f9c382d..726561c038686c999ee0852efa96d8c85bb9578e 100644 --- a/ee/spec/requests/trial_registrations_controller_spec.rb +++ b/ee/spec/requests/trial_registrations_controller_spec.rb @@ -4,12 +4,14 @@ RSpec.describe TrialRegistrationsController, :with_current_organization, feature_category: :onboarding do include FullNameHelper + include SubscriptionPortalHelpers include IdentityVerificationHelpers let(:onboarding_enabled?) { true } before do stub_saas_features(onboarding: onboarding_enabled?) + 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 22b02ca28300cce9c2020d45d034965f5b9bb121..d775cba0936d59b2e6b6e2d23b5d2d1947f60b91 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 d3f841b653ace97811b2ef7490eb0cb9a6a7b4d7..c1009537362f3c8e4c560cb557a44fe115ebbada 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,8 @@ require 'spec_helper' RSpec.describe GitlabSubscriptions::TrialDurationService, feature_category: :acquisition do - describe '#execute', :saas, :sidekiq_inline, :use_clean_rails_memory_store_caching do + include SubscriptionPortalHelpers + 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 } @@ -41,17 +42,44 @@ subject(:service) { described_class.new } before do - allow(Gitlab::SubscriptionPortal::Client).to receive(:namespace_trial_types).and_return(response) + stub_subscription_trial_types(trial_types: trial_types) 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) } @@ -84,7 +112,9 @@ end context 'with an unsuccessful CustomersDot query' do - let(:response) { { success: false } } + before do + 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 4dbcd7748de476c295360c117986322390827316..d0e32471d29024064835b5a9533dcea67e9fac13 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 5cc49ad70f0a312f205f73a3cd6e3e70564dbe3c..60fb405fc44d107dc1e625b1acb52981f867172a 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/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 440667d7b10425e7ad2c15d62ba1e581778b9dcf..8dc7cb8dbf050820df32655de558eb91952d2d28 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 33c4788e57c8812d951a8e0a80ecbd9a77229e7a..0f9c2902115aa0ab4b619fd310854e9f9d6659b1 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 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 b1c0c91dd6eaa529c4262f38aa3ea8401ca0a636..3c1b2870f2f28d94ef1b88c8c069abdb9d358f23 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 89731e32d6dbc4f6a5ca46ae58fc8d3e53e86aa3..c8d529f6af648a57f5a12c76798c3122ce938bae 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 45d290e4a70fed9f1b16f6e80bffbc198dcb7cf4..2cfd33bcb8ca5a8584c9f6e1a777f7f427b6a2de 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 36d2c981bf2688bd91ce9d22dad2e80f942bcba9..167eac3c2097613ad1d765a1ab17628ee0e343a9 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 201ce8c17d687d3357a66d16feeb72bf75f6f571..36298f6c9114374f4662f9598735857091cf8618 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 67aef23704a916329bb571e30c54d8043e2dd3dc..4920ddee2a2ede9eb96530c020d6611a9a648124 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