Commit 25537d4c authored by Diana Zubova's avatar Diana Zubova Committed by Andrew Fontaine

Add a new route for storage purchase

Add a simple page for it
parent 5fcf9c4e
---
name: new_route_storage_purchase
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68834
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/327896
milestone: '14.3'
type: development
group: group::purchase
default_enabled: false
import mountSubscriptionsApplication from 'ee/subscriptions/buy_storage';
mountSubscriptionsApplication(document.getElementById('js-buy-storage'));
<script>
import StepOrderApp from 'ee/vue_shared/purchase_flow/components/step_order_app.vue';
export default {
components: {
StepOrderApp,
},
};
</script>
<template>
<step-order-app>
<template #checkout></template>
<template #order-summary></template>
</step-order-app>
</template>
import Vue from 'vue';
import App from './components/app.vue';
export default (el) => {
return new Vue({
el,
components: {
App,
},
render(createElement) {
return createElement(App);
},
});
};
......@@ -41,6 +41,16 @@ class SubscriptionsController < ApplicationController
render_404 unless Feature.enabled?(:new_route_ci_minutes_purchase, @group, default_enabled: :yaml)
end
def buy_storage
return render_404 unless storage_plan_data.present?
@group = find_group(plan_id: storage_plan_data["id"])
return render_404 if @group.nil?
render_404 unless Feature.enabled?(:new_route_storage_purchase, @group, default_enabled: :yaml)
end
def payment_form
response = client.payment_form_params(params[:id])
render json: response[:data]
......@@ -128,6 +138,14 @@ class SubscriptionsController < ApplicationController
end
end
def storage_plan_data
strong_memoize(:storage_plan_data) do
plan_response = client.get_plans(tags: ['STORAGE_PLAN'])
plan_response[:success] ? plan_response[:data].first : nil
end
end
def load_eligible_groups
return @eligible_groups = [] unless current_user
......
......@@ -22,6 +22,12 @@ module SubscriptionsHelper
}.merge(addon_data(group))
end
def buy_storage_addon_data(group)
{
redirect_after_success: group_usage_quotas_path(group, anchor: 'pipelines-quota-tab', purchased_product: _('Storage'))
}.merge(addon_data(group))
end
def addon_data(group)
{
group_data: [present_group(group)].to_json,
......
- page_title _('Buy Storage')
#js-buy-storage{ data: buy_storage_addon_data(@group) }
......@@ -2,6 +2,7 @@
resource :subscriptions, only: [:new, :create] do
get :buy_minutes
get :buy_storage
get :payment_form
get :payment_method
......
......@@ -14,6 +14,7 @@ RSpec.describe SubscriptionsController do
expected_subscription_path = new_subscriptions_path(plan_id: 'bronze_id') if redirect_from == 'checkout'
expected_subscription_path = buy_minutes_subscriptions_path(plan_id: 'bronze_id') if redirect_from == 'buy_minutes'
expected_subscription_path = buy_storage_subscriptions_path(plan_id: 'bronze_id') if redirect_from == 'buy_storage'
expect(controller.stored_location_for(:user)).to eq(expected_subscription_path)
end
......@@ -82,7 +83,6 @@ RSpec.describe SubscriptionsController do
context 'with authenticated user' do
before do
group.add_owner(user)
stub_feature_flags(new_route_ci_minutes_purchase: false)
stub_feature_flags(new_route_ci_minutes_purchase: group)
sign_in(user)
end
......@@ -146,6 +146,71 @@ RSpec.describe SubscriptionsController do
end
end
describe 'GET #buy_storage' do
let_it_be(:group) { create(:group) }
subject { get :buy_storage, params: { selected_group: group.id } }
context 'with authenticated user' do
before do
group.add_owner(user)
stub_feature_flags(new_route_storage_purchase: group)
sign_in(user)
end
context 'when the add-on plan cannot be found' do
let_it_be(:group) { create(:group) }
before do
group.add_owner(user)
allow(Gitlab::SubscriptionPortal::Client)
.to receive(:get_plans).with(tags: ['STORAGE_PLAN'])
.and_return({ success: false, data: [] })
end
it { is_expected.to have_gitlab_http_status(:not_found) }
end
context 'with :new_route_storage_purchase enabled' do
let_it_be(:group) { create(:group) }
before do
group.add_owner(user)
allow(Gitlab::SubscriptionPortal::Client)
.to receive(:get_plans).with(tags: ['STORAGE_PLAN'])
.and_return({ success: true, data: [{ 'id' => 'storage' }] })
allow_next_instance_of(
GitlabSubscriptions::FilterPurchaseEligibleNamespacesService,
user: user,
plan_id: 'storage',
namespaces: [group]
) do |instance|
allow(instance).to receive(:execute).and_return(instance_double(ServiceResponse, success?: true, payload: [group]))
end
end
it { is_expected.to render_template 'layouts/checkout' }
it { is_expected.to render_template :buy_storage }
end
end
context 'with :new_route_storage_purchase disabled' do
before do
allow(Gitlab::SubscriptionPortal::Client)
.to receive(:get_plans).with(tags: ['STORAGE_PLAN'])
.and_return({ success: true, data: [{ 'id' => 'ci_minutes' }] })
stub_feature_flags(new_route_ci_minutes_purchase: false)
sign_in(user)
end
it { is_expected.to have_gitlab_http_status(:not_found) }
end
end
describe 'GET #payment_form' do
subject { get :payment_form, params: { id: 'cc' } }
......
......@@ -167,4 +167,22 @@ RSpec.describe SubscriptionsHelper do
it { is_expected.to include(group_data: %Q{[{"id":#{group.id},"name":"My Namespace","users":1,"guests":0}]}) }
it { is_expected.to include(redirect_after_success: group_usage_quotas_path(group, anchor: 'pipelines-quota-tab', purchased_product: 'CI minutes')) }
end
describe '#buy_storage_addon_data' do
subject(:buy_storage_addon_data) { helper.buy_storage_addon_data(group) }
let_it_be(:user) { create(:user, name: 'First Last') }
let_it_be(:group) { create(:group, name: 'My Namespace') }
before do
allow(helper).to receive(:current_user).and_return(user)
allow(helper).to receive(:params).and_return({ selected_group: group.id.to_s, source: 'some_source' })
group.add_owner(user)
end
it { is_expected.to include(namespace_id: group.id.to_s) }
it { is_expected.to include(source: 'some_source') }
it { is_expected.to include(group_data: %Q{[{"id":#{group.id},"name":"My Namespace","users":1,"guests":0}]}) }
it { is_expected.to include(redirect_after_success: group_usage_quotas_path(group, anchor: 'pipelines-quota-tab', purchased_product: 'Storage')) }
end
end
......@@ -39,3 +39,23 @@ RSpec.shared_examples_for 'buy minutes addon form data' do |js_selector|
it { is_expected.to have_selector("#{js_selector}[data-source='some_source']") }
it { is_expected.to have_selector("#{js_selector}[data-redirect-after-success='/groups/my-ci-minutes-group/-/usage_quotas']") }
end
RSpec.shared_examples_for 'buy storage addon form data' do |js_selector|
before do
allow(view).to receive(:buy_storage_addon_data).and_return(
group_data: '[{"id":"storage_plan_id","code":"storage","price_per_year":10.0}]',
namespace_id: '2',
plan_id: 'storage_plan_id',
source: 'some_source',
redirect_after_success: '/groups/my-group/-/usage_quotas'
)
end
subject { render }
it { is_expected.to have_selector("#{js_selector}[data-group-data='[{\"id\":\"storage_plan_id\",\"code\":\"storage\",\"price_per_year\":10.0}]']") }
it { is_expected.to have_selector("#{js_selector}[data-plan-id='storage_plan_id']") }
it { is_expected.to have_selector("#{js_selector}[data-namespace-id='2']") }
it { is_expected.to have_selector("#{js_selector}[data-source='some_source']") }
it { is_expected.to have_selector("#{js_selector}[data-redirect-after-success='/groups/my-group/-/usage_quotas']") }
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'subscriptions/buy_storage' do
it_behaves_like 'buy storage addon form data', '#js-buy-storage'
end
......@@ -5888,6 +5888,9 @@ msgstr ""
msgid "Buy CI Minutes"
msgstr ""
msgid "Buy Storage"
msgstr ""
msgid "Buy more Pipeline minutes"
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