Commit 5d676eb1 authored by Mark Florian's avatar Mark Florian

Merge branch 'ag/333698-tax-and-subtotal-ci-min' into 'master'

Display subtotal and tax line in CI Minutes Purchase

See merge request gitlab-org/gitlab!67479
parents 37c947e4 1fa181bd
<script>
import { GlLink, GlSprintf } from '@gitlab/ui';
import formattingMixins from 'ee/subscriptions/new/formatting_mixins';
import { s__ } from '~/locale';
export default {
components: {
GlLink,
GlSprintf,
},
mixins: [formattingMixins],
props: {
vat: {
......@@ -48,6 +53,15 @@ export default {
endDate() {
return this.startDate.setFullYear(this.startDate.getFullYear() + 1);
},
hasPositiveQuantity() {
return this.quantity > 0;
},
taxAmount() {
return this.taxRate ? this.formatAmount(this.vat, this.quantity > 0) : '';
},
taxLine() {
return `${this.$options.i18n.tax} ${this.$options.i18n.taxNote}`;
},
},
i18n: {
selectedPlanText: s__('Checkout|%{selectedPlanText} plan'),
......@@ -56,29 +70,32 @@ export default {
dates: s__('Checkout|%{startDate} - %{endDate}'),
subtotal: s__('Checkout|Subtotal'),
tax: s__('Checkout|Tax'),
taxNote: s__('Checkout|(may be %{linkStart}charged upon purchase%{linkEnd})'),
total: s__('Checkout|Total'),
},
};
</script>
<template>
<div>
<div class="d-flex justify-content-between bold gl-mt-3 gl-mb-3">
<div
class="gl-display-flex gl-justify-content-space-between gl-font-weight-bold gl-mt-3 gl-mb-3"
>
<div data-testid="selected-plan">
{{ sprintf($options.i18n.selectedPlanText, { selectedPlanText }) }}
<span v-if="quantity" data-testid="quantity">{{
sprintf($options.i18n.quantity, { quantity })
}}</span>
</div>
<div data-testid="amount">{{ formatAmount(totalExVat, quantity > 0) }}</div>
<div data-testid="amount">{{ formatAmount(totalExVat, hasPositiveQuantity) }}</div>
</div>
<div class="text-secondary" data-testid="price-per-unit">
<div class="gl-text-gray-500" data-testid="price-per-unit">
{{
sprintf($options.i18n.pricePerUnitPerYear, {
selectedPlanPrice: selectedPlanPrice.toLocaleString(),
})
}}
</div>
<div v-if="purchaseHasExpiration" class="text-secondary" data-testid="subscription-period">
<div v-if="purchaseHasExpiration" class="gl-text-gray-500" data-testid="subscription-period">
{{
sprintf($options.i18n.dates, {
startDate: formatDate(startDate),
......@@ -86,21 +103,35 @@ export default {
})
}}
</div>
<div v-if="taxRate">
<div>
<div class="border-bottom gl-mt-3 gl-mb-3"></div>
<div class="d-flex justify-content-between text-secondary">
<div class="gl-display-flex gl-justify-content-space-between gl-text-gray-500">
<div>{{ $options.i18n.subtotal }}</div>
<div data-testid="total-ex-vat">{{ formatAmount(totalExVat, quantity > 0) }}</div>
<div data-testid="total-ex-vat">{{ formatAmount(totalExVat, hasPositiveQuantity) }}</div>
</div>
<div class="d-flex justify-content-between text-secondary">
<div>{{ $options.i18n.tax }}</div>
<div data-testid="vat">{{ formatAmount(vat, quantity > 0) }}</div>
<div class="gl-display-flex gl-justify-content-space-between gl-text-gray-500">
<div>
<div data-testid="vat-info-line">
<gl-sprintf :message="taxLine">
<template #link="{ content }">
<gl-link
class="gl-text-decoration-underline gl-text-gray-500"
href="https://about.gitlab.com/handbook/tax/#indirect-taxes-management"
target="_blank"
data-testid="vat-help-link"
>{{ content }}</gl-link
>
</template>
</gl-sprintf>
</div>
</div>
<div class="border-bottom gl-mt-3 gl-mb-3"></div>
<div class="d-flex justify-content-between bold gl-font-lg">
<div data-testid="vat">{{ taxAmount }}</div>
</div>
</div>
<div class="gl-border-b-1 gl-border-b-gray-100 gl-border-b-solid gl-mt-3 gl-mb-3"></div>
<div class="gl-display-flex gl-justify-content-space-between gl-font-weight-bold gl-font-lg">
<div>{{ $options.i18n.total }}</div>
<div data-itestid="total-amount">{{ formatAmount(totalAmount, quantity > 0) }}</div>
<div data-testid="total-amount">{{ formatAmount(totalAmount, hasPositiveQuantity) }}</div>
</div>
</div>
</template>
import { shallowMount } from '@vue/test-utils';
import { GlSprintf } from '@gitlab/ui';
import SummaryDetails from 'ee/subscriptions/buy_minutes/components/order_summary/summary_details.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
describe('SummaryDetails', () => {
let wrapper;
const createComponent = (props = {}) => {
return shallowMount(SummaryDetails, {
return shallowMountExtended(SummaryDetails, {
propsData: {
vat: 8,
totalExVat: 10,
......@@ -15,13 +16,19 @@ describe('SummaryDetails', () => {
quantity: 1,
...props,
},
stubs: {
GlSprintf,
},
});
};
const findQuantity = () => wrapper.find('[data-testid="quantity"]');
const findSubscriptionPeriod = () => wrapper.find('[data-testid="subscription-period"]');
const findTotalExVat = () => wrapper.find('[data-testid="total-ex-vat"]');
const findVat = () => wrapper.find('[data-testid="vat"]');
const findQuantity = () => wrapper.findByTestId('quantity');
const findSubscriptionPeriod = () => wrapper.findByTestId('subscription-period');
const findTotalAmount = () => wrapper.findByTestId('total-amount');
const findTotalExVat = () => wrapper.findByTestId('total-ex-vat');
const findVat = () => wrapper.findByTestId('vat');
const findVatHelpLink = () => wrapper.findByTestId('vat-help-link');
const findVatInfoLine = () => wrapper.findByTestId('vat-info-line');
afterEach(() => {
wrapper.destroy();
......@@ -33,13 +40,29 @@ describe('SummaryDetails', () => {
});
it('renders the plan name', () => {
expect(wrapper.find('[data-testid="selected-plan"]').text()).toMatchInterpolatedText(
expect(wrapper.findByTestId('selected-plan').text()).toMatchInterpolatedText(
'Test plan (x1)',
);
});
it('renders the price per unit', () => {
expect(wrapper.find('[data-testid="price-per-unit"]').text()).toBe('$10 per pack per year');
expect(wrapper.findByTestId('price-per-unit').text()).toBe('$10 per pack per year');
});
it('displays the total amount', () => {
expect(findTotalAmount().text()).toBe('$10');
});
it('displays a help link', () => {
expect(findVatHelpLink().attributes('href')).toBe(
'https://about.gitlab.com/handbook/tax/#indirect-taxes-management',
);
});
it('displays an info text', () => {
expect(findVatInfoLine().text()).toMatchInterpolatedText(
'Tax (may be charged upon purchase)',
);
});
});
......@@ -60,7 +83,7 @@ describe('SummaryDetails', () => {
});
it('does not render quantity', () => {
expect(wrapper.find('[data-testid="quantity"]').exists()).toBe(false);
expect(wrapper.findByTestId('quantity').exists()).toBe(false);
});
});
......@@ -97,6 +120,18 @@ describe('SummaryDetails', () => {
expect(findVat().isVisible()).toBe(true);
expect(findVat().text()).toBe('$8');
});
it('displays a help link', () => {
expect(findVatHelpLink().attributes('href')).toBe(
'https://about.gitlab.com/handbook/tax/#indirect-taxes-management',
);
});
it('displays an info text', () => {
expect(findVatInfoLine().text()).toMatchInterpolatedText(
'Tax (may be charged upon purchase)',
);
});
});
describe('when tax rate is not applied', () => {
......@@ -104,9 +139,8 @@ describe('SummaryDetails', () => {
wrapper = createComponent();
});
it('does not render tax fields', () => {
expect(findTotalExVat().exists()).toBe(false);
expect(findVat().exists()).toBe(false);
it('displays the vat amount with a stopgap', () => {
expect(findVat().text()).toBe('');
});
});
});
......@@ -6497,6 +6497,9 @@ msgstr ""
msgid "Checkout|%{totalCiMinutes} CI minutes"
msgstr ""
msgid "Checkout|(may be %{linkStart}charged upon purchase%{linkEnd})"
msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
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