Commit df0f7313 authored by Serhii Yarynovskyi's avatar Serhii Yarynovskyi Committed by Kushal Pandya

Add additional tracking for billings page

parent e82febf9
- return unless Gitlab::Tracking.enabled? - return unless Gitlab::Tracking.enabled?
- namespace = @group || @project&.namespace - namespace = @group || @project&.namespace || @namespace
= javascript_tag do = javascript_tag do
:plain :plain
......
...@@ -2,6 +2,8 @@ import Api from 'ee/api'; ...@@ -2,6 +2,8 @@ import Api from 'ee/api';
import { PAYMENT_FORM_ID } from 'ee/subscriptions/constants'; import { PAYMENT_FORM_ID } from 'ee/subscriptions/constants';
import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants'; import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants';
import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/activate_next_step.mutation.graphql'; import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/activate_next_step.mutation.graphql';
import Tracking from '~/tracking';
import { addExperimentContext } from '~/tracking/utils';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { redirectTo } from '~/lib/utils/url_utility'; import { redirectTo } from '~/lib/utils/url_utility';
import { sprintf, s__ } from '~/locale'; import { sprintf, s__ } from '~/locale';
...@@ -9,6 +11,16 @@ import { trackCheckout, trackTransaction } from '~/google_tag_manager'; ...@@ -9,6 +11,16 @@ import { trackCheckout, trackTransaction } from '~/google_tag_manager';
import defaultClient from '../graphql'; import defaultClient from '../graphql';
import * as types from './mutation_types'; import * as types from './mutation_types';
const trackConfirmOrder = (message) =>
Tracking.event(
'default',
'click_button',
addExperimentContext({
label: 'confirm_purchase',
property: message,
}),
);
export const updateSelectedPlan = ({ commit, getters }, selectedPlan) => { export const updateSelectedPlan = ({ commit, getters }, selectedPlan) => {
commit(types.UPDATE_SELECTED_PLAN, selectedPlan); commit(types.UPDATE_SELECTED_PLAN, selectedPlan);
trackCheckout(selectedPlan, getters.confirmOrderParams?.subscription?.quantity); trackCheckout(selectedPlan, getters.confirmOrderParams?.subscription?.quantity);
...@@ -202,15 +214,20 @@ export const confirmOrder = ({ getters, dispatch, commit }) => { ...@@ -202,15 +214,20 @@ export const confirmOrder = ({ getters, dispatch, commit }) => {
}; };
trackTransaction(transactionDetails); trackTransaction(transactionDetails);
trackConfirmOrder(s__('Checkout|Success: subscription'));
dispatch('confirmOrderSuccess', { dispatch('confirmOrderSuccess', {
location: data.location, location: data.location,
}); });
} else { } else {
trackConfirmOrder(data.errors);
dispatch('confirmOrderError', JSON.stringify(data.errors)); dispatch('confirmOrderError', JSON.stringify(data.errors));
} }
}) })
.catch(() => dispatch('confirmOrderError')); .catch((e) => {
trackConfirmOrder(e.message);
dispatch('confirmOrderError');
});
}; };
export const confirmOrderSuccess = (_, { location }) => { export const confirmOrderSuccess = (_, { location }) => {
......
...@@ -36,8 +36,10 @@ class SubscriptionsController < ApplicationController ...@@ -36,8 +36,10 @@ class SubscriptionsController < ApplicationController
def new def new
if current_user if current_user
@namespace = current_user.namespace
experiment(:cart_abandonment_modal, experiment(:cart_abandonment_modal,
namespace: current_user.namespace, namespace: @namespace,
user: current_user, user: current_user,
sticky_to: current_user sticky_to: current_user
).run ).run
......
- Gitlab::Tracking.event(body_data_page, 'render',
label: 'purchase_confirmation_banner_displayed',
user: current_user,
namespace: @group)
%section.gl-banner.gl-banner-introduction{ data: { uid: 'purchase_success_banner_dismissed' } } %section.gl-banner.gl-banner-introduction{ data: { uid: 'purchase_success_banner_dismissed' } }
.gl-banner-illustration .gl-banner-illustration
= image_tag('illustrations/illustration-congratulation-purchase.svg', alt: _('Successful purchase image')) = image_tag('illustrations/illustration-congratulation-purchase.svg', alt: _('Successful purchase image'))
......
...@@ -4,4 +4,9 @@ ...@@ -4,4 +4,9 @@
= render "layouts/one_trust" = render "layouts/one_trust"
= render "layouts/google_tag_manager_body" = render "layouts/google_tag_manager_body"
- Gitlab::Tracking.event(body_data_page, 'render',
label: 'saas_checkout',
user: current_user,
namespace: @namespace)
#js-new-subscription{ data: subscription_data(@eligible_groups) } #js-new-subscription{ data: subscription_data(@eligible_groups) }
...@@ -7,6 +7,7 @@ import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants'; ...@@ -7,6 +7,7 @@ import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants';
import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/activate_next_step.mutation.graphql'; import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/activate_next_step.mutation.graphql';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper'; import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import testAction from 'helpers/vuex_action_helper'; import testAction from 'helpers/vuex_action_helper';
import Tracking from '~/tracking';
import createFlash from '~/flash'; import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import * as googleTagManager from '~/google_tag_manager'; import * as googleTagManager from '~/google_tag_manager';
...@@ -537,57 +538,85 @@ describe('Subscriptions Actions', () => { ...@@ -537,57 +538,85 @@ describe('Subscriptions Actions', () => {
}); });
describe('confirmOrder', () => { describe('confirmOrder', () => {
it('calls confirmOrderSuccess with a redirect location on success', async () => { describe('on success', () => {
const response = { location: 'x' }; const payload = { location: 'x' };
mock.onPost(confirmOrderPath).replyOnce(200, response);
await testAction( beforeEach(() => mock.onPost(confirmOrderPath).replyOnce(200, payload));
actions.confirmOrder,
null,
{},
[{ type: 'UPDATE_IS_CONFIRMING_ORDER', payload: true }],
[{ type: 'confirmOrderSuccess', payload: response }],
);
});
it('calls trackTransaction on success', async () => { it('calls trackTransaction', async () => {
const spy = jest.spyOn(googleTagManager, 'trackTransaction'); const spy = jest.spyOn(googleTagManager, 'trackTransaction');
const response = { location: 'x' };
mock.onPost(confirmOrderPath).replyOnce(200, response);
await testAction( await testAction(
actions.confirmOrder, actions.confirmOrder,
null, null,
{}, {},
[{ type: 'UPDATE_IS_CONFIRMING_ORDER', payload: true }], [{ type: 'UPDATE_IS_CONFIRMING_ORDER', payload: true }],
[{ type: 'confirmOrderSuccess', payload: response }], [{ type: 'confirmOrderSuccess', payload }],
); );
expect(spy).toHaveBeenCalled();
});
it('calls tracking event', async () => {
const spy = jest.spyOn(Tracking, 'event');
expect(spy).toHaveBeenCalled(); await testAction(
actions.confirmOrder,
null,
{},
[{ type: 'UPDATE_IS_CONFIRMING_ORDER', payload: true }],
[{ type: 'confirmOrderSuccess', payload }],
);
expect(spy).toHaveBeenCalledWith('default', 'click_button', {
label: 'confirm_purchase',
property: 'Success: subscription',
});
});
}); });
it('calls confirmOrderError with the errors on error', async () => { describe('on error', () => {
mock.onPost(confirmOrderPath).replyOnce(200, { errors: 'errors' }); const errors = 'errors';
await testAction( beforeEach(() => mock.onPost(confirmOrderPath).replyOnce(200, { errors }));
actions.confirmOrder,
null, it('calls tracking event', async () => {
{}, const spy = jest.spyOn(Tracking, 'event');
[{ type: 'UPDATE_IS_CONFIRMING_ORDER', payload: true }],
[{ type: 'confirmOrderError', payload: '"errors"' }], await testAction(
); actions.confirmOrder,
null,
{},
[{ type: 'UPDATE_IS_CONFIRMING_ORDER', payload: true }],
[{ type: 'confirmOrderError', payload: '"errors"' }],
);
expect(spy).toHaveBeenCalledWith('default', 'click_button', {
label: 'confirm_purchase',
property: errors,
});
});
}); });
it('calls confirmOrderError on failure', async () => { describe('on failure', () => {
mock.onPost(confirmOrderPath).replyOnce(500); beforeEach(() => mock.onPost(confirmOrderPath).replyOnce(500));
await testAction( it('calls tracking event', async () => {
actions.confirmOrder, const spy = jest.spyOn(Tracking, 'event');
null,
{}, await testAction(
[{ type: 'UPDATE_IS_CONFIRMING_ORDER', payload: true }], actions.confirmOrder,
[{ type: 'confirmOrderError' }], null,
); {},
[{ type: 'UPDATE_IS_CONFIRMING_ORDER', payload: true }],
[{ type: 'confirmOrderError' }],
);
expect(spy).toHaveBeenCalledWith('default', 'click_button', {
label: 'confirm_purchase',
property: 'Request failed with status code 500',
});
});
}); });
}); });
......
...@@ -3,18 +3,33 @@ ...@@ -3,18 +3,33 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe 'subscriptions/groups/edit' do RSpec.describe 'subscriptions/groups/edit' do
let(:group) { Group.new }
let(:user) { User.new }
before do before do
assign(:group, Group.new) assign(:group, group)
allow(view).to receive(:params).and_return(quantity: quantity) allow(view).to receive(:params).and_return(quantity: quantity)
allow(view).to receive(:plan_title).and_return('Bronze') allow(view).to receive(:plan_title).and_return('Bronze')
allow(view).to receive(:group_path).and_return('') allow(view).to receive(:group_path).and_return('')
allow(view).to receive(:subscriptions_groups_path).and_return('') allow(view).to receive(:subscriptions_groups_path).and_return('')
allow(view).to receive(:current_user).and_return(User.new) allow(view).to receive(:current_user).and_return(user)
end end
let(:quantity) { '1' } let(:quantity) { '1' }
it 'tracks purchase banner', :snowplow do
render
expect_snowplow_event(
category: 'subscriptions:groups',
action: 'render',
label: 'purchase_confirmation_banner_displayed',
namespace: group,
user: user
)
end
context 'a single user' do context 'a single user' do
it 'displays the correct notification for 1 user' do it 'displays the correct notification for 1 user' do
render render
......
...@@ -7348,6 +7348,9 @@ msgstr "" ...@@ -7348,6 +7348,9 @@ msgstr ""
msgid "Checkout|Subtotal" msgid "Checkout|Subtotal"
msgstr "" msgstr ""
msgid "Checkout|Success: subscription"
msgstr ""
msgid "Checkout|Tax" msgid "Checkout|Tax"
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