Commit 6933e70e authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch 'vs/migrate-confirm-order-to-gql' into 'master'

Migrate confirm order to GraphQL

See merge request gitlab-org/gitlab!64297
parents 3925df42 0ec56f1e
......@@ -4,11 +4,12 @@ import { STEPS, SUBSCRIPTON_FLOW_STEPS } from 'ee/registrations/constants';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
import { s__ } from '~/locale';
import BillingAddress from './checkout/billing_address.vue';
import ConfirmOrder from './checkout/confirm_order.vue';
import PaymentMethod from './checkout/payment_method.vue';
import SubscriptionDetails from './checkout/subscription_details.vue';
export default {
components: { ProgressBar, SubscriptionDetails, BillingAddress, PaymentMethod },
components: { ProgressBar, SubscriptionDetails, BillingAddress, PaymentMethod, ConfirmOrder },
props: {
plans: {
type: Array,
......@@ -40,5 +41,6 @@ export default {
<billing-address />
<payment-method />
</div>
<confirm-order />
</div>
</template>
<script>
import { GlButton, GlLoadingIcon } from '@gitlab/ui';
import Api from 'ee/api';
import { STEPS } from 'ee/subscriptions/constants';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
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 createFlash from '~/flash';
import { redirectTo } from '~/lib/utils/url_utility';
import { s__ } from '~/locale';
export default {
components: {
GlButton,
GlLoadingIcon,
},
data() {
return {
isActive: false,
isLoading: false,
};
},
apollo: {
isActive: {
query: activeStepQuery,
update: ({ activeStep }) => activeStep?.id === STEPS[3].id,
error: (error) => {
createFlash({ message: GENERAL_ERROR_MESSAGE, error, captureError: true });
},
},
confirmOrderParams: {
query: stateQuery,
update(data) {
const { customer } = data;
return {
setup_for_company: data.isSetupForCompany,
selected_group: data.subscription.namespaceId,
new_user: data.isNewUser,
customer: {
country: customer.country,
address_1: customer.address1,
address_2: customer.address2,
city: customer.city,
state: customer.state,
zip_code: customer.zipCode,
company: customer.company,
},
subscription: {
plan_id: data.selectedPlanId,
payment_method_id: data.paymentMethod.id,
quantity: data.subscription.quantity,
},
};
},
},
},
methods: {
confirmOrder() {
this.isLoading = true;
return Api.confirmOrder(this.confirmOrderParams)
.then(({ data }) => {
if (data.location) {
redirectTo(data.location);
} else {
throw new Error(JSON.stringify(data.errors));
}
})
.catch((error) =>
createFlash({ message: GENERAL_ERROR_MESSAGE, error, captureError: true }),
)
.finally(() => {
this.isLoading = false;
});
},
},
i18n: {
confirm: s__('Checkout|Confirm purchase'),
confirming: s__('Checkout|Confirming...'),
},
};
</script>
<template>
<div v-if="isActive" class="full-width gl-mb-7">
<gl-button :disabled="isLoading" variant="success" category="primary" @click="confirmOrder">
<gl-loading-icon v-if="isLoading" inline size="sm" />
{{ isLoading ? $options.i18n.confirming : $options.i18n.confirm }}
</gl-button>
</div>
</template>
import { GlButton, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import Api from 'ee/api';
import { STEPS } from 'ee/subscriptions/constants';
import ConfirmOrder from 'ee/subscriptions/new/components/checkout/confirm_order.vue';
import createStore from 'ee/subscriptions/new/store';
import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants';
import { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_helper';
import flash from '~/flash';
jest.mock('~/flash');
describe('Confirm Order', () => {
const localVue = createLocalVue();
localVue.use(VueApollo);
let wrapper;
jest.mock('ee/api.js');
const store = createStore();
function createComponent(options = {}) {
return shallowMount(ConfirmOrder, {
localVue,
store,
...options,
});
}
const findConfirmButton = () => wrapper.find(GlButton);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
afterEach(() => {
wrapper.destroy();
});
describe('Active', () => {
describe('when receiving proper step data', () => {
beforeEach(() => {
const mockApolloProvider = createMockApolloProvider(STEPS, 3);
wrapper = createComponent({ apolloProvider: mockApolloProvider });
});
it('button should be visible', () => {
expect(findConfirmButton().exists()).toBe(true);
});
it('shows the text "Confirm purchase"', () => {
expect(findConfirmButton().text()).toBe('Confirm purchase');
});
it('the loading indicator should not be visible', () => {
expect(findLoadingIcon().exists()).toBe(false);
});
});
describe('Clicking the button', () => {
beforeEach(() => {
const mockApolloProvider = createMockApolloProvider(STEPS, 3);
wrapper = createComponent({ apolloProvider: mockApolloProvider });
Api.confirmOrder = jest.fn().mockReturnValue(new Promise(jest.fn()));
findConfirmButton().vm.$emit('click');
});
it('calls the confirmOrder API method', () => {
expect(Api.confirmOrder).toHaveBeenCalled();
});
it('shows the text "Confirming..."', () => {
expect(findConfirmButton().text()).toBe('Confirming...');
});
it('the loading indicator should be visible', () => {
expect(findLoadingIcon().exists()).toBe(true);
});
});
describe('when failing to receive step data', () => {
beforeEach(() => {
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', () => {
beforeEach(() => {
const mockApolloProvider = createMockApolloProvider(STEPS, 1);
wrapper = createComponent({ apolloProvider: mockApolloProvider });
});
it('button should not be visible', () => {
expect(findConfirmButton().exists()).toBe(false);
});
});
});
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