From 70d2de2c20db38ac2040601065a277d84f57ab5e Mon Sep 17 00:00:00 2001
From: Serhii Yarynovskyi <syarynovskyi@gitlab.com>
Date: Thu, 24 Oct 2024 18:48:51 +0300
Subject: [PATCH] Convert Duo Enterprise alert partial for free plan

Convert partial into view component for free plan
---
 .../base_component.html.haml                  | 13 +++
 .../duo_enterprise_alert/base_component.rb    | 82 +++++++++++++++++++
 .../duo_enterprise_alert/free_component.rb    | 24 ++++++
 ee/app/helpers/billing_plans_helper.rb        |  9 +-
 ...ree_and_trial_plan_billing_index.html.haml |  5 +-
 .../free_component_spec.rb                    | 75 +++++++++++++++++
 ee/spec/helpers/billing_plans_helper_spec.rb  | 10 ---
 ...o_enterprise_trial_alert.html.haml_spec.rb | 41 ----------
 8 files changed, 197 insertions(+), 62 deletions(-)
 create mode 100644 ee/app/components/gitlab_subscriptions/duo_enterprise_alert/base_component.html.haml
 create mode 100644 ee/app/components/gitlab_subscriptions/duo_enterprise_alert/base_component.rb
 create mode 100644 ee/app/components/gitlab_subscriptions/duo_enterprise_alert/free_component.rb
 create mode 100644 ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/free_component_spec.rb

diff --git a/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/base_component.html.haml b/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/base_component.html.haml
new file mode 100644
index 0000000000000..5b65c7c21fa52
--- /dev/null
+++ b/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/base_component.html.haml
@@ -0,0 +1,13 @@
+= render Pajamas::CardComponent.new(card_options: card_options) do |c|
+  - c.with_body do
+    .gl-text-size-h2.gl-font-bold
+      = icon
+      = title
+    .gl-mb-5
+      - body.map do |line|
+        .gl-mt-3
+          = line
+    .gl-flex.gl-flex-wrap.gl-gap-3
+      = render Pajamas::ButtonComponent.new(**primary_cta_options) do
+        = primary_cta
+      .js-hand-raise-lead-trigger{ data: hand_raise_lead_data }
diff --git a/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/base_component.rb b/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/base_component.rb
new file mode 100644
index 0000000000000..a75a37bf36801
--- /dev/null
+++ b/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/base_component.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+module GitlabSubscriptions
+  module DuoEnterpriseAlert
+    class BaseComponent < ViewComponent::Base
+      # @param [Namespace or Group] namespace
+      # @param [User] user
+
+      def initialize(namespace:, user:)
+        @namespace = namespace
+        @user = user
+      end
+
+      private
+
+      attr_reader :namespace, :user
+
+      delegate :sprite_icon, to: :helpers
+
+      def duo_enterprise_trials_enabled?
+        Feature.enabled?(:duo_enterprise_trials, user)
+      end
+
+      def card_options
+        {
+          class: 'gl-border gl-border-blue-300 gl-bg-blue-50 gl-rounded-base gl-text-left gl-mt-6 gl-p-3',
+          data: { testid: 'duo-enterprise-trial-alert' }
+        }
+      end
+
+      def icon
+        sprite_icon('tanuki-ai', css_class: 'gl-mr-2 !gl-align-baseline')
+      end
+
+      def title
+        s_('BillingPlans|Get the most out of GitLab with Ultimate and GitLab Duo Enterprise')
+      end
+
+      def primary_cta_options
+        {
+          href: primary_link,
+          variant: 'confirm',
+          button_text_classes: '!gl-whitespace-normal',
+          button_options: {
+            class: 'gl-w-full sm:gl-w-auto',
+            data: {
+              event_tracking: 'click_duo_enterprise_trial_billing_page',
+              event_label: primary_tracking_label
+            }
+          }
+        }
+      end
+
+      def primary_link
+        new_trial_path(namespace_id: namespace.id)
+      end
+
+      def primary_tracking_label
+        'ultimate_and_duo_enterprise_trial'
+      end
+
+      def primary_cta
+        s_('BillingPlans|Start free trial of GitLab Ultimate and GitLab Duo Enterprise')
+      end
+
+      def hand_raise_lead_data
+        {
+          glm_content: 'billing-group',
+          cta_tracking: {
+            action: 'hand_raise_form_viewed',
+            label: 'click_duo_enterprise_trial_billing_page'
+          }.to_json,
+          button_attributes: {
+            variant: 'confirm',
+            category: 'secondary',
+            class: 'gl-w-full sm:gl-w-auto'
+          }.to_json
+        }
+      end
+    end
+  end
+end
diff --git a/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/free_component.rb b/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/free_component.rb
new file mode 100644
index 0000000000000..e244e13a9e2b5
--- /dev/null
+++ b/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/free_component.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module GitlabSubscriptions
+  module DuoEnterpriseAlert
+    class FreeComponent < BaseComponent
+      private
+
+      def render?
+        duo_enterprise_trials_enabled? &&
+          namespace.free_plan? &&
+          GitlabSubscriptions::DuoEnterprise.no_add_on_purchase_for_namespace?(namespace)
+      end
+
+      def body
+        [
+          s_('BillingPlans|Start an Ultimate trial with GitLab Duo Enterprise to ' \
+            'try the complete set of features from GitLab. GitLab Duo Enterprise ' \
+            'gives you access to the full product offering from GitLab, including ' \
+            'AI-powered features. You can try it for free, no credit card required.')
+        ]
+      end
+    end
+  end
+end
diff --git a/ee/app/helpers/billing_plans_helper.rb b/ee/app/helpers/billing_plans_helper.rb
index 68268f7c1ddb8..8e639dcef9ac5 100644
--- a/ee/app/helpers/billing_plans_helper.rb
+++ b/ee/app/helpers/billing_plans_helper.rb
@@ -152,7 +152,7 @@ def add_namespace_plan_to_group_instructions
   def show_duo_enterprise_trial_alert?(namespace)
     return false if Feature.disabled?(:duo_enterprise_trials, current_user)
 
-    if namespace.ultimate_plan? || namespace.free_plan?
+    if namespace.ultimate_plan?
       GitlabSubscriptions::DuoEnterprise.no_add_on_purchase_for_namespace?(namespace)
     elsif namespace.premium_plan?
       GitlabSubscriptions::Duo.no_add_on_purchase_for_namespace?(namespace)
@@ -177,13 +177,6 @@ def duo_enterprise_trial_alert_data(namespace)
           s_('BillingPlans|Not ready to trial the full suite of GitLab and GitLab Duo features? Start a free trial of GitLab Duo Pro instead.')
         ]
       }
-    else
-      {
-        title: s_('BillingPlans|Get the most out of GitLab with Ultimate and GitLab Duo Enterprise'),
-        body: [
-          s_('BillingPlans|Start an Ultimate trial with GitLab Duo Enterprise to try the complete set of features from GitLab. GitLab Duo Enterprise gives you access to the full product offering from GitLab, including AI-powered features. You can try it for free, no credit card required.')
-        ]
-      }
     end
   end
 
diff --git a/ee/app/views/groups/billings/_free_and_trial_plan_billing_index.html.haml b/ee/app/views/groups/billings/_free_and_trial_plan_billing_index.html.haml
index d263a6e9d7c3d..8e0bb320b1f3a 100644
--- a/ee/app/views/groups/billings/_free_and_trial_plan_billing_index.html.haml
+++ b/ee/app/views/groups/billings/_free_and_trial_plan_billing_index.html.haml
@@ -11,9 +11,8 @@
 
     = html_escape(s_("BillingPlans|Not the group you're looking for? %{all_groups_link}")) % { all_groups_link: all_groups_link.html_safe }
 
-  - if show_duo_enterprise_trial_alert?(namespace)
-    .billing-plan-divider.gl-mx-auto
-      = render 'shared/billings/duo_enterprise_trial_alert', namespace: namespace
+  .billing-plan-divider.gl-mx-auto
+    = render GitlabSubscriptions::DuoEnterpriseAlert::FreeComponent.new(namespace: namespace, user: current_user)
 
   .gl-flex-row.gl-flex.gl-flex-wrap.gl-justify-center.gl-mb-7.gl-ml-7{ data: { track_action: 'render', testid: 'billing-plans' } }
     = render Billing::PlanComponent.with_collection(plans_data, namespace: namespace, current_plan: current_plan)
diff --git a/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/free_component_spec.rb b/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/free_component_spec.rb
new file mode 100644
index 0000000000000..c7ddbb3b9f472
--- /dev/null
+++ b/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/free_component_spec.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSubscriptions::DuoEnterpriseAlert::FreeComponent, :saas, :aggregate_failures,
+  type: :component, feature_category: :acquisition do
+  let(:namespace) { build(:group, id: non_existing_record_id) }
+  let(:user) { build(:user) }
+
+  subject(:component) do
+    render_inline(described_class.new(namespace: namespace, user: user)) && page
+  end
+
+  before do
+    build(:gitlab_subscription, :free, namespace: namespace)
+  end
+
+  context 'when duo_enterprise_trials is disabled' do
+    before do
+      stub_feature_flags(duo_enterprise_trials: false)
+    end
+
+    it { is_expected.to have_content('') }
+  end
+
+  context 'when ultimate_trial plan' do
+    before do
+      build(:gitlab_subscription, :ultimate_trial, :active_trial, namespace: namespace)
+    end
+
+    it { is_expected.to have_content('') }
+  end
+
+  context 'when there is Duo Enterprise add-on' do
+    before do
+      allow(GitlabSubscriptions::DuoEnterprise)
+        .to receive(:no_add_on_purchase_for_namespace?)
+        .with(namespace)
+        .and_return(false)
+    end
+
+    it { is_expected.to have_content('') }
+  end
+
+  context 'when rendering' do
+    it 'has the correct text' do
+      is_expected.to have_content(
+        'Get the most out of GitLab with Ultimate and GitLab Duo Enterprise'
+      )
+
+      is_expected.to have_content(
+        'Start an Ultimate trial with GitLab Duo Enterprise to try the ' \
+          'complete set of features from GitLab. GitLab Duo Enterprise gives ' \
+          'you access to the full product offering from GitLab, including ' \
+          'AI-powered features. You can try it for free, no credit card required.'
+      )
+    end
+
+    it 'has the primary action' do
+      is_expected.to have_link(
+        'Start free trial of GitLab Ultimate and GitLab Duo Enterprise',
+        href: new_trial_path(namespace_id: namespace.id)
+      )
+
+      is_expected.to have_css(
+        '[data-event-tracking="click_duo_enterprise_trial_billing_page"]' \
+          '[data-event-label="ultimate_and_duo_enterprise_trial"]'
+      )
+    end
+
+    it 'has the hand raise lead selector' do
+      is_expected.to have_selector('.js-hand-raise-lead-trigger')
+    end
+  end
+end
diff --git a/ee/spec/helpers/billing_plans_helper_spec.rb b/ee/spec/helpers/billing_plans_helper_spec.rb
index fc35b23ab1746..3c2f70aafa114 100644
--- a/ee/spec/helpers/billing_plans_helper_spec.rb
+++ b/ee/spec/helpers/billing_plans_helper_spec.rb
@@ -605,16 +605,6 @@
       end
     end
 
-    context 'when free plan' do
-      before do
-        build(:gitlab_subscription, :free, namespace: namespace)
-      end
-
-      it_behaves_like 'available plan' do
-        let(:finder) { GitlabSubscriptions::DuoEnterprise }
-      end
-    end
-
     context 'when ultimate trial plan' do
       before do
         build(:gitlab_subscription, :ultimate_trial, :active_trial, namespace: namespace)
diff --git a/ee/spec/views/shared/billings/_duo_enterprise_trial_alert.html.haml_spec.rb b/ee/spec/views/shared/billings/_duo_enterprise_trial_alert.html.haml_spec.rb
index ede6949b68c7a..0b98768478423 100644
--- a/ee/spec/views/shared/billings/_duo_enterprise_trial_alert.html.haml_spec.rb
+++ b/ee/spec/views/shared/billings/_duo_enterprise_trial_alert.html.haml_spec.rb
@@ -103,45 +103,4 @@ def render
       )
     end
   end
-
-  context 'when free plan' do
-    before do
-      build(:gitlab_subscription, :free, namespace: group)
-    end
-
-    it 'contains the correct text' do
-      render
-
-      expect(rendered).to have_content(
-        'Get the most out of GitLab with Ultimate and GitLab Duo Enterprise'
-      )
-
-      expect(rendered).to have_content(
-        'Start an Ultimate trial with GitLab Duo Enterprise to try the ' \
-          'complete set of features from GitLab. GitLab Duo Enterprise gives ' \
-          'you access to the full product offering from GitLab, including ' \
-          'AI-powered features. You can try it for free, no credit card required.'
-      )
-    end
-
-    it 'contains the primary action' do
-      render
-
-      expect(rendered).to have_link(
-        'Start free trial of GitLab Ultimate and GitLab Duo Enterprise',
-        href: new_trial_path(namespace_id: group.id)
-      )
-
-      expect(rendered).to have_css(
-        '[data-event-tracking="click_duo_enterprise_trial_billing_page"]' \
-          '[data-event-label="ultimate_and_duo_enterprise_trial"]'
-      )
-    end
-
-    it 'contains the hand raise lead selector' do
-      render
-
-      expect(rendered).to have_selector('.js-hand-raise-lead-trigger')
-    end
-  end
 end
-- 
GitLab