Commit 83b9b5c9 authored by Vitaly Slobodin's avatar Vitaly Slobodin Committed by Nicolò Maria Mezzopera

Add CC validation modal to new pipeline page [RUN ALL RSPEC] [RUN AS-IF-FOSS]

parent ded4a188
......@@ -21,7 +21,12 @@ import { backOff } from '~/lib/utils/common_utils';
import httpStatusCodes from '~/lib/utils/http_status';
import { redirectTo } from '~/lib/utils/url_utility';
import { s__, __, n__ } from '~/locale';
import { VARIABLE_TYPE, FILE_TYPE, CONFIG_VARIABLES_TIMEOUT } from '../constants';
import {
VARIABLE_TYPE,
FILE_TYPE,
CONFIG_VARIABLES_TIMEOUT,
CC_VALIDATION_REQUIRED_ERROR,
} from '../constants';
import filterVariables from '../utils/filter_variables';
import RefsDropdown from './refs_dropdown.vue';
......@@ -60,6 +65,8 @@ export default {
GlSprintf,
GlLoadingIcon,
RefsDropdown,
CcValidationRequiredAlert: () =>
import('ee_component/billings/components/cc_validation_required_alert.vue'),
},
directives: { SafeHtml },
props: {
......@@ -143,6 +150,9 @@ export default {
descriptions() {
return this.form[this.refFullName]?.descriptions ?? {};
},
ccRequiredError() {
return this.error === CC_VALIDATION_REQUIRED_ERROR;
},
},
watch: {
refValue() {
......@@ -329,8 +339,9 @@ export default {
<template>
<gl-form @submit.prevent="createPipeline">
<cc-validation-required-alert v-if="ccRequiredError" class="gl-pb-5" />
<gl-alert
v-if="error"
v-else-if="error"
:title="errorTitle"
:dismissible="false"
variant="danger"
......
......@@ -4,3 +4,6 @@ export const DEBOUNCE_REFS_SEARCH_MS = 250;
export const CONFIG_VARIABLES_TIMEOUT = 5000;
export const BRANCH_REF_TYPE = 'branch';
export const TAG_REF_TYPE = 'tag';
export const CC_VALIDATION_REQUIRED_ERROR =
'Credit card required to be on file in order to create a pipeline';
<script>
import { GlAlert, GlLoadingIcon, GlModal, GlSprintf } from '@gitlab/ui';
import { objectToQuery } from '~/lib/utils/url_utility';
import { s__, __ } from '~/locale';
const IFRAME_QUERY = 'enable_submit=false&pp=disable';
const IFRAME_QUERY = Object.freeze({
enable_submit: false,
user_id: null,
});
// 450 is the mininum required height to get all iframe inputs visible
const IFRAME_MINIMUM_HEIGHT = 450;
const i18n = Object.freeze({
......@@ -44,7 +48,9 @@ export default {
},
computed: {
iframeSrc() {
return `${this.iframeUrl}?${IFRAME_QUERY}`;
const query = { ...IFRAME_QUERY, user_id: gon.current_user_id };
return `${this.iframeUrl}?${objectToQuery(query)}`;
},
iframeHeight() {
return IFRAME_MINIMUM_HEIGHT * window.devicePixelRatio;
......@@ -75,7 +81,14 @@ export default {
return;
}
this.error = event.data;
if (event.data.success) {
this.$emit('success');
} else {
this.error = event.data.msg;
this.$refs.zuora.src = this.iframeSrc;
this.$emit('error', this.error);
}
this.isLoading = false;
},
isEventAllowedForOrigin(event) {
......@@ -108,12 +121,12 @@ export default {
</gl-sprintf>
</p>
<gl-alert v-if="error" variant="danger">{{ error.msg }}</gl-alert>
<gl-alert v-if="error" variant="danger">{{ error }}</gl-alert>
<gl-loading-icon v-if="isLoading" size="lg" />
<!-- eslint-disable @gitlab/vue-require-i18n-strings -->
<iframe
v-show="!isLoading"
id="zuora"
ref="zuora"
:src="iframeSrc"
style="border: none"
width="100%"
......
......@@ -18,14 +18,12 @@ export default {
GlSprintf,
AccountVerificationModal,
},
props: {
iframeUrl: {
type: String,
required: true,
computed: {
iframeUrl() {
return gon.payment_form_url;
},
allowedOrigin: {
type: String,
required: true,
allowedOrigin() {
return gon.subscriptions_url;
},
},
methods: {
......@@ -38,7 +36,7 @@ export default {
</script>
<template>
<div class="gl-pt-5">
<div>
<gl-alert
variant="danger"
:dismissible="false"
......
import { GlAlert, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import CreditCardValidationRequiredAlert from 'ee/billings/components/cc_validation_required_alert.vue';
import { TEST_HOST } from 'helpers/test_constants';
describe('CreditCardValidationRequiredAlert', () => {
let wrapper;
const createComponent = () => {
return shallowMount(CreditCardValidationRequiredAlert, {
propsData: {
iframeUrl: 'about:blank',
allowedOrigin: 'about:blank',
},
stubs: {
GlSprintf,
},
......@@ -18,6 +15,11 @@ describe('CreditCardValidationRequiredAlert', () => {
};
beforeEach(() => {
window.gon = {
subscriptions_url: TEST_HOST,
payment_form_url: TEST_HOST,
};
wrapper = createComponent();
});
......
import { GlForm, GlSprintf, GlLoadingIcon } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import CreditCardValidationRequiredAlert from 'ee_component/billings/components/cc_validation_required_alert.vue';
import { TEST_HOST } from 'helpers/test_constants';
import waitForPromises from 'helpers/wait_for_promises';
import axios from '~/lib/utils/axios_utils';
import httpStatusCodes from '~/lib/utils/http_status';
import { redirectTo } from '~/lib/utils/url_utility';
import PipelineNewForm from '~/pipeline_new/components/pipeline_new_form.vue';
import RefsDropdown from '~/pipeline_new/components/refs_dropdown.vue';
import { mockQueryParams, mockPostParams, mockProjectId, mockError, mockRefs } from '../mock_data';
import {
mockQueryParams,
mockPostParams,
mockProjectId,
mockError,
mockRefs,
mockCreditCardValidationRequiredError,
} from '../mock_data';
jest.mock('~/lib/utils/url_utility', () => ({
redirectTo: jest.fn(),
......@@ -376,6 +385,32 @@ describe('Pipeline New Form', () => {
it('re-enables the submit button', () => {
expect(findSubmitButton().props('disabled')).toBe(false);
});
it('does not show the credit card validation required alert', () => {
expect(wrapper.findComponent(CreditCardValidationRequiredAlert).exists()).toBe(false);
});
describe('when the error response is credit card validation required', () => {
beforeEach(async () => {
mock
.onPost(pipelinesPath)
.reply(httpStatusCodes.BAD_REQUEST, mockCreditCardValidationRequiredError);
window.gon = {
subscriptions_url: TEST_HOST,
payment_form_url: TEST_HOST,
};
findForm().vm.$emit('submit', dummySubmitEvent);
await waitForPromises();
});
it('shows credit card validation required alert', () => {
expect(findErrorAlert().exists()).toBe(false);
expect(wrapper.findComponent(CreditCardValidationRequiredAlert).exists()).toBe(true);
});
});
});
describe('when the error response cannot be handled', () => {
......
......@@ -40,6 +40,12 @@ export const mockError = {
total_warnings: 7,
};
export const mockCreditCardValidationRequiredError = {
errors: ['Credit card required to be on file in order to create a pipeline'],
warnings: [],
total_warnings: 0,
};
export const mockBranchRefs = ['main', 'dev', 'release'];
export const mockTagRefs = ['1.0.0', '1.1.0', '1.2.0'];
......
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