Commit db7f3998 authored by Serhii Yarynovskyi's avatar Serhii Yarynovskyi Committed by Doug Stull

Change Update button to Contact sales

Add group_contact_sales feature flag
to change Upgrade to Ultimate button
to Contact sales button on the groups:show page
parent 8f2499da
...@@ -44,6 +44,7 @@ export const POPOVER = { ...@@ -44,6 +44,7 @@ export const POPOVER = {
trackingEvents: { trackingEvents: {
popoverShown: { action: 'popover_shown', label: 'trial_status_popover' }, popoverShown: { action: 'popover_shown', label: 'trial_status_popover' },
closeBtnClick: { action: CLICK_BUTTON_ACTION, label: 'close_popover' }, closeBtnClick: { action: CLICK_BUTTON_ACTION, label: 'close_popover' },
contactSalesBtnClick: { action: CLICK_BUTTON_ACTION, label: 'contact_sales' },
upgradeBtnClick: { action: CLICK_BUTTON_ACTION, label: 'upgrade_to_ultimate' }, upgradeBtnClick: { action: CLICK_BUTTON_ACTION, label: 'upgrade_to_ultimate' },
compareBtnClick: { action: CLICK_BUTTON_ACTION, label: 'compare_all_plans' }, compareBtnClick: { action: CLICK_BUTTON_ACTION, label: 'compare_all_plans' },
}, },
......
...@@ -3,6 +3,8 @@ import { GlButton, GlPopover, GlSprintf } from '@gitlab/ui'; ...@@ -3,6 +3,8 @@ import { GlButton, GlPopover, GlSprintf } from '@gitlab/ui';
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils'; import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { removeTrialSuffix } from 'ee/billings/billings_util'; import { removeTrialSuffix } from 'ee/billings/billings_util';
import { shouldHandRaiseLeadButtonMount } from 'ee/hand_raise_leads/hand_raise_lead';
import GitlabExperiment from '~/experimentation/components/gitlab_experiment.vue';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import { formatDate } from '~/lib/utils/datetime_utility'; import { formatDate } from '~/lib/utils/datetime_utility';
import { sprintf } from '~/locale'; import { sprintf } from '~/locale';
...@@ -29,6 +31,7 @@ export default { ...@@ -29,6 +31,7 @@ export default {
GlButton, GlButton,
GlPopover, GlPopover,
GlSprintf, GlSprintf,
GitlabExperiment,
}, },
mixins: [trackingMixin], mixins: [trackingMixin],
inject: { inject: {
...@@ -43,6 +46,7 @@ export default { ...@@ -43,6 +46,7 @@ export default {
trialEndDate: {}, trialEndDate: {},
userCalloutsPath: {}, userCalloutsPath: {},
userCalloutsFeatureId: {}, userCalloutsFeatureId: {},
user: {},
}, },
data() { data() {
return { return {
...@@ -66,6 +70,14 @@ export default { ...@@ -66,6 +70,14 @@ export default {
planName: removeTrialSuffix(this.planName), planName: removeTrialSuffix(this.planName),
}); });
}, },
trackingPropertyAndValue() {
return {
property: this.forciblyShowing
? TRACKING_PROPERTY_WHEN_FORCED
: TRACKING_PROPERTY_WHEN_VOLUNTARY,
value: this.daysRemaining,
};
},
}, },
created() { created() {
this.debouncedResize = debounce(() => this.onResize(), resizeEventDebounceMS); this.debouncedResize = debounce(() => this.onResize(), resizeEventDebounceMS);
...@@ -85,12 +97,14 @@ export default { ...@@ -85,12 +97,14 @@ export default {
window.removeEventListener(RESIZE_EVENT, this.debouncedResize); window.removeEventListener(RESIZE_EVENT, this.debouncedResize);
}, },
methods: { methods: {
trackPageAction(eventName) {
const { action, ...options } = trackingEvents[eventName];
this.track(action, { ...options, ...this.trackingPropertyAndValue });
},
onClose() { onClose() {
this.forciblyShowing = false; this.forciblyShowing = false;
this.show = false; this.show = false;
this.trackPageAction('closeBtnClick');
const { action, ...options } = trackingEvents.closeBtnClick;
this.track(action, { ...options, ...this.trackingPropertyAndValue() });
}, },
onForciblyShown() { onForciblyShown() {
if (this.userCalloutsPath && this.userCalloutsFeatureId) { if (this.userCalloutsPath && this.userCalloutsFeatureId) {
...@@ -108,24 +122,8 @@ export default { ...@@ -108,24 +122,8 @@ export default {
this.updateDisabledState(); this.updateDisabledState();
}, },
onShown() { onShown() {
const { action, ...options } = trackingEvents.popoverShown; this.trackPageAction('popoverShown');
this.track(action, { ...options, ...this.trackingPropertyAndValue() }); shouldHandRaiseLeadButtonMount();
},
onUpgradeBtnClick() {
const { action, ...options } = trackingEvents.upgradeBtnClick;
this.track(action, { ...options, ...this.trackingPropertyAndValue() });
},
onCompareBtnClick() {
const { action, ...options } = trackingEvents.compareBtnClick;
this.track(action, { ...options, ...this.trackingPropertyAndValue() });
},
trackingPropertyAndValue() {
return {
property: this.forciblyShowing
? TRACKING_PROPERTY_WHEN_FORCED
: TRACKING_PROPERTY_WHEN_VOLUNTARY,
value: this.daysRemaining,
};
}, },
updateDisabledState() { updateDisabledState() {
this.disabled = disabledBreakpoints.includes(bp.getBreakpointSize()); this.disabled = disabledBreakpoints.includes(bp.getBreakpointSize());
...@@ -170,18 +168,37 @@ export default { ...@@ -170,18 +168,37 @@ export default {
</gl-sprintf> </gl-sprintf>
<div class="gl-mt-5"> <div class="gl-mt-5">
<gl-button <gitlab-experiment name="group_contact_sales">
:href="purchaseHref" <template #control>
category="primary" <gl-button
variant="confirm" ref="upgradeBtn"
size="small" category="primary"
class="gl-mb-0" variant="confirm"
block size="small"
data-testid="upgradeBtn" class="gl-mb-0"
@click="onUpgradeBtnClick" block
> :href="purchaseHref"
<span class="gl-font-sm">{{ upgradeButtonTitle }}</span> @click="trackPageAction('upgradeBtnClick')"
</gl-button> >
<span class="gl-font-sm">{{ upgradeButtonTitle }}</span>
</gl-button>
</template>
<template #candidate>
<div data-testid="contactSalesBtn" @click="trackPageAction('contactSalesBtnClick')">
<div
class="js-hand-raise-lead-button"
:data-namespace-id="user.namespaceId"
:data-user-name="user.userName"
:data-first-name="user.firstName"
:data-last-name="user.lastName"
:data-company-name="user.companyName"
:data-glm-content="user.glmContent"
small
></div>
</div>
</template>
</gitlab-experiment>
<gl-button <gl-button
:href="plansHref" :href="plansHref"
...@@ -192,7 +209,7 @@ export default { ...@@ -192,7 +209,7 @@ export default {
block block
data-testid="compareBtn" data-testid="compareBtn"
:title="$options.i18n.compareAllButtonTitle" :title="$options.i18n.compareAllButtonTitle"
@click="onCompareBtnClick" @click="trackPageAction('compareBtnClick')"
> >
<span class="gl-font-sm">{{ $options.i18n.compareAllButtonTitle }}</span> <span class="gl-font-sm">{{ $options.i18n.compareAllButtonTitle }}</span>
</gl-button> </gl-button>
......
...@@ -47,6 +47,12 @@ export const initTrialStatusPopover = () => { ...@@ -47,6 +47,12 @@ export const initTrialStatusPopover = () => {
trialEndDate, trialEndDate,
userCalloutsPath, userCalloutsPath,
userCalloutsFeatureId, userCalloutsFeatureId,
namespaceId,
userName,
firstName,
lastName,
companyName,
glmContent,
} = el.dataset; } = el.dataset;
return new Vue({ return new Vue({
...@@ -63,6 +69,14 @@ export const initTrialStatusPopover = () => { ...@@ -63,6 +69,14 @@ export const initTrialStatusPopover = () => {
trialEndDate: new Date(trialEndDate), trialEndDate: new Date(trialEndDate),
userCalloutsPath, userCalloutsPath,
userCalloutsFeatureId, userCalloutsFeatureId,
user: {
namespaceId,
userName,
firstName,
lastName,
companyName,
glmContent,
},
}, },
render: (createElement) => createElement(TrialStatusPopover), render: (createElement) => createElement(TrialStatusPopover),
}); });
......
...@@ -57,7 +57,7 @@ export default { ...@@ -57,7 +57,7 @@ export default {
autofocusonshow, autofocusonshow,
}, },
mixins: [Tracking.mixin()], mixins: [Tracking.mixin()],
inject: ['user'], inject: ['user', 'small'],
data() { data() {
return { return {
isLoading: false, isLoading: false,
...@@ -233,9 +233,17 @@ export default { ...@@ -233,9 +233,17 @@ export default {
<template> <template>
<div> <div>
<gl-button v-gl-modal.hand-raise-lead :loading="isLoading"> <gl-button
{{ $options.i18n.buttonText }} v-gl-modal.hand-raise-lead
:loading="isLoading"
:href="small ? '#' : ''"
:variant="small ? 'confirm' : 'default'"
:size="small ? 'small' : 'medium'"
:class="{ 'gl-mb-3 gl-w-full': small }"
>
<span :class="{ 'gl-font-sm': small }">{{ $options.i18n.buttonText }}</span>
</gl-button> </gl-button>
<gl-modal <gl-modal
ref="modal" ref="modal"
modal-id="hand-raise-lead" modal-id="hand-raise-lead"
......
...@@ -9,6 +9,7 @@ export const initHandRaiseLeadButton = (el) => { ...@@ -9,6 +9,7 @@ export const initHandRaiseLeadButton = (el) => {
el, el,
apolloProvider, apolloProvider,
provide: { provide: {
small: Boolean(el.hasAttribute('small')),
user: { user: {
namespaceId, namespaceId,
userName, userName,
......
...@@ -39,6 +39,7 @@ export default () => { ...@@ -39,6 +39,7 @@ export default () => {
SecurityDiscoverApp, SecurityDiscoverApp,
}, },
provide: { provide: {
small: false,
user: { user: {
namespaceId, namespaceId,
userName, userName,
......
...@@ -12,7 +12,13 @@ module TrialStatusWidgetHelper ...@@ -12,7 +12,13 @@ module TrialStatusWidgetHelper
D3_CALLOUT_ID = 'trial_status_reminder_d3' D3_CALLOUT_ID = 'trial_status_reminder_d3'
def trial_status_popover_data_attrs(group) def trial_status_popover_data_attrs(group)
base_attrs = trial_status_common_data_attrs(group) hand_raise_attrs = experiment(:group_contact_sales, namespace: group.root_ancestor, user: current_user, sticky_to: current_user) do |e|
e.control { {} }
e.candidate { hand_raise_props(group, glm_content: 'trial-status-show-group') }
end.run
base_attrs = trial_status_common_data_attrs(group).merge(hand_raise_attrs)
base_attrs.merge( base_attrs.merge(
days_remaining: group.trial_days_remaining, # for experiment tracking days_remaining: group.trial_days_remaining, # for experiment tracking
group_name: group.name, group_name: group.name,
......
---
name: group_contact_sales
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77327
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348346
milestone: '14.8'
type: experiment
group: group::conversion
default_enabled: false
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TrialStatusPopover component matches the snapshot 1`] = ` exports[`TrialStatusPopover component group_contact_sales experiment candidate matches the snapshot 1`] = `
<gl-popover-stub
boundary="viewport"
cssclasses=""
delay="[object Object]"
placement="rightbottom"
target="target-element-identifier"
triggers="hover focus"
>
<gl-sprintf-stub
message="Your trial ends on %{boldStart}%{trialEndDate}%{boldEnd}. We hope you’re enjoying the features of GitLab %{planName}. To keep those features after your trial ends, you’ll need to buy a subscription. (You can also choose GitLab Premium if it meets your needs.)"
/>
<div
class="gl-mt-5"
>
<div
data-testid="contactSalesBtn"
>
<div
class="js-hand-raise-lead-button"
data-company-name="companyName"
data-first-name="firstName"
data-glm-content="glmContent"
data-last-name="lastName"
data-namespace-id="namespaceId"
data-user-name="userName"
small=""
/>
</div>
<gl-button-stub
block=""
buttontextclasses=""
category="secondary"
class="gl-mb-0"
data-testid="compareBtn"
href="billing/path-for/group"
icon=""
size="small"
title="Compare all plans"
variant="confirm"
>
<span
class="gl-font-sm"
>
Compare all plans
</span>
</gl-button-stub>
</div>
</gl-popover-stub>
`;
exports[`TrialStatusPopover component group_contact_sales experiment control matches the snapshot 1`] = `
<gl-popover-stub <gl-popover-stub
boundary="viewport" boundary="viewport"
cssclasses="" cssclasses=""
...@@ -22,7 +76,6 @@ exports[`TrialStatusPopover component matches the snapshot 1`] = ` ...@@ -22,7 +76,6 @@ exports[`TrialStatusPopover component matches the snapshot 1`] = `
buttontextclasses="" buttontextclasses=""
category="primary" category="primary"
class="gl-mb-0" class="gl-mb-0"
data-testid="upgradeBtn"
href="transactions/new" href="transactions/new"
icon="" icon=""
size="small" size="small"
......
...@@ -10,6 +10,8 @@ import { ...@@ -10,6 +10,8 @@ import {
import TrialStatusPopover from 'ee/contextual_sidebar/components/trial_status_popover.vue'; import TrialStatusPopover from 'ee/contextual_sidebar/components/trial_status_popover.vue';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper'; import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { stubExperiments } from 'helpers/experimentation_helper';
import GitlabExperiment from '~/experimentation/components/gitlab_experiment.vue';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
Vue.config.ignoredElements = ['gl-emoji']; Vue.config.ignoredElements = ['gl-emoji'];
...@@ -22,6 +24,7 @@ describe('TrialStatusPopover component', () => { ...@@ -22,6 +24,7 @@ describe('TrialStatusPopover component', () => {
const defaultDaysRemaining = 20; const defaultDaysRemaining = 20;
const findGlPopover = () => wrapper.findComponent(GlPopover); const findGlPopover = () => wrapper.findComponent(GlPopover);
const findByRef = (ref) => wrapper.find({ ref });
const expectTracking = ({ action, ...options } = {}) => { const expectTracking = ({ action, ...options } = {}) => {
return expect(trackingSpy).toHaveBeenCalledWith(undefined, action, { return expect(trackingSpy).toHaveBeenCalledWith(undefined, action, {
...@@ -31,7 +34,7 @@ describe('TrialStatusPopover component', () => { ...@@ -31,7 +34,7 @@ describe('TrialStatusPopover component', () => {
}); });
}; };
const createComponent = (providers = {}, mountFn = shallowMount) => { const createComponent = ({ providers = {}, mountFn = shallowMount, stubs = {} } = {}) => {
return extendedWrapper( return extendedWrapper(
mountFn(TrialStatusPopover, { mountFn(TrialStatusPopover, {
provide: { provide: {
...@@ -46,8 +49,17 @@ describe('TrialStatusPopover component', () => { ...@@ -46,8 +49,17 @@ describe('TrialStatusPopover component', () => {
trialEndDate: new Date('2021-02-28'), trialEndDate: new Date('2021-02-28'),
userCalloutsPath: undefined, userCalloutsPath: undefined,
userCalloutsFeatureId: undefined, userCalloutsFeatureId: undefined,
user: {
namespaceId: 'namespaceId',
userName: 'userName',
firstName: 'firstName',
lastName: 'lastName',
companyName: 'companyName',
glmContent: 'glmContent',
},
...providers, ...providers,
}, },
stubs,
}), }),
); );
}; };
...@@ -64,22 +76,12 @@ describe('TrialStatusPopover component', () => { ...@@ -64,22 +76,12 @@ describe('TrialStatusPopover component', () => {
describe('interpolated strings', () => { describe('interpolated strings', () => {
it('correctly interpolates them all', () => { it('correctly interpolates them all', () => {
wrapper = createComponent(undefined, mount); wrapper = createComponent({ providers: undefined, mountFn: mount });
expect(wrapper.text()).not.toMatch(/%{\w+}/); expect(wrapper.text()).not.toMatch(/%{\w+}/);
}); });
}); });
it('matches the snapshot', () => {
expect(wrapper.element).toMatchSnapshot();
});
it('tracks when the upgrade button is clicked', () => {
wrapper.findByTestId('upgradeBtn').vm.$emit('click');
expectTracking(trackingEvents.upgradeBtnClick);
});
it('tracks when the compare button is clicked', () => { it('tracks when the compare button is clicked', () => {
wrapper.findByTestId('compareBtn').vm.$emit('click'); wrapper.findByTestId('compareBtn').vm.$emit('click');
...@@ -87,7 +89,7 @@ describe('TrialStatusPopover component', () => { ...@@ -87,7 +89,7 @@ describe('TrialStatusPopover component', () => {
}); });
it('does not include the word "Trial" if the plan name includes it', () => { it('does not include the word "Trial" if the plan name includes it', () => {
wrapper = createComponent({ planName: 'Ultimate Trial' }, mount); wrapper = createComponent({ providers: { planName: 'Ultimate Trial' }, mountFn: mount });
const popoverText = wrapper.text(); const popoverText = wrapper.text();
...@@ -95,6 +97,44 @@ describe('TrialStatusPopover component', () => { ...@@ -95,6 +97,44 @@ describe('TrialStatusPopover component', () => {
expect(popoverText).toMatch(/Upgrade Some Test Group to Ultimate(?! Trial)/); expect(popoverText).toMatch(/Upgrade Some Test Group to Ultimate(?! Trial)/);
}); });
describe('group_contact_sales experiment', () => {
describe('control', () => {
beforeEach(() => {
stubExperiments({ group_contact_sales: 'control' });
wrapper = createComponent({ stubs: { GitlabExperiment } });
trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn);
});
it('matches the snapshot', () => {
expect(wrapper.element).toMatchSnapshot();
});
it('tracks when the upgrade button is clicked', () => {
findByRef('upgradeBtn').vm.$emit('click');
expectTracking(trackingEvents.upgradeBtnClick);
});
});
describe('candidate', () => {
beforeEach(() => {
stubExperiments({ group_contact_sales: 'candidate' });
wrapper = createComponent({ stubs: { GitlabExperiment } });
trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn);
});
it('matches the snapshot', () => {
expect(wrapper.element).toMatchSnapshot();
});
it('tracks when the contact sales button is clicked', () => {
wrapper.findByTestId('contactSalesBtn').trigger('click');
expectTracking(trackingEvents.contactSalesBtnClick);
});
});
});
describe('startInitiallyShown', () => { describe('startInitiallyShown', () => {
const userCalloutProviders = { const userCalloutProviders = {
userCalloutsPath: 'user_callouts/path', userCalloutsPath: 'user_callouts/path',
...@@ -107,7 +147,7 @@ describe('TrialStatusPopover component', () => { ...@@ -107,7 +147,7 @@ describe('TrialStatusPopover component', () => {
describe('when set to true', () => { describe('when set to true', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createComponent({ startInitiallyShown: true }); wrapper = createComponent({ providers: { startInitiallyShown: true } });
}); });
it('causes the popover to be shown by default', () => { it('causes the popover to be shown by default', () => {
...@@ -121,8 +161,10 @@ describe('TrialStatusPopover component', () => { ...@@ -121,8 +161,10 @@ describe('TrialStatusPopover component', () => {
describe('and the user callout values are provided', () => { describe('and the user callout values are provided', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createComponent({ wrapper = createComponent({
startInitiallyShown: true, providers: {
...userCalloutProviders, startInitiallyShown: true,
...userCalloutProviders,
},
}); });
}); });
...@@ -142,7 +184,7 @@ describe('TrialStatusPopover component', () => { ...@@ -142,7 +184,7 @@ describe('TrialStatusPopover component', () => {
describe('when set to false', () => { describe('when set to false', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createComponent({ ...userCalloutProviders }); wrapper = createComponent({ providers: { ...userCalloutProviders } });
}); });
it('does not cause the popover to be shown by default', () => { it('does not cause the popover to be shown by default', () => {
...@@ -162,7 +204,7 @@ describe('TrialStatusPopover component', () => { ...@@ -162,7 +204,7 @@ describe('TrialStatusPopover component', () => {
describe('close button', () => { describe('close button', () => {
describe('when the popover starts off forcibly shown', () => { describe('when the popover starts off forcibly shown', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createComponent({ startInitiallyShown: true }, mount); wrapper = createComponent({ providers: { startInitiallyShown: true }, mountFn: mount });
}); });
it('is rendered', () => { it('is rendered', () => {
...@@ -235,7 +277,7 @@ describe('TrialStatusPopover component', () => { ...@@ -235,7 +277,7 @@ describe('TrialStatusPopover component', () => {
`( `(
'sets the expected values for `property` & `value`', 'sets the expected values for `property` & `value`',
({ daysRemaining, startInitiallyShown, property }) => { ({ daysRemaining, startInitiallyShown, property }) => {
wrapper = createComponent({ daysRemaining, startInitiallyShown }); wrapper = createComponent({ providers: { daysRemaining, startInitiallyShown } });
// We'll use the "onShown" method to exercise trackingPropertyAndValue // We'll use the "onShown" method to exercise trackingPropertyAndValue
findGlPopover().vm.$emit('shown'); findGlPopover().vm.$emit('shown');
......
...@@ -23,7 +23,7 @@ describe('HandRaiseLeadButton', () => { ...@@ -23,7 +23,7 @@ describe('HandRaiseLeadButton', () => {
let fakeApollo; let fakeApollo;
let trackingSpy; let trackingSpy;
const createComponent = () => { const createComponent = (small = false) => {
const mockResolvers = { const mockResolvers = {
Query: { Query: {
countries() { countries() {
...@@ -39,6 +39,7 @@ describe('HandRaiseLeadButton', () => { ...@@ -39,6 +39,7 @@ describe('HandRaiseLeadButton', () => {
return shallowMountExtended(HandRaiseLeadButton, { return shallowMountExtended(HandRaiseLeadButton, {
apolloProvider: fakeApollo, apolloProvider: fakeApollo,
provide: { provide: {
small,
user: { user: {
namespaceId: '1', namespaceId: '1',
userName: 'joe', userName: 'joe',
...@@ -71,8 +72,12 @@ describe('HandRaiseLeadButton', () => { ...@@ -71,8 +72,12 @@ describe('HandRaiseLeadButton', () => {
expect(findButton().props('loading')).toBe(false); expect(findButton().props('loading')).toBe(false);
}); });
it('has the "Contact sales" text on the button', () => { it('has default medium button and the "Contact sales" text on the button', () => {
expect(findButton().text()).toBe(PQL_BUTTON_TEXT); const button = findButton();
expect(button.props('variant')).toBe('default');
expect(button.props('size')).toBe('medium');
expect(button.text()).toBe(PQL_BUTTON_TEXT);
}); });
it('has the default injected values', async () => { it('has the default injected values', async () => {
...@@ -129,6 +134,17 @@ describe('HandRaiseLeadButton', () => { ...@@ -129,6 +134,17 @@ describe('HandRaiseLeadButton', () => {
label: 'hand_raise_lead_form', label: 'hand_raise_lead_form',
}); });
}); });
describe('small button', () => {
it('has small confirm button and the "Contact sales" text on the button', () => {
wrapper = createComponent(true);
const button = findButton();
expect(button.props('variant')).toBe('confirm');
expect(button.props('size')).toBe('small');
expect(button.text()).toBe(PQL_BUTTON_TEXT);
});
});
}); });
describe('submit button', () => { describe('submit button', () => {
......
...@@ -27,6 +27,7 @@ describe('Card security discover app', () => { ...@@ -27,6 +27,7 @@ describe('Card security discover app', () => {
propsData, propsData,
apolloProvider: createMockApollo([], {}), apolloProvider: createMockApollo([], {}),
provide: { provide: {
small: false,
user: { user: {
namespaceId: '1', namespaceId: '1',
userName: 'joe', userName: 'joe',
......
...@@ -27,6 +27,7 @@ RSpec.describe TrialStatusWidgetHelper, :saas do ...@@ -27,6 +27,7 @@ RSpec.describe TrialStatusWidgetHelper, :saas do
trial_starts_on: trial_start_date, trial_starts_on: trial_start_date,
trial_ends_on: trial_end_date trial_ends_on: trial_end_date
) )
stub_experiments(group_contact_sales: :control)
stub_experiments(forcibly_show_trial_status_popover: :candidate) stub_experiments(forcibly_show_trial_status_popover: :candidate)
allow_next_instance_of(GitlabSubscriptions::FetchSubscriptionPlansService, plan: :free) do |instance| allow_next_instance_of(GitlabSubscriptions::FetchSubscriptionPlansService, plan: :free) do |instance|
allow(instance).to receive(:execute).and_return([ allow(instance).to receive(:execute).and_return([
...@@ -128,6 +129,32 @@ RSpec.describe TrialStatusWidgetHelper, :saas do ...@@ -128,6 +129,32 @@ RSpec.describe TrialStatusWidgetHelper, :saas do
it 'records the experiment subject' do it 'records the experiment subject' do
expect { data_attrs }.to change { ExperimentSubject.count } expect { data_attrs }.to change { ExperimentSubject.count }
end end
context 'when group_contact_sales is enabled' do
before do
stub_experiments(group_contact_sales: :candidate)
end
it 'returns the needed data attributes for mounting the popover Vue component' do
expect(data_attrs).to match(
shared_expected_attrs.merge(
namespace_id: group.id,
user_name: user.username,
first_name: user.first_name,
last_name: user.last_name,
company_name: user.organization,
glm_content: 'trial-status-show-group',
group_name: group.name,
purchase_href: new_subscriptions_path(namespace_id: group.id, plan_id: 'ultimate-plan-id'),
target_id: shared_expected_attrs[:container_id],
start_initially_shown: false,
trial_end_date: trial_end_date,
user_callouts_path: callouts_path,
user_callouts_feature_id: user_callouts_feature_id
)
)
end
end
end end
describe '#trial_status_widget_data_attrs' do describe '#trial_status_widget_data_attrs' do
......
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