Commit 8d2c7f09 authored by Simon Knox's avatar Simon Knox

Merge branch 'ag/341564-subs-name-checkout-tests' into 'master'

Add tests for checkout

See merge request gitlab-org/gitlab!73145
parents 28cf6985 5ec85781
...@@ -8,7 +8,11 @@ import createFlash from '~/flash'; ...@@ -8,7 +8,11 @@ import createFlash from '~/flash';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
export default { export default {
components: { BillingAddress, PaymentMethod, ConfirmOrder }, components: {
BillingAddress,
PaymentMethod,
ConfirmOrder,
},
props: { props: {
plan: { plan: {
type: Object, type: Object,
...@@ -19,7 +23,7 @@ export default { ...@@ -19,7 +23,7 @@ export default {
this.updateSelectedPlan(this.plan); this.updateSelectedPlan(this.plan);
}, },
methods: { methods: {
updateSelectedPlan({ id, isAddon }) { updateSelectedPlan({ id, isAddon } = {}) {
this.$apollo this.$apollo
.mutate({ .mutate({
mutation: updateState, mutation: updateState,
......
...@@ -13,6 +13,9 @@ export const SUBSCRIPTION_TYPE = 'Subscription'; ...@@ -13,6 +13,9 @@ export const SUBSCRIPTION_TYPE = 'Subscription';
export const NAMESPACE_TYPE = 'Namespace'; export const NAMESPACE_TYPE = 'Namespace';
export const PAYMENT_METHOD_TYPE = 'PaymentMethod'; export const PAYMENT_METHOD_TYPE = 'PaymentMethod';
export const PLAN_TYPE = 'Plan'; export const PLAN_TYPE = 'Plan';
export const STEP_TYPE = 'Step';
export const COUNTRY_TYPE = 'Country';
export const STATE_TYPE = 'State';
export const CI_MINUTES_PER_PACK = 1000; export const CI_MINUTES_PER_PACK = 1000;
export const STORAGE_PER_PACK = 10; export const STORAGE_PER_PACK = 10;
......
...@@ -3,6 +3,7 @@ import { merge } from 'lodash'; ...@@ -3,6 +3,7 @@ import { merge } from 'lodash';
import Api from 'ee/api'; import Api from 'ee/api';
import * as SubscriptionsApi from 'ee/api/subscriptions_api'; import * as SubscriptionsApi from 'ee/api/subscriptions_api';
import { ERROR_FETCHING_COUNTRIES, ERROR_FETCHING_STATES } from 'ee/subscriptions/constants'; import { ERROR_FETCHING_COUNTRIES, ERROR_FETCHING_STATES } from 'ee/subscriptions/constants';
import { COUNTRY_TYPE, STATE_TYPE } from 'ee/subscriptions/buy_addons_shared/constants';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql'; import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
import createFlash from '~/flash'; import createFlash from '~/flash';
...@@ -13,10 +14,7 @@ export const resolvers = { ...@@ -13,10 +14,7 @@ export const resolvers = {
countries: () => { countries: () => {
return Api.fetchCountries() return Api.fetchCountries()
.then(({ data }) => .then(({ data }) =>
data.map(([name, alpha2]) => data.map(([name, alpha2]) => ({ name, id: alpha2, __typename: COUNTRY_TYPE })),
// eslint-disable-next-line @gitlab/require-i18n-strings
({ name, id: alpha2, __typename: 'Country' }),
),
) )
.catch(() => createFlash({ message: ERROR_FETCHING_COUNTRIES })); .catch(() => createFlash({ message: ERROR_FETCHING_COUNTRIES }));
}, },
...@@ -26,8 +24,7 @@ export const resolvers = { ...@@ -26,8 +24,7 @@ export const resolvers = {
return Object.entries(data).map(([key, value]) => ({ return Object.entries(data).map(([key, value]) => ({
id: value, id: value,
name: key, name: key,
// eslint-disable-next-line @gitlab/require-i18n-strings __typename: STATE_TYPE,
__typename: 'State',
})); }));
}) })
.catch(() => createFlash({ message: ERROR_FETCHING_STATES })); .catch(() => createFlash({ message: ERROR_FETCHING_STATES }));
......
import produce from 'immer'; import produce from 'immer';
import { STEP_TYPE } from 'ee/subscriptions/buy_addons_shared/constants';
import activeStepQuery from './queries/active_step.query.graphql'; import activeStepQuery from './queries/active_step.query.graphql';
import stepListQuery from './queries/step_list.query.graphql'; import stepListQuery from './queries/step_list.query.graphql';
...@@ -9,8 +10,7 @@ function updateActiveStep(_, { id }, { cache }) { ...@@ -9,8 +10,7 @@ function updateActiveStep(_, { id }, { cache }) {
const data = produce(sourceData, (draftData) => { const data = produce(sourceData, (draftData) => {
draftData.activeStep = { draftData.activeStep = {
// eslint-disable-next-line @gitlab/require-i18n-strings __typename: STEP_TYPE,
__typename: 'Step',
id: activeStep.id, id: activeStep.id,
}; };
}); });
...@@ -26,8 +26,7 @@ function activateNextStep(parent, _, { cache }) { ...@@ -26,8 +26,7 @@ function activateNextStep(parent, _, { cache }) {
const data = produce(sourceData, (draftData) => { const data = produce(sourceData, (draftData) => {
draftData.activeStep = { draftData.activeStep = {
// eslint-disable-next-line @gitlab/require-i18n-strings __typename: STEP_TYPE,
__typename: 'Step',
id: activeStep.id, id: activeStep.id,
}; };
}); });
......
import { createLocalVue } from '@vue/test-utils';
import { merge } from 'lodash';
import VueApollo from 'vue-apollo';
import BillingAddress from 'ee/vue_shared/purchase_flow/components/checkout/billing_address.vue';
import OrderConfirmation from 'ee/vue_shared/purchase_flow/components/checkout/confirm_order.vue';
import PaymentMethod from 'ee/vue_shared/purchase_flow/components/checkout/payment_method.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants';
import Checkout from 'ee/subscriptions/buy_addons_shared/components/checkout.vue';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
import {
mockCiMinutesPlans,
mockParsedNamespaces,
stateData as mockStateData,
} from 'ee_jest/subscriptions/mock_data';
import createMockApollo from 'helpers/mock_apollo_helper';
import createFlash from '~/flash';
import flushPromises from 'helpers/flush_promises';
jest.mock('~/flash');
const localVue = createLocalVue();
localVue.use(VueApollo);
describe('Checkout', () => {
let wrapper;
let updateState = jest.fn();
const [plan] = mockCiMinutesPlans;
const selectedNamespaceId = mockParsedNamespaces[0].id;
const initialStateData = {
eligibleNamespaces: mockParsedNamespaces,
selectedNamespaceId,
subscription: {},
};
const findBillingAddress = () => wrapper.findComponent(BillingAddress);
const findOrderConfirmation = () => wrapper.findComponent(OrderConfirmation);
const findPaymentMethod = () => wrapper.findComponent(PaymentMethod);
const createMockApolloProvider = (stateData = {}) => {
const resolvers = { Mutation: { updateState } };
const mockApollo = createMockApollo([], resolvers);
const data = merge({}, mockStateData, initialStateData, stateData);
mockApollo.clients.defaultClient.cache.writeQuery({
query: stateQuery,
data,
});
return mockApollo;
};
const createComponent = (stateData = {}) => {
const apolloProvider = createMockApolloProvider(stateData);
wrapper = shallowMountExtended(Checkout, {
localVue,
apolloProvider,
propsData: {
plan,
},
});
};
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
describe('when mounted', () => {
it('invokes the mutation with the correct params', () => {
const { id, isAddon } = plan;
expect(updateState).toHaveBeenNthCalledWith(
1,
expect.any(Object),
{ input: { selectedPlan: { id, isAddon } } },
expect.any(Object),
expect.any(Object),
);
});
it('renders a Billing Address Component', () => {
expect(findBillingAddress().exists()).toBe(true);
});
it('renders a Order Confirmation Component', () => {
expect(findOrderConfirmation().exists()).toBe(true);
});
it('renders a Payment Method Component', () => {
expect(findPaymentMethod().exists()).toBe(true);
});
});
describe('when the mutation fails', () => {
beforeEach(() => {
updateState = jest.fn().mockRejectedValue(new Error('Yikes!'));
createComponent();
return flushPromises();
});
it('displays a flash message', () => {
expect(createFlash).toHaveBeenCalledWith({
message: GENERAL_ERROR_MESSAGE,
// Apollo automatically wraps the resolver's error in a NetworkError
error: new Error('Network error: Yikes!'),
captureError: true,
});
});
});
});
...@@ -14,6 +14,7 @@ export const mockCiMinutesPlans = [ ...@@ -14,6 +14,7 @@ export const mockCiMinutesPlans = [
{ {
id: 'ciMinutesPackPlanId', id: 'ciMinutesPackPlanId',
code: 'ci_minutes', code: 'ci_minutes',
isAddon: true,
pricePerYear: 10, pricePerYear: 10,
name: 'CI minutes pack', name: 'CI minutes pack',
__typename: PLAN_TYPE, __typename: PLAN_TYPE,
......
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex'; import Vuex from 'vuex';
import ProgressBar from 'ee/registrations/components/progress_bar.vue'; import ProgressBar from 'ee/registrations/components/progress_bar.vue';
import Component from 'ee/subscriptions/new/components/checkout.vue'; import Component from 'ee/subscriptions/new/components/checkout.vue';
......
...@@ -26,7 +26,5 @@ export function createMockClient(handlers = [], resolvers = {}, cacheOptions = { ...@@ -26,7 +26,5 @@ export function createMockClient(handlers = [], resolvers = {}, cacheOptions = {
export default function createMockApollo(handlers, resolvers, cacheOptions) { export default function createMockApollo(handlers, resolvers, cacheOptions) {
const mockClient = createMockClient(handlers, resolvers, cacheOptions); const mockClient = createMockClient(handlers, resolvers, cacheOptions);
const apolloProvider = new VueApollo({ defaultClient: mockClient }); return new VueApollo({ defaultClient: mockClient });
return apolloProvider;
} }
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