Commit 7ac35d76 authored by Vitaly Slobodin's avatar Vitaly Slobodin

Merge branch...

Merge branch 'ag/350379-saas-add-messaging-about-user-overage-process-to-purchase-flow-2' into 'master'

Add messaging about user overage process to purchase flow

See merge request gitlab-org/gitlab!80149
parents f78aad5d e4375a34
...@@ -31,3 +31,5 @@ export const STEPS = [ ...@@ -31,3 +31,5 @@ export const STEPS = [
]; ];
export const TRACK_SUCCESS_MESSAGE = 'Success'; export const TRACK_SUCCESS_MESSAGE = 'Success';
/* eslint-enable @gitlab/require-i18n-strings */ /* eslint-enable @gitlab/require-i18n-strings */
export const QSR_RECONCILIATION_PATH = 'subscriptions/quarterly_reconciliation.html';
<script> <script>
import { GlFormGroup, GlFormSelect, GlFormInput, GlSprintf, GlLink } from '@gitlab/ui'; import { GlAlert, GlFormGroup, GlFormSelect, GlFormInput, GlSprintf, GlLink } from '@gitlab/ui';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import { mapState, mapGetters, mapActions } from 'vuex'; import { mapState, mapGetters, mapActions } from 'vuex';
import { STEP_SUBSCRIPTION_DETAILS } from 'ee/subscriptions/constants'; import { QSR_RECONCILIATION_PATH, STEP_SUBSCRIPTION_DETAILS } from 'ee/subscriptions/constants';
import { NEW_GROUP } from 'ee/subscriptions/new/constants'; import { NEW_GROUP } from 'ee/subscriptions/new/constants';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue'; import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import { sprintf, s__ } from '~/locale'; import { sprintf, s__, __ } from '~/locale';
import autofocusonshow from '~/vue_shared/directives/autofocusonshow'; import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
import Tracking from '~/tracking'; import Tracking from '~/tracking';
import { helpPagePath } from '~/helpers/help_page_helper';
export default { export default {
components: { components: {
GlAlert,
GlFormGroup, GlFormGroup,
GlFormSelect, GlFormSelect,
GlFormInput, GlFormInput,
...@@ -170,8 +172,12 @@ export default { ...@@ -170,8 +172,12 @@ export default {
selectedPlan: s__('Checkout|%{selectedPlanText} plan'), selectedPlan: s__('Checkout|%{selectedPlanText} plan'),
group: s__('Checkout|Group'), group: s__('Checkout|Group'),
users: s__('Checkout|Users'), users: s__('Checkout|Users'),
qsrOverageMessage: __(
'You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}',
),
}, },
stepId: STEP_SUBSCRIPTION_DETAILS, stepId: STEP_SUBSCRIPTION_DETAILS,
qsrReconciliationLink: helpPagePath(QSR_RECONCILIATION_PATH),
}; };
</script> </script>
<template> <template>
...@@ -215,7 +221,11 @@ export default { ...@@ -215,7 +221,11 @@ export default {
<gl-form-input ref="organization-name" v-model="organizationNameModel" type="text" /> <gl-form-input ref="organization-name" v-model="organizationNameModel" type="text" />
</gl-form-group> </gl-form-group>
<div class="combined d-flex"> <div class="combined d-flex">
<gl-form-group :label="$options.i18n.numberOfUsersLabel" label-size="sm" class="number"> <gl-form-group
:label="$options.i18n.numberOfUsersLabel"
label-size="sm"
class="number gl-mb-0"
>
<gl-form-input <gl-form-input
ref="number-of-users" ref="number-of-users"
v-model.number="numberOfUsersModel" v-model.number="numberOfUsersModel"
...@@ -237,6 +247,18 @@ export default { ...@@ -237,6 +247,18 @@ export default {
</gl-sprintf> </gl-sprintf>
</gl-form-group> </gl-form-group>
</div> </div>
<gl-alert
class="gl-mt-5 gl-mb-6"
:dismissible="false"
variant="info"
data-testid="qsr-overage-message"
>
<gl-sprintf :message="$options.i18n.qsrOverageMessage">
<template #qsrOverageLink="{ content }">
<gl-link :href="$options.qsrReconciliationLink" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</gl-alert>
</template> </template>
<template #summary> <template #summary>
<strong ref="summary-line-1"> <strong ref="summary-line-1">
......
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue'; import Vue, { nextTick } from 'vue';
import { GlLink } from '@gitlab/ui';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { mockTracking } from 'helpers/tracking_helper'; import { mockTracking } from 'helpers/tracking_helper';
import { STEPS } from 'ee/subscriptions/constants'; import { QSR_RECONCILIATION_PATH, STEPS } from 'ee/subscriptions/constants';
import Component from 'ee/subscriptions/new/components/checkout/subscription_details.vue'; import Component from 'ee/subscriptions/new/components/checkout/subscription_details.vue';
import { NEW_GROUP } from 'ee/subscriptions/new/constants'; import { NEW_GROUP } from 'ee/subscriptions/new/constants';
import createStore from 'ee/subscriptions/new/store'; import createStore from 'ee/subscriptions/new/store';
import * as types from 'ee/subscriptions/new/store/mutation_types'; import * as types from 'ee/subscriptions/new/store/mutation_types';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue'; import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_helper'; import { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_helper';
import { mountExtended } from 'helpers/vue_test_utils_helper';
const availablePlans = [ const availablePlans = [
{ id: 'firstPlanId', code: 'bronze', price_per_year: 48, name: 'bronze' }, { id: 'firstPlanId', code: 'bronze', price_per_year: 48, name: 'bronze' },
...@@ -38,7 +39,7 @@ describe('Subscription Details', () => { ...@@ -38,7 +39,7 @@ describe('Subscription Details', () => {
function createComponent(options = {}) { function createComponent(options = {}) {
const { apolloProvider, store } = options; const { apolloProvider, store } = options;
return mount(Component, { return mountExtended(Component, {
store, store,
apolloProvider, apolloProvider,
stubs: { stubs: {
...@@ -51,11 +52,34 @@ describe('Subscription Details', () => { ...@@ -51,11 +52,34 @@ describe('Subscription Details', () => {
const groupSelect = () => wrapper.findComponent({ ref: 'group-select' }); const groupSelect = () => wrapper.findComponent({ ref: 'group-select' });
const numberOfUsersInput = () => wrapper.findComponent({ ref: 'number-of-users' }); const numberOfUsersInput = () => wrapper.findComponent({ ref: 'number-of-users' });
const companyLink = () => wrapper.findComponent({ ref: 'company-link' }); const companyLink = () => wrapper.findComponent({ ref: 'company-link' });
const findQsrOverageMessage = () => wrapper.findByTestId('qsr-overage-message');
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
}); });
describe('when rendering', () => {
beforeEach(() => {
const mockApollo = createMockApolloProvider(STEPS);
const store = createStore(
createDefaultInitialStoreData({ newUser: 'true', setupForCompany: '' }),
);
wrapper = createComponent({ apolloProvider: mockApollo, store });
});
it('has an alert displaying a message related to QSR process', () => {
expect(findQsrOverageMessage().text()).toMatchInterpolatedText(
'You are billed if you exceed this number. How does billing work?',
);
});
it('has a link to QSR process help page', () => {
expect(findQsrOverageMessage().findComponent(GlLink).attributes('href')).toMatch(
QSR_RECONCILIATION_PATH,
);
});
});
describe('A new user for which we do not have setupForCompany info', () => { describe('A new user for which we do not have setupForCompany info', () => {
beforeEach(() => { beforeEach(() => {
const mockApollo = createMockApolloProvider(STEPS); const mockApollo = createMockApolloProvider(STEPS);
......
...@@ -41186,6 +41186,9 @@ msgstr "" ...@@ -41186,6 +41186,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it." msgid "You are attempting to update a file that has changed since you started editing it."
msgstr "" msgstr ""
msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
msgstr ""
msgid "You are connected to the Prometheus server, but there is currently no data to display." msgid "You are connected to the Prometheus server, but there is currently no data to display."
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