Commit f8186f8b authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'vs-add-support-for-legacy-plans' into 'master'

Hide deprecated billing plans

See merge request gitlab-org/gitlab!48888
parents 935ed217 a9558fdf
...@@ -79,6 +79,21 @@ module BillingPlansHelper ...@@ -79,6 +79,21 @@ module BillingPlansHelper
_('Seats usage data is updated every day at 12:00pm UTC') _('Seats usage data is updated every day at 12:00pm UTC')
end end
def upgrade_button_css_classes(namespace, plan, is_current_plan)
css_classes = %w[btn btn-success gl-button]
css_classes << 'disabled' if is_current_plan && !namespace.trial_active?
css_classes << 'invisible' if plan.deprecated?
css_classes.join(' ')
end
def available_plans(plans_data, current_plan)
return plans_data unless ::Feature.enabled?(:hide_deprecated_billing_plans)
plans_data.filter { |plan_data| !plan_data.deprecated? || plan_data.code == current_plan&.code }
end
private private
def plan_purchase_url(group, plan) def plan_purchase_url(group, plan)
......
- purchase_link = plan.purchase_link - purchase_link = plan.purchase_link
- plan_name = plan.name
- show_deprecated_plan = ::Feature.enabled?(:hide_deprecated_billing_plans) && plan.deprecated?
- if show_deprecated_plan
- plan_name += ' (Legacy)'
- faq_link_url = 'https://about.gitlab.com/gitlab-com/#faq'
- faq_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: faq_link_url }
.card.h-100{ class: ("card-active" if is_current) } .card.h-100{ class: ("card-active" if is_current || show_deprecated_plan) }
.card-header.gl-font-weight-bold.d-flex.flex-row.justify-content-between.flex-wrap .card-header.gl-font-weight-bold.d-flex.flex-row.justify-content-between.flex-wrap
%div %div
= plan.name = plan_name
- if is_current - if is_current
.text-muted .text-muted
= _("Current Plan") = _("Current Plan")
.card-body .card-body
- if show_deprecated_plan
= s_("The %{plan_name} is no longer available to purchase. For more information about how this will impact you, check our %{faq_link_start}frequently asked questions%{faq_link_end}.").html_safe % { plan_name: plan.name, faq_link_start: faq_link_start, faq_link_end: '</a>'.html_safe }
- else
.price-per-month .price-per-month
.gl-mr-2 .gl-mr-2
= number_to_plan_currency(plan.price_per_month) = number_to_plan_currency(plan.price_per_month)
...@@ -38,6 +47,6 @@ ...@@ -38,6 +47,6 @@
.float-right{ class: ("invisible" unless purchase_link.action == 'upgrade' || is_current) } .float-right{ class: ("invisible" unless purchase_link.action == 'upgrade' || is_current) }
- if show_contact_sales_button?(purchase_link.action) - if show_contact_sales_button?(purchase_link.action)
= link_to s_('BillingPlan|Contact sales'), "#{contact_sales_url}?test=inappcontactsales#{plan.code}", class: "btn btn-success-secondary gl-button", data: { **experiment_tracking_data_for_button_click('contact_sales') } = link_to s_('BillingPlan|Contact sales'), "#{contact_sales_url}?test=inappcontactsales#{plan.code}", class: "btn btn-success-secondary gl-button", data: { **experiment_tracking_data_for_button_click('contact_sales') }
- upgrade_button_class = "disabled" if is_current && !namespace.trial_active?
- cta_class = '-new' if use_new_purchase_flow?(namespace) - cta_class = '-new' if use_new_purchase_flow?(namespace)
= link_to s_('BillingPlan|Upgrade'), plan_purchase_or_upgrade_url(namespace, plan), class: "btn btn-success gl-button #{upgrade_button_class} billing-cta-purchase#{cta_class}", data: { **experiment_tracking_data_for_button_click('upgrade') } - upgrade_button_classes = upgrade_button_css_classes(namespace, plan, is_current)
= link_to s_('BillingPlan|Upgrade'), plan_purchase_or_upgrade_url(namespace, plan), class: "#{upgrade_button_classes} billing-cta-purchase#{cta_class}", data: { **experiment_tracking_data_for_button_click('upgrade') }
...@@ -5,8 +5,10 @@ ...@@ -5,8 +5,10 @@
= render 'shared/billings/billing_plan_header', namespace: namespace, plan: current_plan = render 'shared/billings/billing_plan_header', namespace: namespace, plan: current_plan
- if show_plans?(namespace) - if show_plans?(namespace)
.billing-plans.gl-mt-5.row - plans = available_plans(plans_data, current_plan)
- plans_data.each do |plan|
.billing-plans.gl-mt-5.row.justify-content-center
- plans.each do |plan|
- is_default_plan = current_plan.nil? && plan.default? - is_default_plan = current_plan.nil? && plan.default?
- is_current = plan.code == current_plan&.code || is_default_plan - is_current = plan.code == current_plan&.code || is_default_plan
.col-md-6.col-lg-3.gl-mb-5 .col-md-6.col-lg-3.gl-mb-5
......
---
name: hide_deprecated_billing_plans
introduced_by_url:
rollout_issue_url:
milestone: '13.7'
type: development
group: group::purchase
default_enabled: false
...@@ -18,6 +18,7 @@ RSpec.describe 'Billing plan pages', :feature do ...@@ -18,6 +18,7 @@ RSpec.describe 'Billing plan pages', :feature do
end end
before do before do
stub_feature_flags(hide_deprecated_billing_plans: false)
stub_experiment_for_subject(contact_sales_btn_in_app: true) stub_experiment_for_subject(contact_sales_btn_in_app: true)
stub_full_request("#{EE::SUBSCRIPTIONS_URL}/gitlab_plans?plan=#{plan.name}") stub_full_request("#{EE::SUBSCRIPTIONS_URL}/gitlab_plans?plan=#{plan.name}")
.to_return(status: 200, body: plans_data.to_json) .to_return(status: 200, body: plans_data.to_json)
...@@ -479,4 +480,46 @@ RSpec.describe 'Billing plan pages', :feature do ...@@ -479,4 +480,46 @@ RSpec.describe 'Billing plan pages', :feature do
end end
end end
end end
context 'when ff purchase_deprecated_plans is enabled' do
before do
stub_feature_flags(hide_deprecated_billing_plans: true)
end
context 'when deprecated plan is active' do
let(:plan) { bronze_plan }
let!(:subscription) do
create(:gitlab_subscription, namespace: namespace, hosted_plan: plan, seats: 15)
end
let(:expected_card_header) { "#{plans_data[1][:name]} (Legacy)" }
it 'renders the plan card marked as Legacy' do
visit profile_billings_path
page.within('.billing-plans') do
panels = page.all('.card')
expect(panels.length).to eq(plans_data.length)
panel_with_legacy_plan = panels[1] # free [0], bronze [1]
expect(panel_with_legacy_plan.find('.card-header')).to have_content(expected_card_header)
expect(panel_with_legacy_plan.find('.card-body')).to have_link('frequently asked questions')
end
end
end
context 'when deprecated plan is inactive' do
let(:plan) { free_plan }
it 'does not render the card for that plan' do
visit profile_billings_path
page.within('.billing-plans') do
panels = page.all('.card')
expect(panels.length).to eq(plans_data.length - 1)
end
end
end
end
end end
...@@ -90,7 +90,8 @@ ...@@ -90,7 +90,8 @@
"purchase_link": { "purchase_link": {
"action": "upgrade", "action": "upgrade",
"href": "http://customers.gitlab.com/subscriptions/new?plan_id=2c92a0ff5a840412015aa3cde86f2ba6" "href": "http://customers.gitlab.com/subscriptions/new?plan_id=2c92a0ff5a840412015aa3cde86f2ba6"
} },
"deprecated": true
}, },
{ {
"id": "silver-external-id", "id": "silver-external-id",
......
...@@ -179,4 +179,58 @@ RSpec.describe BillingPlansHelper do ...@@ -179,4 +179,58 @@ RSpec.describe BillingPlansHelper do
helper.plan_purchase_or_upgrade_url(group, plan) helper.plan_purchase_or_upgrade_url(group, plan)
end end
end end
describe '#upgrade_button_css_classe' do
using RSpec::Parameterized::TableSyntax
let(:plan) { double('Plan', deprecated?: false) }
it 'returns button-related classes only' do
expect(helper.upgrade_button_css_classes(nil, plan, false)).to eq('btn btn-success gl-button')
end
where(:is_current_plan, :trial_active, :result) do
false | false | 'btn btn-success gl-button'
false | true | 'btn btn-success gl-button'
true | true | 'btn btn-success gl-button'
true | false | 'btn btn-success gl-button disabled'
false | false | 'btn btn-success gl-button'
end
with_them do
let(:namespace) { Hashie::Mash.new(trial_active: trial_active) }
subject { helper.upgrade_button_css_classes(namespace, plan, is_current_plan) }
it { is_expected.to include(result) }
end
context 'when plan is deprecated' do
let(:deprecated_plan) { double('Plan', deprecated?: true) }
it 'returns invisible class' do
expect(helper.upgrade_button_css_classes(nil, deprecated_plan, false)).to include('invisible')
end
end
end
describe '#available_plans' do
let(:plan) { double('Plan', deprecated?: false, code: 'silver') }
let(:deprecated_plan) { double('Plan', deprecated?: true, code: 'bronze') }
let(:plans_data) { [plan, deprecated_plan] }
context 'when namespace is on an active plan' do
it 'returns plans without deprecated' do
expect(helper.available_plans(plans_data, nil)).to eq([plan])
end
end
context 'when namespace is on a deprecated plan' do
let(:current_plan) { Hashie::Mash.new(code: 'bronze') }
it 'returns plans with a deprecated plan' do
expect(helper.available_plans(plans_data, current_plan)).to eq(plans_data)
end
end
end
end end
...@@ -27113,6 +27113,9 @@ msgstr "" ...@@ -27113,6 +27113,9 @@ msgstr ""
msgid "The %{link_start}true-up model%{link_end} allows having more users, and additional users will incur a retroactive charge on renewal." msgid "The %{link_start}true-up model%{link_end} allows having more users, and additional users will incur a retroactive charge on renewal."
msgstr "" msgstr ""
msgid "The %{plan_name} is no longer available to purchase. For more information about how this will impact you, check our %{faq_link_start}frequently asked questions%{faq_link_end}."
msgstr ""
msgid "The %{type} contains the following error:" msgid "The %{type} contains the following error:"
msgid_plural "The %{type} contains the following errors:" msgid_plural "The %{type} contains the following errors:"
msgstr[0] "" msgstr[0] ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment