Commit 11b002b9 authored by Nicolò Maria Mezzopera's avatar Nicolò Maria Mezzopera

Merge branch 'ag/341564-use-account-id-for-iframe-FE' into 'master'

Use account id as part of the namespace to init Zuora iframe

See merge request gitlab-org/gitlab!71735
parents 9be3299a 75f1f22a
<script>
import { GlIcon, GlCollapse, GlCollapseToggleDirective } from '@gitlab/ui';
import find from 'lodash/find';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
import { TAX_RATE } from 'ee/subscriptions/new/constants';
import formattingMixins from 'ee/subscriptions/new/formatting_mixins';
......@@ -35,25 +36,23 @@ export default {
query: stateQuery,
manual: true,
result({ data }) {
this.namespaces = data.namespaces;
const id = Number(data.selectedNamespaceId);
this.selectedNamespace = find(data.eligibleNamespaces, { id });
this.subscription = data.subscription;
},
},
},
data() {
return {
subscription: {},
namespaces: [],
isBottomSummaryVisible: false,
selectedNamespace: {},
subscription: {},
};
},
computed: {
selectedPlanPrice() {
return this.plan.pricePerYear;
},
selectedGroup() {
return this.namespaces.find((group) => group.id === Number(this.subscription.namespaceId));
},
totalExVat() {
return this.subscription.quantity * this.selectedPlanPrice;
},
......@@ -67,7 +66,7 @@ export default {
return this.subscription.quantity > 0;
},
namespaceName() {
return this.selectedGroup.name;
return this.selectedNamespace.name;
},
titleWithName() {
return sprintf(this.title, { name: this.namespaceName });
......
......@@ -6,7 +6,7 @@ export const planTags = {
STORAGE_PLAN: 'STORAGE_PLAN',
};
/* eslint-enable @gitlab/require-i18n-strings */
export const CUSTOMER_CLIENT = 'customerClient';
export const CUSTOMERSDOT_CLIENT = 'customersDotClient';
export const GITLAB_CLIENT = 'gitlabClient';
export const CI_MINUTES_PER_PACK = 1000;
......
......@@ -4,7 +4,7 @@ import VueApollo from 'vue-apollo';
import purchaseFlowResolvers from 'ee/vue_shared/purchase_flow/graphql/resolvers';
import typeDefs from 'ee/vue_shared/purchase_flow/graphql/typedefs.graphql';
import createClient from '~/lib/graphql';
import { GITLAB_CLIENT, CUSTOMER_CLIENT } from './constants';
import { GITLAB_CLIENT, CUSTOMERSDOT_CLIENT } from './constants';
import { resolvers } from './graphql/resolvers';
Vue.use(VueApollo);
......@@ -13,7 +13,7 @@ const gitlabClient = createClient(merge({}, resolvers, purchaseFlowResolvers), {
typeDefs,
assumeImmutableResults: true,
});
const customerClient = createClient(
const customersDotClient = createClient(
{},
{
path: '/-/customers_dot/proxy/graphql',
......@@ -26,6 +26,6 @@ export default new VueApollo({
defaultClient: gitlabClient,
clients: {
[GITLAB_CLIENT]: gitlabClient,
[CUSTOMER_CLIENT]: customerClient,
[CUSTOMERSDOT_CLIENT]: customersDotClient,
},
});
......@@ -39,11 +39,9 @@ export const resolvers = {
},
updateState: (_, { input }, { cache }) => {
const oldState = cache.readQuery({ query: stateQuery });
const state = produce(oldState, (draftState) => {
merge(draftState, input);
});
cache.writeQuery({ query: stateQuery, data: state });
},
},
......
......@@ -12,8 +12,9 @@ function arrayToGraphqlArray(arr, typename) {
export function writeInitialDataToApolloCache(apolloProvider, dataset) {
const { groupData, namespaceId, redirectAfterSuccess, subscriptionQuantity } = dataset;
// eslint-disable-next-line @gitlab/require-i18n-strings
const namespaces = arrayToGraphqlArray(JSON.parse(groupData), 'Namespace');
const eligibleNamespaces = arrayToGraphqlArray(JSON.parse(groupData), 'Namespace');
const quantity = subscriptionQuantity || 1;
apolloProvider.clients.defaultClient.cache.writeQuery({
......@@ -23,11 +24,11 @@ export function writeInitialDataToApolloCache(apolloProvider, dataset) {
fullName: null,
isSetupForCompany: false,
selectedPlanId: null,
namespaces,
eligibleNamespaces,
redirectAfterSuccess,
selectedNamespaceId: namespaceId,
subscription: {
quantity,
namespaceId,
// eslint-disable-next-line @gitlab/require-i18n-strings
__typename: 'Subscription',
},
......
......@@ -20,14 +20,13 @@ import {
I18N_CI_MINUTES_PRICE_PRE_UNIT,
I18N_CI_MINUTES_TITLE,
planTags,
CUSTOMER_CLIENT,
CUSTOMERSDOT_CLIENT,
CI_MINUTES_PER_PACK,
} from '../../buy_addons_shared/constants';
import plansQuery from '../../graphql/queries/plans.customer.query.graphql';
export default {
name: 'BuyCIMinutesApp',
components: {
Checkout,
GlEmptyState,
......@@ -93,7 +92,7 @@ export default {
},
apollo: {
plans: {
client: CUSTOMER_CLIENT,
client: CUSTOMERSDOT_CLIENT,
query: plansQuery,
variables: {
tags: [planTags.CI_1000_MINUTES_PLAN],
......
......@@ -17,6 +17,7 @@ export default (el) => {
return new Vue({
el,
name: 'BuyCIMinutes',
apolloProvider,
render(createElement) {
return createElement(extendedApp);
......
......@@ -20,7 +20,7 @@ import {
I18N_STORAGE_PRICE_PRE_UNIT,
I18N_STORAGE_TOOLTIP_NOTE,
planTags,
CUSTOMER_CLIENT,
CUSTOMERSDOT_CLIENT,
STORAGE_PER_PACK,
} from '../../buy_addons_shared/constants';
import plansQuery from '../../graphql/queries/plans.customer.query.graphql';
......@@ -94,7 +94,7 @@ export default {
},
apollo: {
plans: {
client: CUSTOMER_CLIENT,
client: CUSTOMERSDOT_CLIENT,
query: plansQuery,
variables: {
tags: [planTags.STORAGE_PLAN],
......
query State {
namespaces @client {
eligibleNamespaces @client {
id
accountId
name
users
}
......@@ -8,6 +9,7 @@ query State {
fullName @client
isSetupForCompany @client
selectedPlanId @client
selectedNamespaceId @client
redirectAfterSuccess @client
customer @client {
country
......@@ -27,7 +29,6 @@ query State {
}
subscription @client {
quantity
namespaceId
}
activeStep @client {
id
......
<script>
import { GlSprintf } from '@gitlab/ui';
import find from 'lodash/find';
import { STEPS } from 'ee/subscriptions/constants';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
......@@ -17,8 +18,18 @@ export default {
query: stateQuery,
update: (data) => data.paymentMethod,
},
selectedNamespace: {
query: stateQuery,
update: ({ eligibleNamespaces, selectedNamespaceId }) => {
const id = Number(selectedNamespaceId);
return find(eligibleNamespaces, { id });
},
},
},
computed: {
accountId() {
return this.selectedNamespace?.accountId || '';
},
isValid() {
return Boolean(this.paymentMethod.id);
},
......@@ -40,10 +51,10 @@ export default {
<template>
<step :step-id="$options.stepId" :title="$options.i18n.stepTitle" :is-valid="isValid">
<template #body="{ active }">
<zuora :active="active" />
<zuora :active="active" :account-id="accountId" />
</template>
<template #summary>
<div class="js-summary-line-1">
<div data-testid="card-details">
<gl-sprintf :message="$options.i18n.paymentMethod">
<template #cardType>
{{ paymentMethod.creditCardType }}
......@@ -53,7 +64,7 @@ export default {
</template>
</gl-sprintf>
</div>
<div class="js-summary-line-2">
<div data-testid="card-expiration">
{{ expirationDate }}
</div>
</template>
......
......@@ -23,11 +23,16 @@ export default {
type: Boolean,
required: true,
},
accountId: {
type: String,
required: false,
default: '',
},
},
data() {
return {
isLoading: false,
paymentFormParams: null,
paymentFormParams: {},
zuoraLoaded: false,
zuoraScriptEl: null,
};
......@@ -36,6 +41,14 @@ export default {
shouldShowZuoraFrame() {
return this.active && this.zuoraLoaded && !this.isLoading;
},
renderParams() {
return {
...this.paymentFormParams,
...ZUORA_IFRAME_OVERRIDE_PARAMS,
// @TODO: should the component handle re-rendering the form in case this changes?
field_accountId: this.accountId,
};
},
},
mounted() {
this.loadZuoraScript();
......@@ -94,9 +107,8 @@ export default {
});
},
renderZuoraIframe() {
const params = { ...this.paymentFormParams, ...ZUORA_IFRAME_OVERRIDE_PARAMS };
window.Z.runAfterRender(this.zuoraIframeRendered);
window.Z.render(params, {}, this.paymentFormSubmitted);
window.Z.render(this.renderParams, {}, this.paymentFormSubmitted);
},
activateNextStep() {
return this.$apollo
......
......@@ -60,6 +60,7 @@ module SubscriptionsHelper
def present_group(namespace)
{
id: namespace.id,
account_id: nil,
name: namespace.name,
users: namespace.member_count,
guests: namespace.guest_count
......
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { createLocalVue } from '@vue/test-utils';
import { merge } from 'lodash';
import VueApollo from 'vue-apollo';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import OrderSummary from 'ee/subscriptions/buy_addons_shared/components/order_summary.vue';
import subscriptionsResolvers from 'ee/subscriptions/buy_addons_shared/graphql/resolvers';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
......@@ -17,32 +18,30 @@ localVue.use(VueApollo);
describe('Order Summary', () => {
const resolvers = { ...purchaseFlowResolvers, ...subscriptionsResolvers };
const selectedNamespaceId = mockParsedNamespaces[0].id;
const initialStateData = {
selectedPlanId: 'ciMinutesPackPlanId',
namespaces: [mockParsedNamespaces[0]],
subscription: {
namespaceId: mockParsedNamespaces[0].id,
},
eligibleNamespaces: mockParsedNamespaces,
selectedNamespaceId,
subscription: {},
};
let wrapper;
const findAmount = () => wrapper.findByTestId('amount');
const findTitle = () => wrapper.findByTestId('title');
const createMockApolloProvider = (stateData = {}) => {
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 = shallowMount(OrderSummary, {
wrapper = shallowMountExtended(OrderSummary, {
localVue,
apolloProvider,
propsData: {
......@@ -65,9 +64,7 @@ describe('Order Summary', () => {
});
it('displays the title', () => {
expect(wrapper.find('[data-testid="title"]').text()).toMatchInterpolatedText(
"Gitlab Org's CI minutes",
);
expect(findTitle().text()).toMatchInterpolatedText("Gitlab Org's CI minutes");
});
});
......@@ -79,7 +76,7 @@ describe('Order Summary', () => {
});
it('renders amount', () => {
expect(wrapper.find('[data-testid="amount"]').text()).toBe('$30');
expect(findAmount().text()).toBe('$30');
});
});
......@@ -91,7 +88,7 @@ describe('Order Summary', () => {
});
it('does not render amount', () => {
expect(wrapper.find('[data-testid="amount"]').text()).toBe('-');
expect(findAmount().text()).toBe('-');
});
});
});
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 './mock_data';
import { mockNamespaces, mockParsedNamespaces } from '../buy_minutes/mock_data';
const DEFAULT_DATA = {
groupData: mockNamespaces,
......@@ -26,7 +26,7 @@ describe('utils', () => {
${''} | ${{}} | ${true}
${mockNamespaces} | ${mockParsedNamespaces} | ${false}
`('parameter decoding', ({ namespaces, parsedNamespaces, throws }) => {
it(`decodes ${namespaces} to ${parsedNamespaces}`, async () => {
it(`decodes $namespaces to $parsedNamespaces`, async () => {
if (throws) {
expect(() => {
writeInitialDataToApolloCache(apolloProvider, { groupData: namespaces });
......@@ -39,7 +39,7 @@ describe('utils', () => {
const sourceData = await apolloProvider.clients.defaultClient.query({
query: stateQuery,
});
expect(sourceData.data.namespaces).toStrictEqual(parsedNamespaces);
expect(sourceData.data.eligibleNamespaces).toStrictEqual(parsedNamespaces);
}
});
});
......
......@@ -61,7 +61,7 @@ describe('Billing Address', () => {
});
describe('validations', () => {
const isStepValid = () => wrapper.find(Step).props('isValid');
const isStepValid = () => wrapper.findComponent(Step).props('isValid');
const customerData = {
country: 'US',
address1: 'address line 1',
......
......@@ -11,20 +11,19 @@ import { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import flash from '~/flash';
import * as UrlUtility from '~/lib/utils/url_utility';
import flushPromises from 'helpers/flush_promises';
jest.mock('~/lib/utils/url_utility');
jest.mock('~/flash');
jest.mock('ee/api.js');
const flushPromises = () => new Promise(setImmediate);
describe('Confirm Order', () => {
let mockApolloProvider;
let wrapper;
const findRootElement = () => wrapper.findByTestId('confirm-order-root');
const findConfirmButton = () => wrapper.find(GlButton);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
const findConfirmButton = () => wrapper.findComponent(GlButton);
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const localVue = createLocalVue();
localVue.use(VueApollo);
......@@ -77,7 +76,7 @@ describe('Confirm Order', () => {
expect(Api.confirmOrder).toHaveBeenCalledTimes(1);
expect(Api.confirmOrder.mock.calls[0][0]).toMatchObject({
setup_for_company: true,
selected_group: null,
selected_group: undefined,
new_user: false,
redirect_after_success: '/path/to/redirect/',
customer: {
......
import { STEPS } from 'ee/subscriptions/constants';
export const accountId = '111111111111';
export const mockCiMinutesPlans = [
{
id: 'ciMinutesPackPlanId',
......@@ -9,16 +11,18 @@ export const mockCiMinutesPlans = [
__typename: 'Plan',
},
];
export const mockNamespaces =
'[{"id":132,"name":"Gitlab Org","users":3},{"id":483,"name":"Gnuwget","users":12}]';
export const mockParsedNamespaces = [
{ __typename: 'Namespace', id: 132, name: 'Gitlab Org', users: 3 },
{ __typename: 'Namespace', id: 483, name: 'Gnuwget', users: 12 },
];
export const mockNamespaces = `
[{"id":132,"accountId":"${accountId}","name":"Gitlab Org","users":3},
{"id":483,"accountId":null,"name":"Gnuwget","users":12}]
`;
export const mockParsedNamespaces = JSON.parse(mockNamespaces).map((namespace) => ({
...namespace,
__typename: 'Namespace',
}));
export const mockNewUser = 'false';
export const mockFullName = 'John Admin';
export const mockSetupForCompany = 'true';
export const mockDefaultCache = {
......@@ -28,13 +32,13 @@ export const mockDefaultCache = {
};
export const stateData = {
namespaces: [],
eligibleNamespaces: [],
subscription: {
quantity: 1,
namespaceId: null,
__typename: 'Subscription',
},
redirectAfterSuccess: '/path/to/redirect/',
selectedNamespaceId: null,
selectedPlanId: null,
paymentMethod: {
id: null,
......
......@@ -2,6 +2,7 @@ import VueApollo from 'vue-apollo';
import { writeInitialDataToApolloCache } from 'ee/subscriptions/buy_addons_shared/utils';
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';
export function createMockApolloProvider(mockResponses = {}, dataset = {}) {
......@@ -12,11 +13,11 @@ export function createMockApolloProvider(mockResponses = {}, dataset = {}) {
const { quantity } = dataset;
const mockDefaultClient = createMockClient();
const mockCustomerClient = createMockClient([[plansQuery, plansQueryMock]]);
const mockCustomersDotClient = createMockClient([[plansQuery, plansQueryMock]]);
const apolloProvider = new VueApollo({
defaultClient: mockDefaultClient,
clients: { customerClient: mockCustomerClient },
clients: { [CUSTOMERSDOT_CLIENT]: mockCustomersDotClient },
});
writeInitialDataToApolloCache(apolloProvider, {
......
......@@ -85,7 +85,7 @@ describe('Billing Address', () => {
});
describe('validations', () => {
const isStepValid = () => wrapper.find(Step).props('isValid');
const isStepValid = () => wrapper.findComponent(Step).props('isValid');
beforeEach(() => {
store.commit(types.UPDATE_COUNTRY, 'country');
......
......@@ -31,8 +31,8 @@ describe('Confirm Order', () => {
});
}
const findConfirmButton = () => wrapper.find(GlButton);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
const findConfirmButton = () => wrapper.findComponent(GlButton);
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
afterEach(() => {
wrapper.destroy();
......
......@@ -44,7 +44,7 @@ describe('Payment Method', () => {
});
describe('validations', () => {
const isStepValid = () => wrapper.find(Step).props('isValid');
const isStepValid = () => wrapper.findComponent(Step).props('isValid');
it('should be valid when paymentMethodId is defined', () => {
expect(isStepValid()).toBe(true);
......
......@@ -263,7 +263,7 @@ describe('Subscription Details', () => {
});
describe('validations', () => {
const isStepValid = () => wrapper.find(Step).props('isValid');
const isStepValid = () => wrapper.findComponent(Step).props('isValid');
let store;
beforeEach(() => {
......
......@@ -39,7 +39,7 @@ describe('Zuora', () => {
});
};
const findLoading = () => wrapper.find(GlLoadingIcon);
const findLoading = () => wrapper.findComponent(GlLoadingIcon);
const findZuoraPayment = () => wrapper.find('#zuora_payment');
beforeEach(() => {
......
......@@ -17,7 +17,7 @@ describe('Checkout', () => {
});
};
const findProgressBar = () => wrapper.find(ProgressBar);
const findProgressBar = () => wrapper.findComponent(ProgressBar);
beforeEach(() => {
store = createStore();
......
import { mount, createLocalVue } from '@vue/test-utils';
import { createLocalVue } from '@vue/test-utils';
import { merge } from 'lodash';
import VueApollo from 'vue-apollo';
import { resolvers } from 'ee/subscriptions/buy_addons_shared/graphql/resolvers';
......@@ -6,8 +6,13 @@ 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 { stateData as initialStateData } from 'ee_jest/subscriptions/buy_minutes/mock_data';
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';
const localVue = createLocalVue();
localVue.use(VueApollo);
......@@ -15,6 +20,12 @@ localVue.use(VueApollo);
describe('Payment Method', () => {
let wrapper;
const findCCDetails = () => wrapper.findByTestId('card-details');
const findCCExpiration = () => wrapper.findByTestId('card-expiration');
const findZuora = () => wrapper.findComponent(Zuora);
const isStepValid = () => wrapper.findComponent(Step).props('isValid');
const createComponent = (apolloLocalState = {}) => {
const apolloProvider = createMockApolloProvider(STEPS, STEPS[2], {
...resolvers,
......@@ -24,7 +35,7 @@ describe('Payment Method', () => {
data: merge({}, initialStateData, apolloLocalState),
});
return mount(PaymentMethod, {
return mountExtended(PaymentMethod, {
localVue,
apolloProvider,
});
......@@ -46,14 +57,12 @@ describe('Payment Method', () => {
wrapper.destroy();
});
describe('validations', () => {
const isStepValid = () => wrapper.find(Step).props('isValid');
it('should be valid when paymentMethodId is defined', () => {
describe('payment method step', () => {
it('is valid when paymentMethodId is defined', () => {
expect(isStepValid()).toBe(true);
});
it('should be invalid when paymentMethodId is undefined', () => {
it('is invalid when paymentMethodId is undefined', () => {
wrapper = createComponent({
paymentMethod: { id: null },
});
......@@ -62,15 +71,50 @@ describe('Payment Method', () => {
});
});
describe('showing the summary', () => {
it('should show the entered credit card details', () => {
expect(wrapper.find('.js-summary-line-1').text()).toMatchInterpolatedText(
'Visa ending in 4242',
);
describe('summary', () => {
it('shows the entered credit card details', () => {
expect(findCCDetails().text()).toMatchInterpolatedText('Visa ending in 4242');
});
it('shows the entered credit card expiration date', () => {
expect(findCCExpiration().text()).toBe('Exp 12/09');
});
});
describe('Zuora Component', () => {
const eligibleNamespaces = mockParsedNamespaces;
const active = true;
const activeStep = STEPS[2];
describe('when the selected namespace exists', () => {
describe('when it has an account id', () => {
it('has the selected account id', () => {
const { accountId, id } = mockParsedNamespaces[0];
const selectedNamespaceId = `${id}`;
wrapper = createComponent({ eligibleNamespaces, selectedNamespaceId, activeStep });
expect(findZuora().props()).toMatchObject({ active, accountId });
});
});
describe('when it has no account id', () => {
it('has the default account id', () => {
const { id } = mockParsedNamespaces[1];
const selectedNamespaceId = `${id}`;
wrapper = createComponent({ eligibleNamespaces, selectedNamespaceId, activeStep });
expect(findZuora().props()).toMatchObject({ active, accountId: '' });
});
});
});
it('should show the entered credit card expiration date', () => {
expect(wrapper.find('.js-summary-line-2').text()).toBe('Exp 12/09');
describe('when the selected namespace does not exists', () => {
it('has the default account id', () => {
const selectedNamespaceId = `000`;
wrapper = createComponent({ eligibleNamespaces, selectedNamespaceId, activeStep });
expect(findZuora().props()).toMatchObject({ active, accountId: '' });
});
});
});
});
......@@ -10,6 +10,7 @@ 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 { createMockApolloProvider } from 'ee_jest/vue_shared/purchase_flow/spec_helper';
import axios from '~/lib/utils/axios_utils';
import flushPromises from 'helpers/flush_promises';
const localVue = createLocalVue();
localVue.use(VueApollo);
......@@ -39,7 +40,7 @@ describe('Zuora', () => {
});
};
const findLoading = () => wrapper.find(GlLoadingIcon);
const findLoading = () => wrapper.findComponent(GlLoadingIcon);
const findZuoraPayment = () => wrapper.find('#zuora_payment');
beforeEach(() => {
......@@ -47,7 +48,7 @@ describe('Zuora', () => {
runAfterRender(fn) {
return Promise.resolve().then(fn);
},
render() {},
render: jest.fn(),
};
axiosMock = new AxiosMockAdapter(axios);
......@@ -97,4 +98,25 @@ describe('Zuora', () => {
expect(findZuoraPayment().isVisible()).toBe(false);
});
});
describe.each(['', '111111'])('when rendering the iframe with account id: %s', (id) => {
beforeEach(() => {
wrapper = createComponent({ accountId: id }, { isLoading: false });
wrapper.vm.zuoraScriptEl.onload();
return flushPromises();
});
it(`calls render with ${id}`, () => {
expect(window.Z.render).toHaveBeenCalledWith(
{
field_accountId: id,
retainValues: 'true',
style: 'inline',
submitEnabled: 'true',
},
{},
expect.any(Function),
);
});
});
});
......@@ -171,14 +171,14 @@ describe('Step', () => {
const mockApollo = createMockApolloProvider(STEPS, 1);
wrapper = createComponent({ apolloProvider: mockApollo });
expect(wrapper.find(GlButton).attributes('disabled')).toBeUndefined();
expect(wrapper.findComponent(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');
wrapper.findComponent(GlButton).vm.$emit('click');
await waitForPromises();
expect(flash.mock.calls).toHaveLength(1);
......
......@@ -51,7 +51,7 @@ RSpec.describe SubscriptionsHelper do
it { is_expected.to include(plan_id: 'bronze_id') }
it { is_expected.to include(namespace_id: group.id.to_s) }
it { is_expected.to include(source: 'some_source') }
it { is_expected.to include(group_data: %Q{[{"id":#{group.id},"name":"My Namespace","users":2,"guests":1}]}) }
it { is_expected.to include(group_data: %Q{[{"id":#{group.id},"account_id":null,"name":"My Namespace","users":2,"guests":1}]}) }
describe 'new_user' do
where(:referer, :expected_result) do
......@@ -150,7 +150,7 @@ RSpec.describe SubscriptionsHelper do
it { is_expected.to include(namespace_id: group.id.to_s) }
it { is_expected.to include(source: 'some_source') }
it { is_expected.to include(group_data: %Q{[{"id":#{group.id},"name":"My Namespace","users":1,"guests":0}]}) }
it { is_expected.to include(group_data: %Q{[{"id":#{group.id},"account_id":null,"name":"My Namespace","users":1,"guests":0}]}) }
it { is_expected.to include(redirect_after_success: group_usage_quotas_path(group, anchor: anchor, purchased_product: purchased_product)) }
end
end
export default function flushPromises() {
return new Promise(setImmediate);
}
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