Commit ad936c19 authored by Savas Vedova's avatar Savas Vedova

Merge branch '344286-add-the-isaddon-flag-to-storage-purchase-flow' into 'master'

Add isAddon flag to Storage purchase flow

See merge request gitlab-org/gitlab!73383
parents d636cd52 07f2b868
......@@ -59,6 +59,14 @@ export default {
hasError: false,
};
},
computed: {
plan() {
return {
...this.plans[0],
isAddon: true,
};
},
},
methods: {
isQuantityValid(quantity) {
return Number.isFinite(quantity) && quantity > 0;
......@@ -124,7 +132,7 @@ export default {
/>
<step-order-app v-else-if="!$apollo.loading">
<template #checkout>
<checkout :plan="plans[0]">
<checkout :plan="plan">
<template #purchase-details>
<addon-purchase-details
:product-label="$options.i18n.productLabel"
......@@ -138,14 +146,14 @@ export default {
<strong data-testid="summary-label">
{{ summaryTitle(quantity) }}
</strong>
<p class="gl-mb-0">{{ summaryTotal(quantity) }}</p>
<p class="gl-mb-0" data-testid="summary-total">{{ summaryTotal(quantity) }}</p>
</template>
</addon-purchase-details>
</template>
</checkout>
</template>
<template #order-summary>
<order-summary :plan="plans[0]" :title="$options.i18n.title" purchase-has-expiration>
<order-summary :plan="plan" :title="$options.i18n.title" purchase-has-expiration>
<template #price-per-unit="{ price }">
{{ pricePerUnitLabel(price) }}
</template>
......
......@@ -2,12 +2,12 @@ import { GlAlert } from '@gitlab/ui';
import { createLocalVue } from '@vue/test-utils';
import { merge } from 'lodash';
import VueApollo from 'vue-apollo';
import { stateData as initialStateData } from 'ee_jest/subscriptions/mock_data';
import AddonPurchaseDetails from 'ee/subscriptions/buy_addons_shared/components/checkout/addon_purchase_details.vue';
import subscriptionsResolvers from 'ee/subscriptions/buy_addons_shared/graphql/resolvers';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import purchaseFlowResolvers from 'ee/vue_shared/purchase_flow/graphql/resolvers';
import { stateData as initialStateData } from 'ee_jest/subscriptions/buy_minutes/mock_data';
import createMockApollo from 'helpers/mock_apollo_helper';
import { mountExtended } from 'helpers/vue_test_utils_helper';
......
......@@ -10,7 +10,7 @@ import {
mockCiMinutesPlans,
mockParsedNamespaces,
stateData as mockStateData,
} from 'ee_jest/subscriptions/buy_minutes/mock_data';
} from 'ee_jest/subscriptions/mock_data';
import createMockApollo from 'helpers/mock_apollo_helper';
const localVue = createLocalVue();
......
import apolloProvider from 'ee/subscriptions/buy_addons_shared/graphql';
import { writeInitialDataToApolloCache } from 'ee/subscriptions/buy_addons_shared/utils';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
import { mockNamespaces, mockParsedNamespaces } from '../buy_minutes/mock_data';
import { mockNamespaces, mockParsedNamespaces } from '../mock_data';
const DEFAULT_DATA = {
groupData: mockNamespaces,
......
......@@ -2,7 +2,7 @@ import { GlEmptyState } from '@gitlab/ui';
import { createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import { pick } from 'lodash';
import { I18N_CI_MINUTES_TITLE, planTags } from 'ee/subscriptions/buy_addons_shared/constants';
import { I18N_CI_MINUTES_TITLE } from 'ee/subscriptions/buy_addons_shared/constants';
import Checkout from 'ee/subscriptions/buy_addons_shared/components/checkout.vue';
import AddonPurchaseDetails from 'ee/subscriptions/buy_addons_shared/components/checkout/addon_purchase_details.vue';
import OrderSummary from 'ee/subscriptions/buy_addons_shared/components/order_summary.vue';
......@@ -11,19 +11,18 @@ import App from 'ee/subscriptions/buy_minutes/components/app.vue';
import StepOrderApp from 'ee/vue_shared/purchase_flow/components/step_order_app.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { createMockApolloProvider } from '../spec_helper';
import { mockCiMinutesPlans } from '../mock_data';
import { createMockApolloProvider } from 'ee_jest/subscriptions/spec_helper';
import { mockCiMinutesPlans } from 'ee_jest/subscriptions/mock_data';
const localVue = createLocalVue();
localVue.use(VueApollo);
describe('App', () => {
describe('Buy Minutes App', () => {
let wrapper;
function createComponent(apolloProvider) {
return shallowMountExtended(App, {
localVue,
propsData: { plan: planTags.CI_1000_MINUTES_PLAN },
apolloProvider,
stubs: {
Checkout,
......@@ -121,7 +120,7 @@ describe('App', () => {
});
describe('labels', () => {
it('are shown correctly for 1 pack', async () => {
it('shows labels correctly for 1 pack', async () => {
const mockApollo = createMockApolloProvider();
wrapper = createComponent(mockApollo);
await waitForPromises();
......@@ -134,7 +133,7 @@ describe('App', () => {
expect(findPriceLabel().text()).toBe('$10 per pack of 1,000 minutes');
});
it('are shown correctly for 2 packs', async () => {
it('shows labels correctly for 2 packs', async () => {
const mockApollo = createMockApolloProvider({}, { quantity: 2 });
wrapper = createComponent(mockApollo);
await waitForPromises();
......@@ -146,7 +145,7 @@ describe('App', () => {
expect(findSummaryTotal().text()).toBe('Total minutes: 2,000');
});
it('are not shown if input is invalid', async () => {
it('does not show labels if input is invalid', async () => {
const mockApollo = createMockApolloProvider({}, { quantity: -1 });
wrapper = createComponent(mockApollo);
await waitForPromises();
......
......@@ -6,7 +6,7 @@ import { STEPS } from 'ee/subscriptions/constants';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
import BillingAddress from 'ee/vue_shared/purchase_flow/components/checkout/billing_address.vue';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import { stateData as initialStateData } from 'ee_jest/subscriptions/buy_minutes/mock_data';
import { stateData as initialStateData } from 'ee_jest/subscriptions/mock_data';
import { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_helper';
import waitForPromises from 'helpers/wait_for_promises';
......
......@@ -6,10 +6,7 @@ import { STEPS } from 'ee/subscriptions/constants';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
import ConfirmOrder from 'ee/vue_shared/purchase_flow/components/checkout/confirm_order.vue';
import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants';
import {
stateData as initialStateData,
subscriptionName,
} from 'ee_jest/subscriptions/buy_minutes/mock_data';
import { stateData as initialStateData, subscriptionName } from 'ee_jest/subscriptions/mock_data';
import { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import flash from '~/flash';
......
import { GlEmptyState } from '@gitlab/ui';
import { createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import { pick } from 'lodash';
import { I18N_STORAGE_TITLE } from 'ee/subscriptions/buy_addons_shared/constants';
import Checkout from 'ee/subscriptions/buy_addons_shared/components/checkout.vue';
import AddonPurchaseDetails from 'ee/subscriptions/buy_addons_shared/components/checkout/addon_purchase_details.vue';
import OrderSummary from 'ee/subscriptions/buy_addons_shared/components/order_summary.vue';
import SummaryDetails from 'ee/subscriptions/buy_addons_shared/components/order_summary/summary_details.vue';
import App from 'ee/subscriptions/buy_storage/components/app.vue';
import StepOrderApp from 'ee/vue_shared/purchase_flow/components/step_order_app.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { createMockApolloProvider } from 'ee_jest/subscriptions/spec_helper';
import { mockStoragePlans } from 'ee_jest/subscriptions/mock_data';
const localVue = createLocalVue();
localVue.use(VueApollo);
describe('Buy Storage App', () => {
let wrapper;
function createComponent(apolloProvider) {
wrapper = shallowMountExtended(App, {
localVue,
apolloProvider,
stubs: {
Checkout,
AddonPurchaseDetails,
OrderSummary,
SummaryDetails,
},
});
return waitForPromises();
}
const getStoragePlan = () => pick(mockStoragePlans[0], ['id', 'code', 'pricePerYear', 'name']);
const findCheckout = () => wrapper.findComponent(Checkout);
const findOrderSummary = () => wrapper.findComponent(OrderSummary);
const findPriceLabel = () => wrapper.findByTestId('price-per-unit');
const findQuantityText = () => wrapper.findByTestId('addon-quantity-text');
const findSummaryLabel = () => wrapper.findByTestId('summary-label');
const findSummaryTotal = () => wrapper.findByTestId('summary-total');
afterEach(() => {
wrapper.destroy();
});
describe('when data is received', () => {
beforeEach(() => {
const mockApollo = createMockApolloProvider();
return createComponent(mockApollo);
});
it('should display the StepOrderApp', () => {
expect(wrapper.findComponent(StepOrderApp).exists()).toBe(true);
expect(wrapper.findComponent(GlEmptyState).exists()).toBe(false);
});
it('provides the correct props to checkout', () => {
expect(findCheckout().props()).toMatchObject({
plan: { ...getStoragePlan, isAddon: true },
});
});
it('provides the correct props to order summary', () => {
expect(findOrderSummary().props()).toMatchObject({
plan: { ...getStoragePlan, isAddon: true },
title: I18N_STORAGE_TITLE,
});
});
});
describe('when data is not received', () => {
it('should display the GlEmptyState for empty data', async () => {
const mockApollo = createMockApolloProvider({
plansQueryMock: jest.fn().mockResolvedValue({ data: null }),
});
await createComponent(mockApollo);
expect(wrapper.findComponent(StepOrderApp).exists()).toBe(false);
expect(wrapper.findComponent(GlEmptyState).exists()).toBe(true);
});
it('should display the GlEmptyState for empty plans', async () => {
const mockApollo = createMockApolloProvider({
plansQueryMock: jest.fn().mockResolvedValue({ data: { plans: null } }),
});
await createComponent(mockApollo);
expect(wrapper.findComponent(StepOrderApp).exists()).toBe(false);
expect(wrapper.findComponent(GlEmptyState).exists()).toBe(true);
});
it('should display the GlEmptyState for plans data of wrong type', async () => {
const mockApollo = createMockApolloProvider({
plansQueryMock: jest.fn().mockResolvedValue({ data: { plans: {} } }),
});
await createComponent(mockApollo);
expect(wrapper.findComponent(StepOrderApp).exists()).toBe(false);
expect(wrapper.findComponent(GlEmptyState).exists()).toBe(true);
});
});
describe('when an error is received', () => {
it('should display the GlEmptyState', async () => {
const mockApollo = createMockApolloProvider({
plansQueryMock: jest.fn().mockRejectedValue(new Error('An error happened!')),
});
await createComponent(mockApollo);
expect(wrapper.findComponent(StepOrderApp).exists()).toBe(false);
expect(wrapper.findComponent(GlEmptyState).exists()).toBe(true);
});
});
describe('labels', () => {
it('shows labels correctly for 1 pack', async () => {
const mockApollo = createMockApolloProvider();
await createComponent(mockApollo);
expect(findQuantityText().text()).toMatchInterpolatedText(
'x 10 GB per pack = 10 GB of storage',
);
expect(findSummaryLabel().text()).toBe('1 storage pack');
expect(findSummaryTotal().text()).toBe('Total storage: 10 GB');
expect(findPriceLabel().text()).toBe('$10 per 10 GB storage per pack');
});
it('shows labels correctly for 2 packs', async () => {
const mockApollo = createMockApolloProvider({}, { quantity: 2 });
await createComponent(mockApollo);
expect(findQuantityText().text()).toMatchInterpolatedText(
'x 10 GB per pack = 20 GB of storage',
);
expect(findSummaryLabel().text()).toBe('2 storage packs');
expect(findSummaryTotal().text()).toBe('Total storage: 20 GB');
});
it('does not show labels if input is invalid', async () => {
const mockApollo = createMockApolloProvider({}, { quantity: -1 });
await createComponent(mockApollo);
expect(findQuantityText().text()).toMatchInterpolatedText('x 10 GB per pack');
});
});
});
......@@ -20,6 +20,16 @@ export const mockCiMinutesPlans = [
},
];
export const mockStoragePlans = [
{
id: 'storagePackPlanId',
code: 'storage',
pricePerYear: 50,
name: 'Storage pack',
__typename: PLAN_TYPE,
},
];
export const mockNamespaces = `
[{"id":132,"accountId":"${accountId}","name":"Gitlab Org","users":3},
{"id":483,"accountId":null,"name":"Gnuwget","users":12}]
......
......@@ -3,7 +3,7 @@ import { writeInitialDataToApolloCache } from 'ee/subscriptions/buy_addons_share
import plansQuery from 'ee/subscriptions/graphql/queries/plans.customer.query.graphql';
import { createMockClient } from 'helpers/mock_apollo_helper';
import { CUSTOMERSDOT_CLIENT } from 'ee/subscriptions/buy_addons_shared/constants';
import { mockCiMinutesPlans, mockDefaultCache } from './mock_data';
import { mockCiMinutesPlans, mockDefaultCache } from 'ee_jest/subscriptions/mock_data';
export function createMockApolloProvider(mockResponses = {}, dataset = {}) {
const {
......
import { createLocalVue } from '@vue/test-utils';
import { merge } from 'lodash';
import VueApollo from 'vue-apollo';
import {
mockParsedNamespaces,
stateData as initialStateData,
} from 'ee_jest/subscriptions/mock_data';
import { resolvers } from 'ee/subscriptions/buy_addons_shared/graphql/resolvers';
import { STEPS } from 'ee/subscriptions/constants';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
import PaymentMethod from 'ee/vue_shared/purchase_flow/components/checkout/payment_method.vue';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import {
mockParsedNamespaces,
stateData as initialStateData,
} from 'ee_jest/subscriptions/buy_minutes/mock_data';
import { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_helper';
import Zuora from 'ee/vue_shared/purchase_flow/components/checkout/zuora.vue';
import { mountExtended } from 'helpers/vue_test_utils_helper';
......
......@@ -7,7 +7,7 @@ import { resolvers } from 'ee/subscriptions/buy_addons_shared/graphql/resolvers'
import { STEPS } from 'ee/subscriptions/constants';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
import Zuora from 'ee/vue_shared/purchase_flow/components/checkout/zuora.vue';
import { stateData as initialStateData } from 'ee_jest/subscriptions/buy_minutes/mock_data';
import { stateData as initialStateData } from 'ee_jest/subscriptions/mock_data';
import { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_helper';
import axios from '~/lib/utils/axios_utils';
import flushPromises from 'helpers/flush_promises';
......
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