Commit a7ca3737 authored by David O'Regan's avatar David O'Regan

Merge branch '321650-mlunoe-migrate-purchase-flow-components-follow-up' into 'master'

Feat(Purchase flow): Add steps error handling

See merge request gitlab-org/gitlab!58084
parents a7c591ee adef44af
<script> <script>
import { GlButton, GlLoadingIcon } from '@gitlab/ui'; import { GlButton, GlLoadingIcon } from '@gitlab/ui';
import { mapState, mapActions } from 'vuex'; import { mapState, mapActions } from 'vuex';
import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants';
import activeStepQuery from 'ee/vue_shared/purchase_flow/graphql/queries/active_step.query.graphql'; import activeStepQuery from 'ee/vue_shared/purchase_flow/graphql/queries/active_step.query.graphql';
import createFlash from '~/flash';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { STEPS } from '../../constants'; import { STEPS } from '../../constants';
...@@ -18,7 +20,10 @@ export default { ...@@ -18,7 +20,10 @@ export default {
apollo: { apollo: {
isActive: { isActive: {
query: activeStepQuery, query: activeStepQuery,
update: ({ activeStep }) => activeStep.id === STEPS[3].id, update: ({ activeStep }) => activeStep?.id === STEPS[3].id,
error: (error) => {
createFlash({ message: GENERAL_ERROR_MESSAGE, error, captureError: true });
},
}, },
}, },
computed: { computed: {
......
import Api from 'ee/api'; import Api from 'ee/api';
import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants';
import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/activate_next_step.mutation.graphql'; import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/activate_next_step.mutation.graphql';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { redirectTo } from '~/lib/utils/url_utility'; import { redirectTo } from '~/lib/utils/url_utility';
...@@ -169,8 +170,12 @@ export const fetchPaymentMethodDetails = ({ state, dispatch, commit }) => ...@@ -169,8 +170,12 @@ export const fetchPaymentMethodDetails = ({ state, dispatch, commit }) =>
export const fetchPaymentMethodDetailsSuccess = ({ commit }, creditCardDetails) => { export const fetchPaymentMethodDetailsSuccess = ({ commit }, creditCardDetails) => {
commit(types.UPDATE_CREDIT_CARD_DETAILS, creditCardDetails); commit(types.UPDATE_CREDIT_CARD_DETAILS, creditCardDetails);
defaultClient.mutate({ defaultClient
.mutate({
mutation: activateNextStepMutation, mutation: activateNextStepMutation,
})
.catch((error) => {
createFlash({ message: GENERAL_ERROR_MESSAGE, error, captureError: true });
}); });
}; };
......
...@@ -4,7 +4,9 @@ import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutati ...@@ -4,7 +4,9 @@ import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutati
import updateStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/update_active_step.mutation.graphql'; import updateStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/update_active_step.mutation.graphql';
import activeStepQuery from 'ee/vue_shared/purchase_flow/graphql/queries/active_step.query.graphql'; import activeStepQuery from 'ee/vue_shared/purchase_flow/graphql/queries/active_step.query.graphql';
import stepListQuery from 'ee/vue_shared/purchase_flow/graphql/queries/step_list.query.graphql'; import stepListQuery from 'ee/vue_shared/purchase_flow/graphql/queries/step_list.query.graphql';
import createFlash from '~/flash';
import { convertToSnakeCase, dasherize } from '~/lib/utils/text_utility'; import { convertToSnakeCase, dasherize } from '~/lib/utils/text_utility';
import { GENERAL_ERROR_MESSAGE } from '../constants';
import StepHeader from './step_header.vue'; import StepHeader from './step_header.vue';
import StepSummary from './step_summary.vue'; import StepSummary from './step_summary.vue';
...@@ -44,6 +46,9 @@ export default { ...@@ -44,6 +46,9 @@ export default {
apollo: { apollo: {
activeStep: { activeStep: {
query: activeStepQuery, query: activeStepQuery,
error(error) {
this.handleError(error);
},
}, },
stepList: { stepList: {
query: stepListQuery, query: stepListQuery,
...@@ -66,6 +71,9 @@ export default { ...@@ -66,6 +71,9 @@ export default {
}, },
}, },
methods: { methods: {
handleError(error) {
createFlash({ message: GENERAL_ERROR_MESSAGE, error, captureError: true });
},
async nextStep() { async nextStep() {
if (!this.isValid) { if (!this.isValid) {
return; return;
...@@ -75,6 +83,9 @@ export default { ...@@ -75,6 +83,9 @@ export default {
.mutate({ .mutate({
mutation: activateNextStepMutation, mutation: activateNextStepMutation,
}) })
.catch((error) => {
this.handleError(error);
})
.finally(() => { .finally(() => {
this.loading = false; this.loading = false;
}); });
...@@ -86,6 +97,9 @@ export default { ...@@ -86,6 +97,9 @@ export default {
mutation: updateStepMutation, mutation: updateStepMutation,
variables: { id: this.stepId }, variables: { id: this.stepId },
}) })
.catch((error) => {
this.handleError(error);
})
.finally(() => { .finally(() => {
this.loading = false; this.loading = false;
}); });
......
import { s__ } from '~/locale';
export const GENERAL_ERROR_MESSAGE = s__(
'PurchaseStep|An error occured in the purchase step. If the problem persists please contact support@gitlab.com.',
);
---
title: Add error handling feedback inside purchase flow
merge_request: 58084
author:
type: changed
...@@ -6,8 +6,11 @@ import Api from 'ee/api'; ...@@ -6,8 +6,11 @@ import Api from 'ee/api';
import ConfirmOrder from 'ee/subscriptions/new/components/checkout/confirm_order.vue'; import ConfirmOrder from 'ee/subscriptions/new/components/checkout/confirm_order.vue';
import { STEPS } from 'ee/subscriptions/new/constants'; import { STEPS } from 'ee/subscriptions/new/constants';
import createStore from 'ee/subscriptions/new/store'; import createStore from 'ee/subscriptions/new/store';
import updateStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/update_active_step.mutation.graphql'; import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants';
import { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_helper'; import { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_helper';
import flash from '~/flash';
jest.mock('~/flash');
describe('Confirm Order', () => { describe('Confirm Order', () => {
const localVue = createLocalVue(); const localVue = createLocalVue();
...@@ -15,19 +18,11 @@ describe('Confirm Order', () => { ...@@ -15,19 +18,11 @@ describe('Confirm Order', () => {
localVue.use(VueApollo); localVue.use(VueApollo);
let wrapper; let wrapper;
let mockApolloProvider;
jest.mock('ee/api.js'); jest.mock('ee/api.js');
const store = createStore(); const store = createStore();
function activateStep(stepId) {
return mockApolloProvider.clients.defaultClient.mutate({
mutation: updateStepMutation,
variables: { id: stepId },
});
}
function createComponent(options = {}) { function createComponent(options = {}) {
return shallowMount(ConfirmOrder, { return shallowMount(ConfirmOrder, {
localVue, localVue,
...@@ -39,18 +34,15 @@ describe('Confirm Order', () => { ...@@ -39,18 +34,15 @@ describe('Confirm Order', () => {
const findConfirmButton = () => wrapper.find(GlButton); const findConfirmButton = () => wrapper.find(GlButton);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon); const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
beforeEach(() => {
mockApolloProvider = createMockApolloProvider(STEPS);
wrapper = createComponent({ apolloProvider: mockApolloProvider });
});
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
}); });
describe('Active', () => { describe('Active', () => {
describe('when receiving proper step data', () => {
beforeEach(async () => { beforeEach(async () => {
await activateStep(STEPS[3].id); const mockApolloProvider = createMockApolloProvider(STEPS, 3);
wrapper = createComponent({ apolloProvider: mockApolloProvider });
}); });
it('button should be visible', () => { it('button should be visible', () => {
...@@ -64,9 +56,12 @@ describe('Confirm Order', () => { ...@@ -64,9 +56,12 @@ describe('Confirm Order', () => {
it('the loading indicator should not be visible', () => { it('the loading indicator should not be visible', () => {
expect(findLoadingIcon().exists()).toBe(false); expect(findLoadingIcon().exists()).toBe(false);
}); });
});
describe('Clicking the button', () => { describe('Clicking the button', () => {
beforeEach(() => { beforeEach(() => {
const mockApolloProvider = createMockApolloProvider(STEPS, 3);
wrapper = createComponent({ apolloProvider: mockApolloProvider });
Api.confirmOrder = jest.fn().mockReturnValue(new Promise(jest.fn())); Api.confirmOrder = jest.fn().mockReturnValue(new Promise(jest.fn()));
findConfirmButton().vm.$emit('click'); findConfirmButton().vm.$emit('click');
...@@ -84,11 +79,32 @@ describe('Confirm Order', () => { ...@@ -84,11 +79,32 @@ describe('Confirm Order', () => {
expect(findLoadingIcon().exists()).toBe(true); expect(findLoadingIcon().exists()).toBe(true);
}); });
}); });
describe('when failing to receive step data', () => {
beforeEach(async () => {
const mockApolloProvider = createMockApolloProvider([]);
mockApolloProvider.clients.defaultClient.clearStore();
wrapper = createComponent({ apolloProvider: mockApolloProvider });
});
afterEach(() => {
flash.mockClear();
});
it('displays an error', () => {
expect(flash.mock.calls[0][0]).toMatchObject({
message: GENERAL_ERROR_MESSAGE,
captureError: true,
error: expect.any(Error),
});
});
});
}); });
describe('Inactive', () => { describe('Inactive', () => {
beforeEach(async () => { beforeEach(async () => {
await activateStep(STEPS[1].id); const mockApolloProvider = createMockApolloProvider(STEPS, 1);
wrapper = createComponent({ apolloProvider: mockApolloProvider });
}); });
it('button should not be visible', () => { it('button should not be visible', () => {
......
...@@ -3,13 +3,18 @@ import { shallowMount, createLocalVue } from '@vue/test-utils'; ...@@ -3,13 +3,18 @@ import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue'; import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import StepSummary from 'ee/vue_shared/purchase_flow/components/step_summary.vue'; import StepSummary from 'ee/vue_shared/purchase_flow/components/step_summary.vue';
import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants';
import updateStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/update_active_step.mutation.graphql'; import updateStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/update_active_step.mutation.graphql';
import waitForPromises from 'helpers/wait_for_promises';
import flash from '~/flash';
import { STEPS } from '../mock_data'; import { STEPS } from '../mock_data';
import { createMockApolloProvider } from '../spec_helper'; import { createMockApolloProvider } from '../spec_helper';
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(VueApollo); localVue.use(VueApollo);
jest.mock('~/flash');
describe('Step', () => { describe('Step', () => {
let wrapper; let wrapper;
...@@ -32,11 +37,15 @@ describe('Step', () => { ...@@ -32,11 +37,15 @@ describe('Step', () => {
localVue, localVue,
propsData: { ...initialProps, ...propsData }, propsData: { ...initialProps, ...propsData },
apolloProvider, apolloProvider,
stubs: {
StepSummary,
},
}); });
} }
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
flash.mockClear();
}); });
describe('Step Body', () => { describe('Step Body', () => {
...@@ -61,7 +70,27 @@ describe('Step', () => { ...@@ -61,7 +70,27 @@ describe('Step', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); const mockApollo = createMockApolloProvider(STEPS, 1);
await activateFirstStep(mockApollo); await activateFirstStep(mockApollo);
wrapper = createComponent({ apolloProvider: mockApollo }); wrapper = createComponent({ apolloProvider: mockApollo });
expect(wrapper.find(StepSummary).exists()).toBe(true); expect(wrapper.findComponent(StepSummary).exists()).toBe(true);
});
it('displays an error when editing a wrong step', async () => {
const mockApollo = createMockApolloProvider(STEPS, 1);
await activateFirstStep(mockApollo);
wrapper = createComponent({
propsData: { stepId: 'does not exist' },
apolloProvider: mockApollo,
});
wrapper.findComponent(StepSummary).findComponent(GlButton).vm.$emit('click');
await waitForPromises();
expect(flash.mock.calls).toHaveLength(1);
expect(flash.mock.calls[0][0]).toMatchObject({
message: GENERAL_ERROR_MESSAGE,
captureError: true,
error: expect.any(Error),
});
}); });
it('should not be shown when this step is not valid and not active', async () => { it('should not be shown when this step is not valid and not active', async () => {
...@@ -69,21 +98,21 @@ describe('Step', () => { ...@@ -69,21 +98,21 @@ describe('Step', () => {
await activateFirstStep(mockApollo); await activateFirstStep(mockApollo);
wrapper = createComponent({ propsData: { isValid: false }, apolloProvider: mockApollo }); wrapper = createComponent({ propsData: { isValid: false }, apolloProvider: mockApollo });
expect(wrapper.find(StepSummary).exists()).toBe(false); expect(wrapper.findComponent(StepSummary).exists()).toBe(false);
}); });
it('should not be shown when this step is valid and active', () => { it('should not be shown when this step is valid and active', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); const mockApollo = createMockApolloProvider(STEPS, 1);
wrapper = createComponent({ apolloProvider: mockApollo }); wrapper = createComponent({ apolloProvider: mockApollo });
expect(wrapper.find(StepSummary).exists()).toBe(false); expect(wrapper.findComponent(StepSummary).exists()).toBe(false);
}); });
it('should not be shown when this step is not valid and active', () => { it('should not be shown when this step is not valid and active', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); const mockApollo = createMockApolloProvider(STEPS, 1);
wrapper = createComponent({ propsData: { isValid: false }, apolloProvider: mockApollo }); wrapper = createComponent({ propsData: { isValid: false }, apolloProvider: mockApollo });
expect(wrapper.find(StepSummary).exists()).toBe(false); expect(wrapper.findComponent(StepSummary).exists()).toBe(false);
}); });
}); });
...@@ -92,7 +121,7 @@ describe('Step', () => { ...@@ -92,7 +121,7 @@ describe('Step', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); const mockApollo = createMockApolloProvider(STEPS, 1);
wrapper = createComponent({ propsData: { stepId: STEPS[0].id }, apolloProvider: mockApollo }); wrapper = createComponent({ propsData: { stepId: STEPS[0].id }, apolloProvider: mockApollo });
expect(wrapper.find(StepSummary).props('isEditable')).toBe(true); expect(wrapper.findComponent(StepSummary).props('isEditable')).toBe(true);
}); });
}); });
...@@ -102,14 +131,14 @@ describe('Step', () => { ...@@ -102,14 +131,14 @@ describe('Step', () => {
await activateFirstStep(mockApollo); await activateFirstStep(mockApollo);
wrapper = createComponent({ apolloProvider: mockApollo }); wrapper = createComponent({ apolloProvider: mockApollo });
expect(wrapper.find(StepSummary).exists()).toBe(true); expect(wrapper.findComponent(StepSummary).exists()).toBe(true);
}); });
it('does not show the summary when this step is not finished', () => { it('does not show the summary when this step is not finished', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); const mockApollo = createMockApolloProvider(STEPS, 1);
wrapper = createComponent({ apolloProvider: mockApollo }); wrapper = createComponent({ apolloProvider: mockApollo });
expect(wrapper.find(StepSummary).exists()).toBe(false); expect(wrapper.findComponent(StepSummary).exists()).toBe(false);
}); });
}); });
...@@ -135,7 +164,7 @@ describe('Step', () => { ...@@ -135,7 +164,7 @@ describe('Step', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); const mockApollo = createMockApolloProvider(STEPS, 1);
wrapper = createComponent({ propsData: { isValid: false }, apolloProvider: mockApollo }); wrapper = createComponent({ propsData: { isValid: false }, apolloProvider: mockApollo });
expect(wrapper.find(GlButton).attributes('disabled')).toBe('true'); expect(wrapper.findComponent(GlButton).attributes('disabled')).toBe('true');
}); });
it('is enabled when this step is valid', () => { it('is enabled when this step is valid', () => {
...@@ -144,5 +173,20 @@ describe('Step', () => { ...@@ -144,5 +173,20 @@ describe('Step', () => {
expect(wrapper.find(GlButton).attributes('disabled')).toBeUndefined(); expect(wrapper.find(GlButton).attributes('disabled')).toBeUndefined();
}); });
it('displays an error if navigating too far', async () => {
const mockApollo = createMockApolloProvider(STEPS, 2);
wrapper = createComponent({ propsData: { stepId: STEPS[2].id }, apolloProvider: mockApollo });
wrapper.find(GlButton).vm.$emit('click');
await waitForPromises();
expect(flash.mock.calls).toHaveLength(1);
expect(flash.mock.calls[0][0]).toMatchObject({
message: GENERAL_ERROR_MESSAGE,
captureError: true,
error: expect.any(Error),
});
});
}); });
}); });
import { createMockClient } from 'mock-apollo-client';
import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/activate_next_step.mutation.graphql'; import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/activate_next_step.mutation.graphql';
import updateStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/update_active_step.mutation.graphql'; import updateStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/update_active_step.mutation.graphql';
import activeStepQuery from 'ee/vue_shared/purchase_flow/graphql/queries/active_step.query.graphql'; import activeStepQuery from 'ee/vue_shared/purchase_flow/graphql/queries/active_step.query.graphql';
import stepListQuery from 'ee/vue_shared/purchase_flow/graphql/queries/step_list.query.graphql'; import stepListQuery from 'ee/vue_shared/purchase_flow/graphql/queries/step_list.query.graphql';
import resolvers from 'ee/vue_shared/purchase_flow/graphql/resolvers';
import typeDefs from 'ee/vue_shared/purchase_flow/graphql/typedefs.graphql';
import { STEPS } from '../mock_data'; import { STEPS } from '../mock_data';
import { createMockApolloProvider } from '../spec_helper';
describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => { describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => {
let mockClient; let mockApolloClient;
describe('Query', () => {
beforeEach(async () => { beforeEach(async () => {
mockClient = createMockClient({ resolvers, typeDefs }); const mockApollo = createMockApolloProvider(STEPS, 0);
mockClient.cache.writeQuery({ mockApolloClient = mockApollo.clients.defaultClient;
query: stepListQuery,
data: {
stepList: STEPS,
},
});
mockClient.cache.writeQuery({
query: activeStepQuery,
data: {
activeStep: STEPS[0],
},
});
}); });
describe('Query', () => {
describe('stepListQuery', () => { describe('stepListQuery', () => {
it('stores the stepList', async () => { it('stores the stepList', async () => {
const queryResult = await mockClient.query({ query: stepListQuery }); const queryResult = await mockApolloClient.query({ query: stepListQuery });
expect(queryResult.data.stepList).toMatchObject( expect(queryResult.data.stepList).toMatchObject(
STEPS.map(({ id }) => { STEPS.map(({ id }) => {
return { id }; return { id };
...@@ -38,8 +25,8 @@ describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => { ...@@ -38,8 +25,8 @@ describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => {
}); });
it('throws an error when cache is not initiated properly', async () => { it('throws an error when cache is not initiated properly', async () => {
mockClient.clearStore(); mockApolloClient.clearStore();
await mockClient.query({ query: stepListQuery }).catch((e) => { await mockApolloClient.query({ query: stepListQuery }).catch((e) => {
expect(e instanceof Error).toBe(true); expect(e instanceof Error).toBe(true);
}); });
}); });
...@@ -47,13 +34,13 @@ describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => { ...@@ -47,13 +34,13 @@ describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => {
describe('activeStepQuery', () => { describe('activeStepQuery', () => {
it('stores the activeStep', async () => { it('stores the activeStep', async () => {
const queryResult = await mockClient.query({ query: activeStepQuery }); const queryResult = await mockApolloClient.query({ query: activeStepQuery });
expect(queryResult.data.activeStep).toMatchObject({ id: STEPS[0].id }); expect(queryResult.data.activeStep).toMatchObject({ id: STEPS[0].id });
}); });
it('throws an error when cache is not initiated properly', async () => { it('throws an error when cache is not initiated properly', async () => {
mockClient.clearStore(); mockApolloClient.clearStore();
await mockClient.query({ query: activeStepQuery }).catch((e) => { await mockApolloClient.query({ query: activeStepQuery }).catch((e) => {
expect(e instanceof Error).toBe(true); expect(e instanceof Error).toBe(true);
}); });
}); });
...@@ -62,18 +49,23 @@ describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => { ...@@ -62,18 +49,23 @@ describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => {
describe('Mutation', () => { describe('Mutation', () => {
describe('updateActiveStep', () => { describe('updateActiveStep', () => {
beforeEach(async () => {
const mockApollo = createMockApolloProvider(STEPS, 0);
mockApolloClient = mockApollo.clients.defaultClient;
});
it('updates the active step', async () => { it('updates the active step', async () => {
await mockClient.mutate({ await mockApolloClient.mutate({
mutation: updateStepMutation, mutation: updateStepMutation,
variables: { id: STEPS[1].id }, variables: { id: STEPS[1].id },
}); });
const queryResult = await mockClient.query({ query: activeStepQuery }); const queryResult = await mockApolloClient.query({ query: activeStepQuery });
expect(queryResult.data.activeStep).toMatchObject({ id: STEPS[1].id }); expect(queryResult.data.activeStep).toMatchObject({ id: STEPS[1].id });
}); });
it('throws an error when STEP is not present', async () => { it('throws an error when STEP is not present', async () => {
const id = 'does not exist'; const id = 'does not exist';
await mockClient await mockApolloClient
.mutate({ .mutate({
mutation: updateStepMutation, mutation: updateStepMutation,
variables: { id }, variables: { id },
...@@ -84,8 +76,8 @@ describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => { ...@@ -84,8 +76,8 @@ describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => {
}); });
it('throws an error when cache is not initiated properly', async () => { it('throws an error when cache is not initiated properly', async () => {
mockClient.clearStore(); mockApolloClient.clearStore();
await mockClient await mockApolloClient
.mutate({ .mutate({
mutation: updateStepMutation, mutation: updateStepMutation,
variables: { id: STEPS[1].id }, variables: { id: STEPS[1].id },
...@@ -98,19 +90,20 @@ describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => { ...@@ -98,19 +90,20 @@ describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => {
describe('activateNextStep', () => { describe('activateNextStep', () => {
it('updates the active step to the next', async () => { it('updates the active step to the next', async () => {
await mockClient.mutate({ const mockApollo = createMockApolloProvider(STEPS, 0);
mockApolloClient = mockApollo.clients.defaultClient;
await mockApolloClient.mutate({
mutation: activateNextStepMutation, mutation: activateNextStepMutation,
}); });
const queryResult = await mockClient.query({ query: activeStepQuery }); const queryResult = await mockApolloClient.query({ query: activeStepQuery });
expect(queryResult.data.activeStep).toMatchObject({ id: STEPS[1].id }); expect(queryResult.data.activeStep).toMatchObject({ id: STEPS[1].id });
}); });
it('throws an error when out of bounds', async () => { it('throws an error when out of bounds', async () => {
await mockClient.mutate({ const mockApollo = createMockApolloProvider(STEPS, 2);
mutation: activateNextStepMutation, mockApolloClient = mockApollo.clients.defaultClient;
});
await mockClient await mockApolloClient
.mutate({ .mutate({
mutation: activateNextStepMutation, mutation: activateNextStepMutation,
}) })
...@@ -120,8 +113,8 @@ describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => { ...@@ -120,8 +113,8 @@ describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => {
}); });
it('throws an error when cache is not initiated properly', async () => { it('throws an error when cache is not initiated properly', async () => {
mockClient.clearStore(); mockApolloClient.clearStore();
await mockClient await mockApolloClient
.mutate({ .mutate({
mutation: activateNextStepMutation, mutation: activateNextStepMutation,
}) })
......
export const STEPS = [ export const STEPS = [
{ __typename: 'Step', id: 'firstStep' }, { __typename: 'Step', id: 'firstStep' },
{ __typename: 'Step', id: 'secondStep' }, { __typename: 'Step', id: 'secondStep' },
{ __typename: 'Step', id: 'finalStep' },
]; ];
...@@ -25506,6 +25506,9 @@ msgstr "" ...@@ -25506,6 +25506,9 @@ msgstr ""
msgid "Purchase more storage" msgid "Purchase more storage"
msgstr "" msgstr ""
msgid "PurchaseStep|An error occured in the purchase step. If the problem persists please contact support@gitlab.com."
msgstr ""
msgid "Push" msgid "Push"
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