Commit c2a59e01 authored by Etienne Baqué's avatar Etienne Baqué

Merge branch 'billing-page-when-customers-down' into 'master'

Render an Error on the Billing Page When CustomersDot is Unavailable

See merge request gitlab-org/gitlab!61060
parents 5bed8c46 8427d734
...@@ -15,7 +15,12 @@ class Groups::BillingsController < Groups::ApplicationController ...@@ -15,7 +15,12 @@ class Groups::BillingsController < Groups::ApplicationController
@plans_data = GitlabSubscriptions::FetchSubscriptionPlansService @plans_data = GitlabSubscriptions::FetchSubscriptionPlansService
.new(plan: current_plan, namespace_id: relevant_group.id) .new(plan: current_plan, namespace_id: relevant_group.id)
.execute .execute
track_experiment_event(:contact_sales_btn_in_app, 'page_view:billing_plans:group')
record_experiment_user(:contact_sales_btn_in_app) if @plans_data
track_experiment_event(:contact_sales_btn_in_app, 'page_view:billing_plans:group')
record_experiment_user(:contact_sales_btn_in_app)
else
render 'shared/billings/customers_dot_unavailable'
end
end end
end end
...@@ -9,7 +9,12 @@ class Profiles::BillingsController < Profiles::ApplicationController ...@@ -9,7 +9,12 @@ class Profiles::BillingsController < Profiles::ApplicationController
@plans_data = GitlabSubscriptions::FetchSubscriptionPlansService @plans_data = GitlabSubscriptions::FetchSubscriptionPlansService
.new(plan: current_user.namespace.plan_name_for_upgrading, namespace_id: current_user.namespace_id) .new(plan: current_user.namespace.plan_name_for_upgrading, namespace_id: current_user.namespace_id)
.execute .execute
track_experiment_event(:contact_sales_btn_in_app, 'page_view:billing_plans:profile')
record_experiment_user(:contact_sales_btn_in_app) if @plans_data
track_experiment_event(:contact_sales_btn_in_app, 'page_view:billing_plans:profile')
record_experiment_user(:contact_sales_btn_in_app)
else
render 'shared/billings/customers_dot_unavailable'
end
end end
end end
- page_title _("Billing")
.gl-alert.gl-alert-danger.gl-mb-5
= sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon')
.gl-alert-content
.gl-alert-title
= _('Subscription service outage')
.gl-alert-body
= html_escape(_("The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}.")) % { linkStart: "<a href=\"#{::EE::GITLAB_COM_STATUS_URL}\">".html_safe, linkEnd: '</a>'.html_safe }
...@@ -12,4 +12,5 @@ module EE ...@@ -12,4 +12,5 @@ module EE
SUBSCRIPTION_PORTAL_ADMIN_TOKEN = ENV.fetch('SUBSCRIPTION_PORTAL_ADMIN_TOKEN', 'customer_admin_token') SUBSCRIPTION_PORTAL_ADMIN_TOKEN = ENV.fetch('SUBSCRIPTION_PORTAL_ADMIN_TOKEN', 'customer_admin_token')
CUSTOMER_SUPPORT_URL = 'https://support.gitlab.com' CUSTOMER_SUPPORT_URL = 'https://support.gitlab.com'
CUSTOMER_LICENSE_SUPPORT_URL = 'https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=360000071293' CUSTOMER_LICENSE_SUPPORT_URL = 'https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=360000071293'
GITLAB_COM_STATUS_URL = "https://status.gitlab.com"
end end
...@@ -27,7 +27,7 @@ RSpec.describe Groups::BillingsController do ...@@ -27,7 +27,7 @@ RSpec.describe Groups::BillingsController do
before do before do
add_group_owner add_group_owner
allow_next_instance_of(GitlabSubscriptions::FetchSubscriptionPlansService) do |instance| allow_next_instance_of(GitlabSubscriptions::FetchSubscriptionPlansService) do |instance|
allow(instance).to receive(:execute) allow(instance).to receive(:execute).and_return([])
end end
allow(controller).to receive(:track_experiment_event) allow(controller).to receive(:track_experiment_event)
end end
...@@ -61,6 +61,30 @@ RSpec.describe Groups::BillingsController do ...@@ -61,6 +61,30 @@ RSpec.describe Groups::BillingsController do
get_index get_index
end end
context 'when CustomersDot is unavailable' do
before do
allow_next_instance_of(GitlabSubscriptions::FetchSubscriptionPlansService) do |instance|
allow(instance).to receive(:execute).and_return(nil)
end
end
it 'does not track the page view for the contact_sales_btn_in_app experiment' do
expect(controller).not_to receive(:track_experiment_event)
get_index
expect(response).to render_template('shared/billings/customers_dot_unavailable')
end
it 'does not record the user for the contact_sales_btn_in_app experiment' do
expect(controller).not_to receive(:record_experiment_user)
get_index
expect(response).to render_template('shared/billings/customers_dot_unavailable')
end
end
end end
context 'unauthorized' do context 'unauthorized' do
......
...@@ -11,7 +11,7 @@ RSpec.describe Profiles::BillingsController do ...@@ -11,7 +11,7 @@ RSpec.describe Profiles::BillingsController do
stub_application_setting(check_namespace_plan: true) stub_application_setting(check_namespace_plan: true)
allow(Gitlab).to receive(:com?) { true } allow(Gitlab).to receive(:com?) { true }
allow_next_instance_of(GitlabSubscriptions::FetchSubscriptionPlansService) do |instance| allow_next_instance_of(GitlabSubscriptions::FetchSubscriptionPlansService) do |instance|
allow(instance).to receive(:execute) allow(instance).to receive(:execute).and_return([])
end end
allow(controller).to receive(:track_experiment_event) allow(controller).to receive(:track_experiment_event)
end end
...@@ -51,5 +51,29 @@ RSpec.describe Profiles::BillingsController do ...@@ -51,5 +51,29 @@ RSpec.describe Profiles::BillingsController do
get_index get_index
end end
context 'when CustomersDot is unavailable' do
before do
allow_next_instance_of(GitlabSubscriptions::FetchSubscriptionPlansService) do |instance|
allow(instance).to receive(:execute).and_return(nil)
end
end
it 'does not track the page view for the contact_sales_btn_in_app experiment' do
expect(controller).not_to receive(:track_experiment_event)
get_index
expect(response).to render_template('shared/billings/customers_dot_unavailable')
end
it 'does not record the user for the contact_sales_btn_in_app experiment' do
expect(controller).not_to receive(:record_experiment_user)
get_index
expect(response).to render_template('shared/billings/customers_dot_unavailable')
end
end
end end
end end
...@@ -315,6 +315,22 @@ RSpec.describe 'Billing plan pages', :feature, :js do ...@@ -315,6 +315,22 @@ RSpec.describe 'Billing plan pages', :feature, :js do
it_behaves_like 'plan with subscription table' it_behaves_like 'plan with subscription table'
it_behaves_like 'does not display EoA banner' it_behaves_like 'does not display EoA banner'
end end
context 'when CustomersDot is unavailable' do
let(:plan) { ultimate_plan }
let!(:subscription) { create(:gitlab_subscription, namespace: namespace, hosted_plan: plan) }
before do
stub_full_request("#{EE::SUBSCRIPTIONS_URL}/gitlab_plans?plan=#{plan.name}&namespace_id=#{namespace.id}")
.to_raise("Connection refused")
end
it 'renders an error page' do
visit page_path
expect(page).to have_content("Subscription service outage")
end
end
end end
context 'users profile billing page with a trial' do context 'users profile billing page with a trial' do
......
...@@ -18,80 +18,107 @@ RSpec.describe 'Groups > Billing', :js do ...@@ -18,80 +18,107 @@ RSpec.describe 'Groups > Billing', :js do
'.subscription-table' '.subscription-table'
end end
before do before_all do
stub_eoa_eligibility_request(group.id) group.add_owner(user)
stub_full_request("#{EE::SUBSCRIPTIONS_URL}/gitlab_plans?plan=#{plan}&namespace_id=#{group.id}") end
.with(headers: { 'Accept' => 'application/json' })
.to_return(status: 200, body: File.new(Rails.root.join('ee/spec/fixtures/gitlab_com_plans.json')))
before do
allow(Gitlab).to receive(:com?).and_return(true) allow(Gitlab).to receive(:com?).and_return(true)
stub_application_setting(check_namespace_plan: true) stub_application_setting(check_namespace_plan: true)
group.add_owner(user)
sign_in(user) sign_in(user)
end end
context 'with a free plan' do context 'when CustomersDot is available' do
let(:plan) { 'free' } before do
stub_eoa_eligibility_request(group.id)
let!(:subscription) do stub_full_request("#{EE::SUBSCRIPTIONS_URL}/gitlab_plans?plan=#{plan}&namespace_id=#{group.id}")
create(:gitlab_subscription, namespace: group, hosted_plan: nil, seats: 15) .with(headers: { 'Accept' => 'application/json' })
.to_return(status: 200, body: File.new(Rails.root.join('ee/spec/fixtures/gitlab_com_plans.json')))
end end
it 'shows the proper title and subscription data' do context 'with a free plan' do
visit group_billings_path(group) let(:plan) { 'free' }
expect(page).to have_content("#{group.name} is currently using the Free Plan") let!(:subscription) do
within subscription_table do create(:gitlab_subscription, namespace: group, hosted_plan: nil, seats: 15)
expect(page).to have_content("start date #{formatted_date(subscription.start_date)}") end
expect(page).to have_link("Upgrade", href: "#{EE::SUBSCRIPTIONS_URL}/subscriptions")
expect(page).not_to have_link("Manage") it 'shows the proper title and subscription data' do
visit group_billings_path(group)
expect(page).to have_content("#{group.name} is currently using the Free Plan")
within subscription_table do
expect(page).to have_content("start date #{formatted_date(subscription.start_date)}")
expect(page).to have_link("Upgrade", href: "#{EE::SUBSCRIPTIONS_URL}/subscriptions")
expect(page).not_to have_link("Manage")
end
end end
end end
end
context 'with a paid plan' do context 'with a paid plan' do
let(:plan) { 'bronze' } let(:plan) { 'bronze' }
let_it_be(:subscription) do let_it_be(:subscription) do
create(:gitlab_subscription, namespace: group, hosted_plan: bronze_plan, seats: 15) create(:gitlab_subscription, namespace: group, hosted_plan: bronze_plan, seats: 15)
end
it 'shows the proper title and subscription data' do
extra_seats_url = "#{EE::SUBSCRIPTIONS_URL}/gitlab/namespaces/#{group.id}/extra_seats"
renew_url = "#{EE::SUBSCRIPTIONS_URL}/gitlab/namespaces/#{group.id}/renew"
upgrade_url =
"#{EE::SUBSCRIPTIONS_URL}/gitlab/namespaces/#{group.id}/upgrade/bronze-external-id"
visit group_billings_path(group)
expect(page).to have_content("#{group.name} is currently using the Bronze Plan")
within subscription_table do
expect(page).to have_content("start date #{formatted_date(subscription.start_date)}")
expect(page).to have_link("Upgrade", href: upgrade_url)
expect(page).to have_link("Manage", href: "#{EE::SUBSCRIPTIONS_URL}/subscriptions")
expect(page).to have_link("Add seats", href: extra_seats_url)
expect(page).to have_link("Renew", href: renew_url)
expect(page).to have_link("See usage", href: group_seat_usage_path(group))
end
end
end end
it 'shows the proper title and subscription data' do context 'with a legacy paid plan' do
extra_seats_url = "#{EE::SUBSCRIPTIONS_URL}/gitlab/namespaces/#{group.id}/extra_seats" let(:plan) { 'bronze' }
renew_url = "#{EE::SUBSCRIPTIONS_URL}/gitlab/namespaces/#{group.id}/renew"
upgrade_url =
"#{EE::SUBSCRIPTIONS_URL}/gitlab/namespaces/#{group.id}/upgrade/bronze-external-id"
visit group_billings_path(group) let!(:subscription) do
create(:gitlab_subscription, end_date: 1.week.ago, namespace: group, hosted_plan: bronze_plan, seats: 15)
end
expect(page).to have_content("#{group.name} is currently using the Bronze Plan") it 'shows the proper title and subscription data' do
within subscription_table do visit group_billings_path(group)
expect(page).to have_content("start date #{formatted_date(subscription.start_date)}")
expect(page).to have_link("Upgrade", href: upgrade_url) expect(page).to have_content("#{group.name} is currently using the Bronze Plan")
expect(page).to have_link("Manage", href: "#{EE::SUBSCRIPTIONS_URL}/subscriptions") within subscription_table do
expect(page).to have_link("Add seats", href: extra_seats_url) expect(page).not_to have_link("Upgrade")
expect(page).to have_link("Renew", href: renew_url) expect(page).to have_link("Manage", href: "#{EE::SUBSCRIPTIONS_URL}/subscriptions")
expect(page).to have_link("See usage", href: group_seat_usage_path(group)) end
end end
end end
end end
context 'with a legacy paid plan' do context 'when CustomersDot is unavailable' do
before do
stub_full_request("#{EE::SUBSCRIPTIONS_URL}/gitlab_plans?plan=#{plan}&namespace_id=#{group.id}")
.with(headers: { 'Accept' => 'application/json' })
.to_raise("Connection refused")
end
let(:plan) { 'bronze' } let(:plan) { 'bronze' }
let!(:subscription) do let_it_be(:subscription) do
create(:gitlab_subscription, end_date: 1.week.ago, namespace: group, hosted_plan: bronze_plan, seats: 15) create(:gitlab_subscription, namespace: group, hosted_plan: bronze_plan, seats: 15)
end end
it 'shows the proper title and subscription data' do it 'renders an error page' do
visit group_billings_path(group) visit group_billings_path(group)
expect(page).to have_content("#{group.name} is currently using the Bronze Plan") expect(page).to have_content("Subscription service outage")
within subscription_table do
expect(page).not_to have_link("Upgrade")
expect(page).to have_link("Manage", href: "#{EE::SUBSCRIPTIONS_URL}/subscriptions")
end
end end
end end
end end
...@@ -88,6 +88,18 @@ RSpec.describe GitlabSubscriptions::FetchSubscriptionPlansService do ...@@ -88,6 +88,18 @@ RSpec.describe GitlabSubscriptions::FetchSubscriptionPlansService do
it 'returns nil' do it 'returns nil' do
is_expected.to be_nil is_expected.to be_nil
end end
it 'does not cache the result' do
service = described_class.new(plan: plan)
Rails.cache.with_local_cache do
service.execute
expect(Gitlab::HTTP).to receive(:get)
service.execute
end
end
end end
end end
end end
...@@ -31070,6 +31070,9 @@ msgstr "" ...@@ -31070,6 +31070,9 @@ msgstr ""
msgid "Subscription deletion failed." msgid "Subscription deletion failed."
msgstr "" msgstr ""
msgid "Subscription service outage"
msgstr ""
msgid "Subscription successfully applied to \"%{group_name}\"" msgid "Subscription successfully applied to \"%{group_name}\""
msgstr "" msgstr ""
...@@ -31974,6 +31977,9 @@ msgstr "" ...@@ -31974,6 +31977,9 @@ msgstr ""
msgid "The Compliance Dashboard gives you the ability to see a group's merge request activity by providing a high-level view for all projects in the group." msgid "The Compliance Dashboard gives you the ability to see a group's merge request activity by providing a high-level view for all projects in the group."
msgstr "" msgstr ""
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
msgid "The GitLab user to which the Jira user %{jiraDisplayName} will be mapped" msgid "The GitLab user to which the Jira user %{jiraDisplayName} will be mapped"
msgstr "" msgstr ""
......
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