Commit 72b97b20 authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch 'led/345373-move-pipeline-usage-quota-to-vue' into 'master'

PipelinesUsageApp: Buy Additional Minutes button

See merge request gitlab-org/gitlab!83021
parents 7cc9c5a2 f6392723
......@@ -232,35 +232,40 @@ export const trackTransaction = (transactionDetails) => {
pushEnhancedEcommerceEvent('EECtransactionSuccess', eventData);
};
export const trackAddToCartUsageTab = () => {
export const pushEECproductAddToCartEvent = () => {
if (!isSupported()) {
return;
}
const getStartedButton = document.querySelector('.js-buy-additional-minutes');
getStartedButton.addEventListener('click', () => {
window.dataLayer.push({
event: 'EECproductAddToCart',
ecommerce: {
currencyCode: 'USD',
add: {
products: [
{
name: 'CI/CD Minutes',
id: '0003',
price: '10',
brand: 'GitLab',
category: 'DevOps',
variant: 'add-on',
quantity: 1,
},
],
},
window.dataLayer.push({
event: 'EECproductAddToCart',
ecommerce: {
currencyCode: 'USD',
add: {
products: [
{
name: 'CI/CD Minutes',
id: '0003',
price: '10',
brand: 'GitLab',
category: 'DevOps',
variant: 'add-on',
quantity: 1,
},
],
},
});
},
});
};
export const trackAddToCartUsageTab = () => {
const getStartedButton = document.querySelector('.js-buy-additional-minutes');
if (!getStartedButton) {
return;
}
getStartedButton.addEventListener('click', pushEECproductAddToCartEvent);
};
export const trackCombinedGroupProjectForm = () => {
if (!isSupported()) {
return;
......
......@@ -88,6 +88,15 @@ module NamespacesHelper
}.to_json
end
def pipeline_usage_quota_app_data(namespace)
{
namespace_actual_plan_name: namespace.actual_plan_name,
namespace_path: namespace.full_path,
namespace_id: namespace.id,
page_size: page_size
}
end
private
# Many importers create a temporary Group, so use the real
......
<script>
import { GlButton } from '@gitlab/ui';
import { pushEECproductAddToCartEvent } from '~/google_tag_manager';
import { LABEL_BUY_ADDITIONAL_MINUTES } from '../constants';
export default {
name: 'PipelineUsageApp',
components: { GlButton },
inject: ['namespaceActualPlanName', 'buyAdditionalMinutesPath', 'buyAdditionalMinutesTarget'],
methods: {
trackBuyAdditionalMinutesClick() {
pushEECproductAddToCartEvent();
},
},
LABEL_BUY_ADDITIONAL_MINUTES,
};
</script>
<template>
<div>
<div
v-if="buyAdditionalMinutesPath && buyAdditionalMinutesTarget"
class="gl-display-flex gl-justify-content-end"
>
<gl-button
:href="buyAdditionalMinutesPath"
:target="buyAdditionalMinutesTarget"
:data-track-label="namespaceActualPlanName"
data-track-action="click_buy_ci_minutes"
data-track-property="pipeline_quota_page"
data-testid="buy-additional-minutes-button"
category="primary"
variant="confirm"
@click="trackBuyAdditionalMinutesClick"
>
{{ $options.LABEL_BUY_ADDITIONAL_MINUTES }}
</gl-button>
</div>
</div>
</template>
import { s__ } from '~/locale';
export const LABEL_BUY_ADDITIONAL_MINUTES = s__('UsageQuota|Buy additional minutes');
import Vue from 'vue';
import PipelineUsageApp from './components/app.vue';
export default () => {
const el = document.getElementById('js-pipeline-usage-app');
if (!el) {
return false;
}
const {
namespaceActualPlanName,
buyAdditionalMinutesPath,
buyAdditionalMinutesTarget,
} = el.dataset;
return new Vue({
el,
name: 'PipelinesUsageView',
provide: {
namespaceActualPlanName,
buyAdditionalMinutesPath,
buyAdditionalMinutesTarget,
},
render(createElement) {
return createElement(PipelineUsageApp);
},
});
};
......@@ -67,6 +67,16 @@ module EE
namespace.root_ancestor.free_plan? && !minute_limit_banner_dismissed?
end
override :pipeline_usage_quota_app_data
def pipeline_usage_quota_app_data(namespace)
return super unless ::Gitlab::CurrentSettings.should_check_namespace_plan?
super.merge(
buy_additional_minutes_path: buy_additional_minutes_path(namespace),
buy_additional_minutes_target: buy_addon_target_attr(namespace)
)
end
private
def use_customers_dot_for_addon_path?(namespace)
......
import { GlButton } from '@gitlab/ui';
import { pushEECproductAddToCartEvent } from '~/google_tag_manager';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import PipelineUsageApp from 'ee/usage_quotas/pipelines/components/app.vue';
import { LABEL_BUY_ADDITIONAL_MINUTES } from 'ee/usage_quotas/pipelines/constants';
import { defaultProvide } from '../mock_data';
jest.mock('~/google_tag_manager');
describe('PipelineUsageApp', () => {
let wrapper;
const findBuyAdditionalMinutesButton = () =>
wrapper.findByTestId('buy-additional-minutes-button');
const createComponent = ({ provide = {} } = {}) => {
wrapper = shallowMountExtended(PipelineUsageApp, {
provide: {
...defaultProvide,
...provide,
},
stubs: {
GlButton,
},
});
};
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
describe('Buy additional minutes Button', () => {
it('calls pushEECproductAddToCartEvent on click', async () => {
findBuyAdditionalMinutesButton().trigger('click');
expect(pushEECproductAddToCartEvent).toHaveBeenCalledTimes(1);
});
describe('Gitlab SaaS: valid data for buyAdditionalMinutesPath and buyAdditionalMinutesTarget', () => {
it('renders the button to buy additional minutes', () => {
expect(findBuyAdditionalMinutesButton().exists()).toBe(true);
expect(findBuyAdditionalMinutesButton().text()).toBe(LABEL_BUY_ADDITIONAL_MINUTES);
});
});
describe('Gitlab Self-Managed: buyAdditionalMinutesPath and buyAdditionalMinutesTarget not provided', () => {
beforeEach(() => {
createComponent({
provide: {
buyAdditionalMinutesPath: undefined,
buyAdditionalMinutesTarget: undefined,
},
});
});
it('does not render the button to buy additional minutes', () => {
expect(findBuyAdditionalMinutesButton().exists()).toBe(false);
});
});
});
});
import { TEST_HOST } from 'helpers/test_constants';
export const defaultProvide = {
namespaceActualPlanName: 'MyGroup',
buyAdditionalMinutesPath: `${TEST_HOST}/-/subscriptions/buy_minutes?selected_group=12345`,
buyAdditionalMinutesTarget: '_self',
};
......@@ -264,4 +264,34 @@ RSpec.describe EE::NamespacesHelper do
end
end
end
describe '#pipeline_usage_quota_app_data' do
context 'Gitlab SaaS', :saas do
before do
stub_ee_application_setting(should_check_namespace_plan: true)
end
it 'returns a hash with buy_additional_minutes data' do
expect(helper.pipeline_usage_quota_app_data(user_group)).to eql({
namespace_actual_plan_name: user_group.actual_plan_name,
namespace_path: user_group.full_path,
namespace_id: user_group.id,
page_size: Kaminari.config.default_per_page,
buy_additional_minutes_path: EE::SUBSCRIPTIONS_MORE_MINUTES_URL,
buy_additional_minutes_target: '_blank'
})
end
end
context 'Gitlab Self-Managed' do
it 'returns a hash without buy_additional_minutes data' do
expect(helper.pipeline_usage_quota_app_data(user_group)).to eql({
namespace_actual_plan_name: user_group.actual_plan_name,
namespace_path: user_group.full_path,
namespace_id: user_group.id,
page_size: Kaminari.config.default_per_page
})
end
end
end
end
......@@ -268,4 +268,15 @@ RSpec.describe NamespacesHelper do
end
end
end
describe '#pipeline_usage_quota_app_data' do
it 'returns a hash with necessary data for the frontend' do
expect(helper.pipeline_usage_quota_app_data(user_group)).to eql({
namespace_actual_plan_name: user_group.actual_plan_name,
namespace_path: user_group.full_path,
namespace_id: user_group.id,
page_size: Kaminari.config.default_per_page
})
end
end
end
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