Commit 42fdfa78 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch 'vs-revert-gql-in-purchase-flow' into 'master'

Revert Feat(Purchase Flow): migrate step components to use GraphQL

See merge request gitlab-org/gitlab!58565
parents d4df8986 f76123b5
<script> <script>
import StepOrderApp from 'ee/vue_shared/purchase_flow/components/step_order_app.vue'; import StepOrderApp from 'ee/vue_shared/components/step_order_app.vue';
export default { export default {
components: { components: {
......
<script> <script>
import StepOrderApp from 'ee/vue_shared/purchase_flow/components/step_order_app.vue'; import StepOrderApp from 'ee/vue_shared/components/step_order_app.vue';
import Checkout from './checkout.vue'; import Checkout from './checkout.vue';
import OrderSummary from './order_summary.vue'; import OrderSummary from './order_summary.vue';
......
...@@ -2,10 +2,9 @@ ...@@ -2,10 +2,9 @@
import { GlFormGroup, GlFormInput, GlFormSelect } from '@gitlab/ui'; import { GlFormGroup, GlFormInput, GlFormSelect } from '@gitlab/ui';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import { mapState, mapActions } from 'vuex'; import { mapState, mapActions } from 'vuex';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import autofocusonshow from '~/vue_shared/directives/autofocusonshow'; import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
import { STEPS } from '../../constants'; import Step from './step.vue';
export default { export default {
components: { components: {
...@@ -129,12 +128,11 @@ export default { ...@@ -129,12 +128,11 @@ export default {
stateSelectPrompt: s__('Checkout|Please select a state'), stateSelectPrompt: s__('Checkout|Please select a state'),
zipCodeLabel: s__('Checkout|Zip code'), zipCodeLabel: s__('Checkout|Zip code'),
}, },
stepId: STEPS[1].id,
}; };
</script> </script>
<template> <template>
<step <step
:step-id="$options.stepId" step="billingAddress"
:title="$options.i18n.stepTitle" :title="$options.i18n.stepTitle"
:is-valid="isValid" :is-valid="isValid"
:next-step-button-text="$options.i18n.nextStepButtonText" :next-step-button-text="$options.i18n.nextStepButtonText"
......
<script> <script>
import { GlButton, GlLoadingIcon } from '@gitlab/ui'; import { GlButton, GlLoadingIcon } from '@gitlab/ui';
import { mapState, mapActions } from 'vuex'; import { mapState, mapActions, mapGetters } from 'vuex';
import activeStepQuery from 'ee/vue_shared/purchase_flow/graphql/queries/active_step.query.graphql';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { STEPS } from '../../constants';
export default { export default {
components: { components: {
GlButton, GlButton,
GlLoadingIcon, GlLoadingIcon,
}, },
data() {
return {
isActive: {},
};
},
apollo: {
isActive: {
query: activeStepQuery,
update: ({ activeStep }) => activeStep.id === STEPS[3].id,
},
},
computed: { computed: {
...mapState(['isConfirmingOrder']), ...mapState(['isConfirmingOrder']),
...mapGetters(['currentStep']),
isActive() {
return this.currentStep === 'confirmOrder';
},
}, },
methods: { methods: {
...mapActions(['confirmOrder']), ...mapActions(['confirmOrder']),
......
<script> <script>
import { GlSprintf } from '@gitlab/ui'; import { GlSprintf } from '@gitlab/ui';
import { mapState } from 'vuex'; import { mapState } from 'vuex';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import { sprintf, s__ } from '~/locale'; import { sprintf, s__ } from '~/locale';
import { STEPS } from '../../constants'; import Step from './step.vue';
import Zuora from './zuora.vue'; import Zuora from './zuora.vue';
export default { export default {
...@@ -29,11 +28,10 @@ export default { ...@@ -29,11 +28,10 @@ export default {
creditCardDetails: s__('Checkout|%{cardType} ending in %{lastFourDigits}'), creditCardDetails: s__('Checkout|%{cardType} ending in %{lastFourDigits}'),
expirationDate: s__('Checkout|Exp %{expirationMonth}/%{expirationYear}'), expirationDate: s__('Checkout|Exp %{expirationMonth}/%{expirationYear}'),
}, },
stepId: STEPS[2].id,
}; };
</script> </script>
<template> <template>
<step :step-id="$options.stepId" :title="$options.i18n.stepTitle" :is-valid="isValid"> <step step="paymentMethod" :title="$options.i18n.stepTitle" :is-valid="isValid">
<template #body="props"> <template #body="props">
<zuora :active="props.active" /> <zuora :active="props.active" />
</template> </template>
......
<script> <script>
import { GlFormGroup, GlButton } from '@gitlab/ui'; import { GlFormGroup, GlButton } from '@gitlab/ui';
import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/activate_next_step.mutation.graphql'; import { mapActions, mapGetters } from 'vuex';
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 stepListQuery from 'ee/vue_shared/purchase_flow/graphql/queries/step_list.query.graphql';
import { convertToSnakeCase, dasherize } from '~/lib/utils/text_utility'; import { convertToSnakeCase, dasherize } from '~/lib/utils/text_utility';
import StepHeader from './step_header.vue'; import StepHeader from './step_header.vue';
import StepSummary from './step_summary.vue'; import StepSummary from './step_summary.vue';
...@@ -16,7 +13,7 @@ export default { ...@@ -16,7 +13,7 @@ export default {
StepSummary, StepSummary,
}, },
props: { props: {
stepId: { step: {
type: String, type: String,
required: true, required: true,
}, },
...@@ -34,61 +31,30 @@ export default { ...@@ -34,61 +31,30 @@ export default {
default: '', default: '',
}, },
}, },
data() {
return {
activeStep: {},
stepList: [],
loading: false,
};
},
apollo: {
activeStep: {
query: activeStepQuery,
},
stepList: {
query: stepListQuery,
},
},
computed: { computed: {
isActive() { isActive() {
return this.activeStep.id === this.stepId; return this.currentStep === this.step;
}, },
isFinished() { isFinished() {
return this.isValid && !this.isActive; return this.isValid && !this.isActive;
}, },
isEditable() { isEditable() {
const index = this.stepList.findIndex(({ id }) => id === this.stepId); return this.isFinished && this.stepIndex(this.step) < this.currentStepIndex;
const activeIndex = this.stepList.findIndex(({ id }) => id === this.activeStep.id);
return this.isFinished && index < activeIndex;
}, },
snakeCasedStep() { snakeCasedStep() {
return dasherize(convertToSnakeCase(this.stepId)); return dasherize(convertToSnakeCase(this.step));
}, },
...mapGetters(['currentStep', 'stepIndex', 'currentStepIndex']),
}, },
methods: { methods: {
async nextStep() { ...mapActions(['activateStep', 'activateNextStep']),
if (!this.isValid) { nextStep() {
return; if (this.isValid) {
this.activateNextStep();
} }
this.loading = true;
await this.$apollo
.mutate({
mutation: activateNextStepMutation,
})
.finally(() => {
this.loading = false;
});
}, },
async edit() { edit() {
this.loading = true; this.activateStep(this.step);
await this.$apollo
.mutate({
mutation: updateStepMutation,
variables: { id: this.stepId },
})
.finally(() => {
this.loading = false;
});
}, },
}, },
}; };
......
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
import { GlFormGroup, GlFormSelect, GlFormInput, GlSprintf, GlLink } from '@gitlab/ui'; import { GlFormGroup, GlFormSelect, GlFormInput, GlSprintf, GlLink } from '@gitlab/ui';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import { mapState, mapGetters, mapActions } from 'vuex'; import { mapState, mapGetters, mapActions } from 'vuex';
import { NEW_GROUP, STEPS } from 'ee/subscriptions/new/constants'; import { NEW_GROUP } from 'ee/subscriptions/new/constants';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import { sprintf, s__ } from '~/locale'; import { sprintf, s__ } from '~/locale';
import autofocusonshow from '~/vue_shared/directives/autofocusonshow'; import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
import Step from './step.vue';
export default { export default {
components: { components: {
...@@ -133,12 +133,11 @@ export default { ...@@ -133,12 +133,11 @@ export default {
group: s__('Checkout|Group'), group: s__('Checkout|Group'),
users: s__('Checkout|Users'), users: s__('Checkout|Users'),
}, },
stepId: STEPS[0].id,
}; };
</script> </script>
<template> <template>
<step <step
:step-id="$options.stepId" step="subscriptionDetails"
:title="$options.i18n.stepTitle" :title="$options.i18n.stepTitle"
:is-valid="isValid" :is-valid="isValid"
:next-step-button-text="$options.i18n.nextStepButtonText" :next-step-button-text="$options.i18n.nextStepButtonText"
......
// The order of the steps in this array determines the flow of the application // The order of the steps in this array determines the flow of the application
/* eslint-disable @gitlab/require-i18n-strings */ export const STEPS = ['subscriptionDetails', 'billingAddress', 'paymentMethod', 'confirmOrder'];
export const STEPS = [
{ id: 'subscriptionDetails', __typename: 'Step' },
{ id: 'billingAddress', __typename: 'Step' },
{ id: 'paymentMethod', __typename: 'Step' },
{ id: 'confirmOrder', __typename: 'Step' },
];
/* eslint-enable @gitlab/require-i18n-strings */
export const ZUORA_SCRIPT_URL = 'https://static.zuora.com/Resources/libs/hosted/1.3.1/zuora-min.js'; export const ZUORA_SCRIPT_URL = 'https://static.zuora.com/Resources/libs/hosted/1.3.1/zuora-min.js';
......
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 resolvers from 'ee/vue_shared/purchase_flow/graphql/resolvers';
import typeDefs from 'ee/vue_shared/purchase_flow/graphql/typedefs.graphql';
import createDefaultClient from '~/lib/graphql';
export default function createClient(stepList) {
const client = createDefaultClient(resolvers, {
typeDefs,
assumeImmutableResults: true,
});
client.cache.writeQuery({
query: stepListQuery,
data: {
stepList,
},
});
client.cache.writeQuery({
query: activeStepQuery,
data: {
activeStep: stepList[0],
},
});
return client;
}
import Vue from 'vue'; import Vue from 'vue';
import VueApollo from 'vue-apollo';
import App from './components/app.vue'; import App from './components/app.vue';
import { STEPS } from './constants';
import createClient from './graphql';
import createStore from './store'; import createStore from './store';
Vue.use(VueApollo);
const defaultClient = createClient(STEPS);
const apolloProvider = new VueApollo({
defaultClient,
});
export default () => { export default () => {
const el = document.getElementById('js-new-subscription'); const el = document.getElementById('js-new-subscription');
const store = createStore(el.dataset); const store = createStore(el.dataset);
...@@ -19,7 +9,6 @@ export default () => { ...@@ -19,7 +9,6 @@ export default () => {
return new Vue({ return new Vue({
el, el,
store, store,
apolloProvider,
components: { components: {
App, App,
}, },
......
import Api from 'ee/api'; import Api from 'ee/api';
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';
import { sprintf, s__ } from '~/locale'; import { sprintf, s__ } from '~/locale';
import { PAYMENT_FORM_ID } from '../constants'; import { STEPS, PAYMENT_FORM_ID } from '../constants';
import defaultClient from '../graphql';
import * as types from './mutation_types'; import * as types from './mutation_types';
export const activateStep = ({ commit }, currentStep) => {
if (STEPS.includes(currentStep)) {
commit(types.UPDATE_CURRENT_STEP, currentStep);
}
};
export const activateNextStep = ({ commit, getters }) => {
const { currentStepIndex } = getters;
if (currentStepIndex < STEPS.length - 1) {
const nextStep = STEPS[currentStepIndex + 1];
commit(types.UPDATE_CURRENT_STEP, nextStep);
}
};
export const updateSelectedPlan = ({ commit }, selectedPlan) => { export const updateSelectedPlan = ({ commit }, selectedPlan) => {
commit(types.UPDATE_SELECTED_PLAN, selectedPlan); commit(types.UPDATE_SELECTED_PLAN, selectedPlan);
}; };
...@@ -166,12 +180,10 @@ export const fetchPaymentMethodDetails = ({ state, dispatch, commit }) => ...@@ -166,12 +180,10 @@ export const fetchPaymentMethodDetails = ({ state, dispatch, commit }) =>
.catch(() => dispatch('fetchPaymentMethodDetailsError')) .catch(() => dispatch('fetchPaymentMethodDetailsError'))
.finally(() => commit(types.UPDATE_IS_LOADING_PAYMENT_METHOD, false)); .finally(() => commit(types.UPDATE_IS_LOADING_PAYMENT_METHOD, false));
export const fetchPaymentMethodDetailsSuccess = ({ commit }, creditCardDetails) => { export const fetchPaymentMethodDetailsSuccess = ({ commit, dispatch }, creditCardDetails) => {
commit(types.UPDATE_CREDIT_CARD_DETAILS, creditCardDetails); commit(types.UPDATE_CREDIT_CARD_DETAILS, creditCardDetails);
defaultClient.mutate({ dispatch('activateNextStep');
mutation: activateNextStepMutation,
});
}; };
export const fetchPaymentMethodDetailsError = () => { export const fetchPaymentMethodDetailsError = () => {
......
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { NEW_GROUP } from '../constants'; import { STEPS, NEW_GROUP } from '../constants';
export const currentStep = (state) => state.currentStep;
export const stepIndex = () => (step) => STEPS.findIndex((el) => el === step);
export const currentStepIndex = (state, getters) => getters.stepIndex(state.currentStep);
export const selectedPlanText = (state, getters) => getters.selectedPlanDetails.text; export const selectedPlanText = (state, getters) => getters.selectedPlanDetails.text;
......
export const UPDATE_CURRENT_STEP = 'UPDATE_CURRENT_STEP';
export const UPDATE_SELECTED_PLAN = 'UPDATE_SELECTED_PLAN'; export const UPDATE_SELECTED_PLAN = 'UPDATE_SELECTED_PLAN';
export const UPDATE_SELECTED_GROUP = 'UPDATE_SELECTED_GROUP'; export const UPDATE_SELECTED_GROUP = 'UPDATE_SELECTED_GROUP';
......
import * as types from './mutation_types'; import * as types from './mutation_types';
export default { export default {
[types.UPDATE_CURRENT_STEP](state, currentStep) {
state.currentStep = currentStep;
},
[types.UPDATE_SELECTED_PLAN](state, selectedPlan) { [types.UPDATE_SELECTED_PLAN](state, selectedPlan) {
state.selectedPlan = selectedPlan; state.selectedPlan = selectedPlan;
}, },
......
import { parseBoolean } from '~/lib/utils/common_utils'; import { parseBoolean } from '~/lib/utils/common_utils';
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility'; import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
import { TAX_RATE } from '../constants'; import { STEPS, TAX_RATE } from '../constants';
const parsePlanData = (planData) => const parsePlanData = (planData) =>
JSON.parse(planData).map((plan) => ({ JSON.parse(planData).map((plan) => ({
...@@ -52,6 +52,7 @@ export default ({ ...@@ -52,6 +52,7 @@ export default ({
const groups = parseGroupData(groupData); const groups = parseGroupData(groupData);
return { return {
currentStep: STEPS[0],
isSetupForCompany: parseBoolean(setupForCompany) || !isNewUser, isSetupForCompany: parseBoolean(setupForCompany) || !isNewUser,
availablePlans, availablePlans,
selectedPlan: determineSelectedPlan(planId, availablePlans), selectedPlan: determineSelectedPlan(planId, availablePlans),
......
...@@ -4,7 +4,7 @@ import { createWrapper } from '@vue/test-utils'; ...@@ -4,7 +4,7 @@ import { createWrapper } from '@vue/test-utils';
import initBuyMinutesApp from 'ee/subscriptions/buy_minutes'; import initBuyMinutesApp from 'ee/subscriptions/buy_minutes';
import * as utils from 'ee/subscriptions/buy_minutes/utils'; import * as utils from 'ee/subscriptions/buy_minutes/utils';
import StepOrderApp from 'ee/vue_shared/purchase_flow/components/step_order_app.vue'; import StepOrderApp from 'ee/vue_shared/components/step_order_app.vue';
import { mockCiMinutesPlans, mockParsedCiMinutesPlans } from './mock_data'; import { mockCiMinutesPlans, mockParsedCiMinutesPlans } from './mock_data';
jest.mock('ee/subscriptions/buy_minutes/utils'); jest.mock('ee/subscriptions/buy_minutes/utils');
......
import { mount, createLocalVue } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue'; import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import Vuex from 'vuex'; import Vuex from 'vuex';
import BillingAddress from 'ee/subscriptions/new/components/checkout/billing_address.vue'; import Component from 'ee/subscriptions/new/components/checkout/billing_address.vue';
import { STEPS } from 'ee/subscriptions/new/constants'; import Step from 'ee/subscriptions/new/components/checkout/step.vue';
import { getStoreConfig } from 'ee/subscriptions/new/store'; import { getStoreConfig } from 'ee/subscriptions/new/store';
import * as types from 'ee/subscriptions/new/store/mutation_types'; import * as types from 'ee/subscriptions/new/store/mutation_types';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/activate_next_step.mutation.graphql';
import { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_helper';
const localVue = createLocalVue(); Vue.use(Vuex);
localVue.use(Vuex);
localVue.use(VueApollo);
describe('Billing Address', () => { describe('Billing Address', () => {
let store; let store;
let wrapper; let wrapper;
let mockApolloProvider;
const actionMocks = { const actionMocks = {
fetchCountries: jest.fn(), fetchCountries: jest.fn(),
fetchStates: jest.fn(), fetchStates: jest.fn(),
}; };
function activateNextStep() { const createComponent = () => {
return mockApolloProvider.clients.defaultClient.mutate({
mutation: activateNextStepMutation,
});
}
function createStore() {
const { actions, ...storeConfig } = getStoreConfig(); const { actions, ...storeConfig } = getStoreConfig();
return new Vuex.Store({ store = new Vuex.Store({
...storeConfig, ...storeConfig,
actions: { ...actions, ...actionMocks }, actions: { ...actions, ...actionMocks },
}); });
}
function createComponent(options = {}) { wrapper = mount(Component, {
return mount(BillingAddress, { store,
localVue,
...options,
}); });
} };
beforeEach(() => { beforeEach(() => {
store = createStore(); createComponent();
mockApolloProvider = createMockApolloProvider(STEPS);
wrapper = createComponent({ store, apolloProvider: mockApolloProvider });
}); });
afterEach(() => { afterEach(() => {
...@@ -128,15 +110,14 @@ describe('Billing Address', () => { ...@@ -128,15 +110,14 @@ describe('Billing Address', () => {
}); });
describe('showing the summary', () => { describe('showing the summary', () => {
beforeEach(async () => { beforeEach(() => {
store.commit(types.UPDATE_COUNTRY, 'country'); store.commit(types.UPDATE_COUNTRY, 'country');
store.commit(types.UPDATE_STREET_ADDRESS_LINE_ONE, 'address line 1'); store.commit(types.UPDATE_STREET_ADDRESS_LINE_ONE, 'address line 1');
store.commit(types.UPDATE_STREET_ADDRESS_LINE_TWO, 'address line 2'); store.commit(types.UPDATE_STREET_ADDRESS_LINE_TWO, 'address line 2');
store.commit(types.UPDATE_COUNTRY_STATE, 'state'); store.commit(types.UPDATE_COUNTRY_STATE, 'state');
store.commit(types.UPDATE_CITY, 'city'); store.commit(types.UPDATE_CITY, 'city');
store.commit(types.UPDATE_ZIP_CODE, 'zip'); store.commit(types.UPDATE_ZIP_CODE, 'zip');
await activateNextStep(); store.commit(types.UPDATE_CURRENT_STEP, 'nextStep');
await activateNextStep();
}); });
it('should show the entered address line 1', () => { it('should show the entered address line 1', () => {
......
import { GlButton, GlLoadingIcon } from '@gitlab/ui'; import { GlButton, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import Vuex from 'vuex'; import Vuex from 'vuex';
import Api from 'ee/api'; import Api from 'ee/api';
import ConfirmOrder from 'ee/subscriptions/new/components/checkout/confirm_order.vue'; import Component from 'ee/subscriptions/new/components/checkout/confirm_order.vue';
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 * as types from 'ee/subscriptions/new/store/mutation_types';
import { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_helper';
describe('Confirm Order', () => { describe('Confirm Order', () => {
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
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) { const createComponent = (opts = {}) => {
return mockApolloProvider.clients.defaultClient.mutate({ wrapper = shallowMount(Component, {
mutation: updateStepMutation,
variables: { id: stepId },
});
}
function createComponent(options = {}) {
return shallowMount(ConfirmOrder, {
localVue, localVue,
store, store,
...options, ...opts,
}); });
} };
const findConfirmButton = () => wrapper.find(GlButton); const findConfirmButton = () => wrapper.find(GlButton);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon); const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
beforeEach(() => { beforeEach(() => {
mockApolloProvider = createMockApolloProvider(STEPS); createComponent();
wrapper = createComponent({ apolloProvider: mockApolloProvider });
}); });
afterEach(() => { afterEach(() => {
...@@ -49,8 +36,8 @@ describe('Confirm Order', () => { ...@@ -49,8 +36,8 @@ describe('Confirm Order', () => {
}); });
describe('Active', () => { describe('Active', () => {
beforeEach(async () => { beforeEach(() => {
await activateStep(STEPS[3].id); store.commit(types.UPDATE_CURRENT_STEP, 'confirmOrder');
}); });
it('button should be visible', () => { it('button should be visible', () => {
...@@ -87,8 +74,8 @@ describe('Confirm Order', () => { ...@@ -87,8 +74,8 @@ describe('Confirm Order', () => {
}); });
describe('Inactive', () => { describe('Inactive', () => {
beforeEach(async () => { beforeEach(() => {
await activateStep(STEPS[1].id); store.commit(types.UPDATE_CURRENT_STEP, 'otherStep');
}); });
it('button should not be visible', () => { it('button should not be visible', () => {
......
import { mount, createLocalVue } from '@vue/test-utils'; import { mount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import Vuex from 'vuex'; import Vuex from 'vuex';
import PaymentMethod from 'ee/subscriptions/new/components/checkout/payment_method.vue'; import Component from 'ee/subscriptions/new/components/checkout/payment_method.vue';
import { STEPS } from 'ee/subscriptions/new/constants'; import Step from 'ee/subscriptions/new/components/checkout/step.vue';
import createStore from 'ee/subscriptions/new/store'; import createStore from 'ee/subscriptions/new/store';
import * as types from 'ee/subscriptions/new/store/mutation_types'; import * as types from 'ee/subscriptions/new/store/mutation_types';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_helper';
describe('Payment Method', () => { describe('Payment Method', () => {
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
localVue.use(VueApollo);
let store; let store;
let wrapper; let wrapper;
function createComponent(options = {}) { const createComponent = (opts = {}) => {
return mount(PaymentMethod, { wrapper = mount(Component, {
localVue, localVue,
store, store,
...options, ...opts,
}); });
} };
beforeEach(() => { beforeEach(() => {
store = createStore(); store = createStore();
...@@ -35,8 +31,7 @@ describe('Payment Method', () => { ...@@ -35,8 +31,7 @@ describe('Payment Method', () => {
credit_card_expiration_year: 2009, credit_card_expiration_year: 2009,
}); });
const mockApollo = createMockApolloProvider(STEPS); createComponent();
wrapper = createComponent({ apolloProvider: mockApollo });
}); });
afterEach(() => { afterEach(() => {
......
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo'; import Vuex from 'vuex';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue'; import Component from 'ee/subscriptions/new/components/checkout/step.vue';
import StepSummary from 'ee/vue_shared/purchase_flow/components/step_summary.vue'; import StepSummary from 'ee/subscriptions/new/components/checkout/step_summary.vue';
import updateStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/update_active_step.mutation.graphql'; import * as constants from 'ee/subscriptions/new/constants';
import { STEPS } from '../mock_data'; import createStore from 'ee/subscriptions/new/store';
import { createMockApolloProvider } from '../spec_helper';
const localVue = createLocalVue();
localVue.use(VueApollo);
describe('Step', () => { describe('Step', () => {
const localVue = createLocalVue();
localVue.use(Vuex);
let store;
let wrapper; let wrapper;
const initialProps = { const initialProps = {
stepId: STEPS[1].id, step: 'secondStep',
isValid: true, isValid: true,
title: 'title', title: 'title',
nextStepButtonText: 'next', nextStepButtonText: 'next',
}; };
function activateFirstStep(apolloProvider) { const createComponent = (propsData) => {
return apolloProvider.clients.defaultClient.mutate({ wrapper = shallowMount(Component, {
mutation: updateStepMutation,
variables: { id: STEPS[0].id },
});
}
function createComponent(options = {}) {
const { apolloProvider, propsData } = options;
return shallowMount(Step, {
localVue,
propsData: { ...initialProps, ...propsData }, propsData: { ...initialProps, ...propsData },
apolloProvider, localVue,
store,
});
};
const activatePreviousStep = () => {
store.dispatch('activateStep', 'firstStep');
};
constants.STEPS = ['firstStep', 'secondStep'];
beforeEach(() => {
store = createStore();
store.dispatch('activateStep', 'secondStep');
}); });
}
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
...@@ -41,47 +45,42 @@ describe('Step', () => { ...@@ -41,47 +45,42 @@ describe('Step', () => {
describe('Step Body', () => { describe('Step Body', () => {
it('should display the step body when this step is the current step', () => { it('should display the step body when this step is the current step', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); createComponent();
wrapper = createComponent({ apolloProvider: mockApollo });
expect(wrapper.find('.card > div').attributes('style')).toBeUndefined(); expect(wrapper.find('.card > div').attributes('style')).toBeUndefined();
}); });
it('should not display the step body when this step is not the current step', async () => { it('should not display the step body when this step is not the current step', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); activatePreviousStep();
await activateFirstStep(mockApollo); createComponent();
wrapper = createComponent({ apolloProvider: mockApollo });
expect(wrapper.find('.card > div').attributes('style')).toBe('display: none;'); expect(wrapper.find('.card > div').attributes('style')).toBe('display: none;');
}); });
}); });
describe('Step Summary', () => { describe('Step Summary', () => {
it('should be shown when this step is valid and not active', async () => { it('should be shown when this step is valid and not active', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); activatePreviousStep();
await activateFirstStep(mockApollo); createComponent();
wrapper = createComponent({ apolloProvider: mockApollo });
expect(wrapper.find(StepSummary).exists()).toBe(true); expect(wrapper.find(StepSummary).exists()).toBe(true);
}); });
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', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); activatePreviousStep();
await activateFirstStep(mockApollo); createComponent({ isValid: false });
wrapper = createComponent({ propsData: { isValid: false }, apolloProvider: mockApollo });
expect(wrapper.find(StepSummary).exists()).toBe(false); expect(wrapper.find(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); createComponent();
wrapper = createComponent({ apolloProvider: mockApollo });
expect(wrapper.find(StepSummary).exists()).toBe(false); expect(wrapper.find(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); createComponent({ isValid: false });
wrapper = createComponent({ propsData: { isValid: false }, apolloProvider: mockApollo });
expect(wrapper.find(StepSummary).exists()).toBe(false); expect(wrapper.find(StepSummary).exists()).toBe(false);
}); });
...@@ -89,25 +88,22 @@ describe('Step', () => { ...@@ -89,25 +88,22 @@ describe('Step', () => {
describe('isEditable', () => { describe('isEditable', () => {
it('should set the isEditable property to true when this step is finished and comes before the current step', () => { it('should set the isEditable property to true when this step is finished and comes before the current step', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); createComponent({ step: 'firstStep' });
wrapper = createComponent({ propsData: { stepId: STEPS[0].id }, apolloProvider: mockApollo });
expect(wrapper.find(StepSummary).props('isEditable')).toBe(true); expect(wrapper.find(StepSummary).props('isEditable')).toBe(true);
}); });
}); });
describe('Showing the summary', () => { describe('Showing the summary', () => {
it('shows the summary when this step is finished', async () => { it('shows the summary when this step is finished', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); activatePreviousStep();
await activateFirstStep(mockApollo); createComponent();
wrapper = createComponent({ apolloProvider: mockApollo });
expect(wrapper.find(StepSummary).exists()).toBe(true); expect(wrapper.find(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); createComponent();
wrapper = createComponent({ apolloProvider: mockApollo });
expect(wrapper.find(StepSummary).exists()).toBe(false); expect(wrapper.find(StepSummary).exists()).toBe(false);
}); });
...@@ -115,32 +111,25 @@ describe('Step', () => { ...@@ -115,32 +111,25 @@ describe('Step', () => {
describe('Next button', () => { describe('Next button', () => {
it('shows the next button when the text was passed', () => { it('shows the next button when the text was passed', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); createComponent();
wrapper = createComponent({ apolloProvider: mockApollo });
expect(wrapper.text()).toBe('next'); expect(wrapper.text()).toBe('next');
}); });
it('does not show the next button when no text was passed', () => { it('does not show the next button when no text was passed', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); createComponent({ nextStepButtonText: '' });
wrapper = createComponent({
propsData: { nextStepButtonText: '' },
apolloProvider: mockApollo,
});
expect(wrapper.text()).toBe(''); expect(wrapper.text()).toBe('');
}); });
it('is disabled when this step is not valid', () => { it('is disabled when this step is not valid', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); createComponent({ isValid: false });
wrapper = createComponent({ propsData: { isValid: false }, apolloProvider: mockApollo });
expect(wrapper.find(GlButton).attributes('disabled')).toBe('true'); expect(wrapper.find(GlButton).attributes('disabled')).toBe('true');
}); });
it('is enabled when this step is valid', () => { it('is enabled when this step is valid', () => {
const mockApollo = createMockApolloProvider(STEPS, 1); createComponent();
wrapper = createComponent({ apolloProvider: mockApollo });
expect(wrapper.find(GlButton).attributes('disabled')).toBeUndefined(); expect(wrapper.find(GlButton).attributes('disabled')).toBeUndefined();
}); });
......
import { mount, createLocalVue } from '@vue/test-utils'; import { mount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import Vuex from 'vuex'; import Vuex from 'vuex';
import Step from 'ee/subscriptions/new/components/checkout/step.vue';
import Component from 'ee/subscriptions/new/components/checkout/subscription_details.vue'; import Component from 'ee/subscriptions/new/components/checkout/subscription_details.vue';
import { NEW_GROUP, STEPS } from 'ee/subscriptions/new/constants'; import { NEW_GROUP } from 'ee/subscriptions/new/constants';
import createStore from 'ee/subscriptions/new/store'; import createStore from 'ee/subscriptions/new/store';
import * as types from 'ee/subscriptions/new/store/mutation_types'; import * as types from 'ee/subscriptions/new/store/mutation_types';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_helper';
const availablePlans = [ describe('Subscription Details', () => {
const localVue = createLocalVue();
localVue.use(Vuex);
let store;
let wrapper;
const availablePlans = [
{ id: 'firstPlanId', code: 'bronze', price_per_year: 48, name: 'bronze' }, { id: 'firstPlanId', code: 'bronze', price_per_year: 48, name: 'bronze' },
{ id: 'secondPlanId', code: 'silver', price_per_year: 228, name: 'silver' }, { id: 'secondPlanId', code: 'silver', price_per_year: 228, name: 'silver' },
]; ];
const groupData = [ const groupData = [
{ id: 132, name: 'My first group', users: 3 }, { id: 132, name: 'My first group', users: 3 },
{ id: 483, name: 'My second group', users: 12 }, { id: 483, name: 'My second group', users: 12 },
]; ];
const defaultInitialStoreData = { let initialNamespaceId = null;
const initialData = (namespaceId) => {
return {
availablePlans: JSON.stringify(availablePlans), availablePlans: JSON.stringify(availablePlans),
groupData: JSON.stringify(groupData), groupData: JSON.stringify(groupData),
planId: 'secondPlanId', planId: 'secondPlanId',
namespaceId: null, namespaceId,
setupForCompany: 'true', setupForCompany: 'true',
fullName: 'Full Name', fullName: 'Full Name',
}; };
};
describe('Subscription Details', () => {
const localVue = createLocalVue();
localVue.use(Vuex);
localVue.use(VueApollo);
let wrapper;
function createComponent(options = {}) { const createComponent = () => {
const { apolloProvider, store } = options; wrapper = mount(Component, {
return mount(Component, {
localVue, localVue,
store, store,
apolloProvider,
stubs: {
Step,
},
}); });
} };
const organizationNameInput = () => wrapper.find({ ref: 'organization-name' }); const organizationNameInput = () => wrapper.find({ ref: 'organization-name' });
const groupSelect = () => wrapper.find({ ref: 'group-select' }); const groupSelect = () => wrapper.find({ ref: 'group-select' });
const numberOfUsersInput = () => wrapper.find({ ref: 'number-of-users' }); const numberOfUsersInput = () => wrapper.find({ ref: 'number-of-users' });
const companyLink = () => wrapper.find({ ref: 'company-link' }); const companyLink = () => wrapper.find({ ref: 'company-link' });
beforeEach(() => {
store = createStore(initialData(initialNamespaceId));
createComponent();
});
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
}); });
describe('A new user setting up for personal use', () => { describe('A new user setting up for personal use', () => {
beforeEach(() => { beforeEach(() => {
const mockApollo = createMockApolloProvider(STEPS);
const store = createStore(defaultInitialStoreData);
store.state.isNewUser = true; store.state.isNewUser = true;
store.state.isSetupForCompany = false; store.state.isSetupForCompany = false;
wrapper = createComponent({ apolloProvider: mockApollo, store });
}); });
it('should not display an input field for the company or group name', () => { it('should not display an input field for the company or group name', () => {
...@@ -87,11 +85,8 @@ describe('Subscription Details', () => { ...@@ -87,11 +85,8 @@ describe('Subscription Details', () => {
describe('A new user setting up for a company or group', () => { describe('A new user setting up for a company or group', () => {
beforeEach(() => { beforeEach(() => {
const mockApollo = createMockApolloProvider(STEPS);
const store = createStore(defaultInitialStoreData);
store.state.isNewUser = true; store.state.isNewUser = true;
store.state.groupData = []; store.state.groupData = [];
wrapper = createComponent({ apolloProvider: mockApollo, store });
}); });
it('should display an input field for the company or group name', () => { it('should display an input field for the company or group name', () => {
...@@ -117,11 +112,8 @@ describe('Subscription Details', () => { ...@@ -117,11 +112,8 @@ describe('Subscription Details', () => {
describe('An existing user without any groups', () => { describe('An existing user without any groups', () => {
beforeEach(() => { beforeEach(() => {
const mockApollo = createMockApolloProvider(STEPS);
const store = createStore(defaultInitialStoreData);
store.state.isNewUser = false; store.state.isNewUser = false;
store.state.groupData = []; store.state.groupData = [];
wrapper = createComponent({ apolloProvider: mockApollo, store });
}); });
it('should display an input field for the company or group name', () => { it('should display an input field for the company or group name', () => {
...@@ -146,13 +138,8 @@ describe('Subscription Details', () => { ...@@ -146,13 +138,8 @@ describe('Subscription Details', () => {
}); });
describe('An existing user with groups', () => { describe('An existing user with groups', () => {
let store;
beforeEach(() => { beforeEach(() => {
const mockApollo = createMockApolloProvider(STEPS);
store = createStore(defaultInitialStoreData);
store.state.isNewUser = false; store.state.isNewUser = false;
wrapper = createComponent({ apolloProvider: mockApollo, store });
}); });
it('should not display an input field for the company or group name', () => { it('should not display an input field for the company or group name', () => {
...@@ -209,13 +196,9 @@ describe('Subscription Details', () => { ...@@ -209,13 +196,9 @@ describe('Subscription Details', () => {
}); });
describe('An existing user coming from group billing page', () => { describe('An existing user coming from group billing page', () => {
let store;
beforeEach(() => { beforeEach(() => {
const mockApollo = createMockApolloProvider(STEPS); initialNamespaceId = '132';
store = createStore({ ...defaultInitialStoreData, namespaceId: '132' });
store.state.isNewUser = false; store.state.isNewUser = false;
wrapper = createComponent({ apolloProvider: mockApollo, store });
}); });
it('should not display an input field for the company or group name', () => { it('should not display an input field for the company or group name', () => {
...@@ -263,13 +246,6 @@ describe('Subscription Details', () => { ...@@ -263,13 +246,6 @@ describe('Subscription Details', () => {
describe('validations', () => { describe('validations', () => {
const isStepValid = () => wrapper.find(Step).props('isValid'); const isStepValid = () => wrapper.find(Step).props('isValid');
let store;
beforeEach(() => {
const mockApollo = createMockApolloProvider(STEPS);
store = createStore(defaultInitialStoreData);
wrapper = createComponent({ apolloProvider: mockApollo, store });
});
describe('when setting up for a company', () => { describe('when setting up for a company', () => {
beforeEach(() => { beforeEach(() => {
...@@ -355,16 +331,12 @@ describe('Subscription Details', () => { ...@@ -355,16 +331,12 @@ describe('Subscription Details', () => {
}); });
describe('Showing summary', () => { describe('Showing summary', () => {
let store;
beforeEach(() => { beforeEach(() => {
const mockApollo = createMockApolloProvider(STEPS, 1);
store = createStore(defaultInitialStoreData);
store.commit(types.UPDATE_IS_SETUP_FOR_COMPANY, true); store.commit(types.UPDATE_IS_SETUP_FOR_COMPANY, true);
store.commit(types.UPDATE_SELECTED_PLAN, 'firstPlanId'); store.commit(types.UPDATE_SELECTED_PLAN, 'firstPlanId');
store.commit(types.UPDATE_ORGANIZATION_NAME, 'My Organization'); store.commit(types.UPDATE_ORGANIZATION_NAME, 'My Organization');
store.commit(types.UPDATE_NUMBER_OF_USERS, 25); store.commit(types.UPDATE_NUMBER_OF_USERS, 25);
wrapper = createComponent({ apolloProvider: mockApollo, store }); store.commit(types.UPDATE_CURRENT_STEP, 'nextStep');
}); });
it('should show the selected plan', () => { it('should show the selected plan', () => {
......
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import Api from 'ee/api'; import Api from 'ee/api';
import * as constants from 'ee/subscriptions/new/constants'; import * as constants from 'ee/subscriptions/new/constants';
import defaultClient from 'ee/subscriptions/new/graphql';
import * as actions from 'ee/subscriptions/new/store/actions'; import * as actions from 'ee/subscriptions/new/store/actions';
import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/activate_next_step.mutation.graphql';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper'; import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import testAction from 'helpers/vuex_action_helper'; import testAction from 'helpers/vuex_action_helper';
import createFlash from '~/flash'; import createFlash from '~/flash';
...@@ -18,18 +16,53 @@ const { ...@@ -18,18 +16,53 @@ const {
} = Api; } = Api;
jest.mock('~/flash'); jest.mock('~/flash');
jest.mock('ee/subscriptions/new/constants', () => ({
STEPS: ['firstStep', 'secondStep'],
}));
describe('Subscriptions Actions', () => { describe('Subscriptions Actions', () => {
let mock; let mock;
beforeEach(() => { beforeEach(() => {
mock = new MockAdapter(axios); mock = new MockAdapter(axios);
defaultClient.mutate = jest.fn();
}); });
afterEach(() => { afterEach(() => {
mock.restore(); mock.restore();
defaultClient.mutate.mockClear(); });
describe('activateStep', () => {
it('set the currentStep to the provided value', (done) => {
testAction(
actions.activateStep,
'secondStep',
{},
[{ type: 'UPDATE_CURRENT_STEP', payload: 'secondStep' }],
[],
done,
);
});
it('does not change the currentStep if provided value is not available', (done) => {
testAction(actions.activateStep, 'thirdStep', {}, [], [], done);
});
});
describe('activateNextStep', () => {
it('set the currentStep to the next step in the available steps', (done) => {
testAction(
actions.activateNextStep,
{},
{ currentStepIndex: 0 },
[{ type: 'UPDATE_CURRENT_STEP', payload: 'secondStep' }],
[],
done,
);
});
it('does not change the currentStep if the current step is the last step', (done) => {
testAction(actions.activateNextStep, {}, { currentStepIndex: 1 }, [], [], done);
});
}); });
describe('updateSelectedPlan', () => { describe('updateSelectedPlan', () => {
...@@ -520,7 +553,7 @@ describe('Subscriptions Actions', () => { ...@@ -520,7 +553,7 @@ describe('Subscriptions Actions', () => {
}); });
describe('fetchPaymentMethodDetailsSuccess', () => { describe('fetchPaymentMethodDetailsSuccess', () => {
it('updates creditCardDetails to the provided data and calls defaultClient with activateNextStepMutation', (done) => { it('updates creditCardDetails to the provided data and calls activateNextStep', (done) => {
testAction( testAction(
actions.fetchPaymentMethodDetailsSuccess, actions.fetchPaymentMethodDetailsSuccess,
{ {
...@@ -541,13 +574,8 @@ describe('Subscriptions Actions', () => { ...@@ -541,13 +574,8 @@ describe('Subscriptions Actions', () => {
}, },
}, },
], ],
[], [{ type: 'activateNextStep' }],
() => { done,
expect(defaultClient.mutate).toHaveBeenCalledWith({
mutation: activateNextStepMutation,
});
done();
},
); );
}); });
}); });
......
import * as constants from 'ee/subscriptions/new/constants'; import * as constants from 'ee/subscriptions/new/constants';
import * as getters from 'ee/subscriptions/new/store/getters'; import * as getters from 'ee/subscriptions/new/store/getters';
constants.STEPS = ['firstStep', 'secondStep'];
const state = { const state = {
currentStep: 'secondStep',
isSetupForCompany: true, isSetupForCompany: true,
isNewUser: true, isNewUser: true,
availablePlans: [ availablePlans: [
...@@ -23,6 +26,35 @@ const state = { ...@@ -23,6 +26,35 @@ const state = {
}; };
describe('Subscriptions Getters', () => { describe('Subscriptions Getters', () => {
describe('currentStep', () => {
it('returns the states currentStep', () => {
expect(getters.currentStep(state)).toBe('secondStep');
});
});
describe('stepIndex', () => {
it('returns a function', () => {
expect(getters.stepIndex()).toBeInstanceOf(Function);
});
it('returns a function that returns the index of the given step', () => {
expect(getters.stepIndex()('secondStep')).toBe(1);
});
});
describe('currentStepIndex', () => {
it('returns a function', () => {
expect(getters.currentStepIndex(state, getters)).toBeInstanceOf(Function);
});
it('calls the stepIndex function with the current step name', () => {
const stepIndexSpy = jest.spyOn(getters, 'stepIndex');
getters.currentStepIndex(state, getters);
expect(stepIndexSpy).toHaveBeenCalledWith('secondStep');
});
});
describe('selectedPlanText', () => { describe('selectedPlanText', () => {
it('returns the text for selectedPlan', () => { it('returns the text for selectedPlan', () => {
expect( expect(
......
...@@ -2,6 +2,7 @@ import * as types from 'ee/subscriptions/new/store/mutation_types'; ...@@ -2,6 +2,7 @@ import * as types from 'ee/subscriptions/new/store/mutation_types';
import mutations from 'ee/subscriptions/new/store/mutations'; import mutations from 'ee/subscriptions/new/store/mutations';
const state = () => ({ const state = () => ({
currentStep: 'firstStep',
selectedPlan: 'firstPlan', selectedPlan: 'firstPlan',
isSetupForCompany: true, isSetupForCompany: true,
numberOfUsers: 1, numberOfUsers: 1,
...@@ -21,6 +22,7 @@ beforeEach(() => { ...@@ -21,6 +22,7 @@ beforeEach(() => {
describe('ee/subscriptions/new/store/mutation', () => { describe('ee/subscriptions/new/store/mutation', () => {
describe.each` describe.each`
mutation | value | stateProp mutation | value | stateProp
${types.UPDATE_CURRENT_STEP} | ${'secondStep'} | ${'currentStep'}
${types.UPDATE_SELECTED_PLAN} | ${'secondPlan'} | ${'selectedPlan'} ${types.UPDATE_SELECTED_PLAN} | ${'secondPlan'} | ${'selectedPlan'}
${types.UPDATE_SELECTED_GROUP} | ${'selectedGroup'} | ${'selectedGroup'} ${types.UPDATE_SELECTED_GROUP} | ${'selectedGroup'} | ${'selectedGroup'}
${types.UPDATE_IS_SETUP_FOR_COMPANY} | ${false} | ${'isSetupForCompany'} ${types.UPDATE_IS_SETUP_FOR_COMPANY} | ${false} | ${'isSetupForCompany'}
......
import * as constants from 'ee/subscriptions/new/constants'; import * as constants from 'ee/subscriptions/new/constants';
import createState from 'ee/subscriptions/new/store/state'; import createState from 'ee/subscriptions/new/store/state';
constants.STEPS = ['firstStep', 'secondStep'];
constants.TAX_RATE = 0; constants.TAX_RATE = 0;
describe('projectsSelector default state', () => { describe('projectsSelector default state', () => {
...@@ -30,6 +31,10 @@ describe('projectsSelector default state', () => { ...@@ -30,6 +31,10 @@ describe('projectsSelector default state', () => {
const state = createState(initialData); const state = createState(initialData);
it('sets the currentStep to the first item of the STEPS constant', () => {
expect(state.currentStep).toEqual('firstStep');
});
describe('availablePlans', () => { describe('availablePlans', () => {
it('sets the availablePlans to the provided parsed availablePlans', () => { it('sets the availablePlans to the provided parsed availablePlans', () => {
expect(state.availablePlans).toEqual([ expect(state.availablePlans).toEqual([
......
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 resolvers from 'ee/vue_shared/purchase_flow/graphql/resolvers';
import createMockApollo from 'helpers/mock_apollo_helper';
export function createMockApolloProvider(stepList, initialStepIndex = 0) {
const mockApollo = createMockApollo([], resolvers);
mockApollo.clients.defaultClient.cache.writeQuery({
query: stepListQuery,
data: { stepList },
});
mockApollo.clients.defaultClient.cache.writeQuery({
query: activeStepQuery,
data: { activeStep: stepList[initialStepIndex] },
});
return mockApollo;
}
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