Commit 2a036b35 authored by Tom Quirk's avatar Tom Quirk

Remove event hub from integrations app

This commit removes the event hub,
and refactors the integration form
to pass validated state down to child components
from parent.

No user facing changes are expected.
parent bbf52b48
import { s__, __ } from '~/locale'; import { s__, __ } from '~/locale';
export const VALIDATE_INTEGRATION_FORM_EVENT = 'validateIntegrationForm';
export const integrationLevels = { export const integrationLevels = {
GROUP: 'group', GROUP: 'group',
INSTANCE: 'instance', INSTANCE: 'instance',
......
...@@ -9,8 +9,6 @@ import { ...@@ -9,8 +9,6 @@ import {
} from '@gitlab/ui'; } from '@gitlab/ui';
import { capitalize, lowerCase, isEmpty } from 'lodash'; import { capitalize, lowerCase, isEmpty } from 'lodash';
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import { VALIDATE_INTEGRATION_FORM_EVENT } from '~/integrations/constants';
import eventHub from '../event_hub';
export default { export default {
name: 'DynamicField', name: 'DynamicField',
...@@ -70,11 +68,15 @@ export default { ...@@ -70,11 +68,15 @@ export default {
required: false, required: false,
default: null, default: null,
}, },
isValidated: {
type: Boolean,
required: false,
default: false,
},
}, },
data() { data() {
return { return {
model: this.value, model: this.value,
validated: false,
}; };
}, },
computed: { computed: {
...@@ -123,22 +125,13 @@ export default { ...@@ -123,22 +125,13 @@ export default {
}; };
}, },
valid() { valid() {
return !this.required || !isEmpty(this.model) || this.isNonEmptyPassword || !this.validated; return !this.required || !isEmpty(this.model) || this.isNonEmptyPassword || !this.isValidated;
}, },
}, },
created() { created() {
if (this.isNonEmptyPassword) { if (this.isNonEmptyPassword) {
this.model = null; this.model = null;
} }
eventHub.$on(VALIDATE_INTEGRATION_FORM_EVENT, this.validateForm);
},
beforeDestroy() {
eventHub.$off(VALIDATE_INTEGRATION_FORM_EVENT, this.validateForm);
},
methods: {
validateForm() {
this.validated = true;
},
}, },
helpHtmlConfig: { helpHtmlConfig: {
ADD_ATTR: ['target'], // allow external links, can be removed after https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1427 is implemented ADD_ATTR: ['target'], // allow external links, can be removed after https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1427 is implemented
......
...@@ -5,7 +5,6 @@ import * as Sentry from '@sentry/browser'; ...@@ -5,7 +5,6 @@ import * as Sentry from '@sentry/browser';
import { mapState, mapActions, mapGetters } from 'vuex'; import { mapState, mapActions, mapGetters } from 'vuex';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { import {
VALIDATE_INTEGRATION_FORM_EVENT,
I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE, I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE,
I18N_DEFAULT_ERROR_MESSAGE, I18N_DEFAULT_ERROR_MESSAGE,
I18N_SUCCESSFUL_CONNECTION_MESSAGE, I18N_SUCCESSFUL_CONNECTION_MESSAGE,
...@@ -14,7 +13,6 @@ import { ...@@ -14,7 +13,6 @@ import {
} from '~/integrations/constants'; } from '~/integrations/constants';
import { refreshCurrentPage } from '~/lib/utils/url_utility'; import { refreshCurrentPage } from '~/lib/utils/url_utility';
import csrf from '~/lib/utils/csrf'; import csrf from '~/lib/utils/csrf';
import eventHub from '../event_hub';
import { testIntegrationSettings } from '../api'; import { testIntegrationSettings } from '../api';
import ActiveCheckbox from './active_checkbox.vue'; import ActiveCheckbox from './active_checkbox.vue';
import ConfirmationModal from './confirmation_modal.vue'; import ConfirmationModal from './confirmation_modal.vue';
...@@ -57,6 +55,7 @@ export default { ...@@ -57,6 +55,7 @@ export default {
isTesting: false, isTesting: false,
isSaving: false, isSaving: false,
isResetting: false, isResetting: false,
isValidated: false,
}; };
}, },
computed: { computed: {
...@@ -107,13 +106,16 @@ export default { ...@@ -107,13 +106,16 @@ export default {
: document.querySelector(INTEGRATION_FORM_SELECTOR); : document.querySelector(INTEGRATION_FORM_SELECTOR);
}, },
methods: { methods: {
...mapActions(['setOverride', 'fetchResetIntegration', 'requestJiraIssueTypes']), ...mapActions(['setOverride', 'requestJiraIssueTypes']),
setIsValidated() {
this.isValidated = true;
},
onSaveClick() { onSaveClick() {
this.isSaving = true; this.isSaving = true;
if (this.integrationActive && !this.form.checkValidity()) { if (this.integrationActive && !this.form.checkValidity()) {
this.isSaving = false; this.isSaving = false;
eventHub.$emit(VALIDATE_INTEGRATION_FORM_EVENT); this.setIsValidated();
return; return;
} }
...@@ -123,14 +125,14 @@ export default { ...@@ -123,14 +125,14 @@ export default {
this.isTesting = true; this.isTesting = true;
if (!this.form.checkValidity()) { if (!this.form.checkValidity()) {
eventHub.$emit(VALIDATE_INTEGRATION_FORM_EVENT); this.setIsValidated();
return; return;
} }
testIntegrationSettings(this.propsSource.testPath, this.getFormData()) testIntegrationSettings(this.propsSource.testPath, this.getFormData())
.then(({ data: { error, message = I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE } }) => { .then(({ data: { error, message = I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE } }) => {
if (error) { if (error) {
eventHub.$emit(VALIDATE_INTEGRATION_FORM_EVENT); this.setIsValidated();
this.$toast.show(message); this.$toast.show(message);
return; return;
} }
...@@ -227,6 +229,7 @@ export default { ...@@ -227,6 +229,7 @@ export default {
v-if="isJira" v-if="isJira"
:key="`${currentKey}-jira-trigger-fields`" :key="`${currentKey}-jira-trigger-fields`"
v-bind="propsSource.triggerFieldsProps" v-bind="propsSource.triggerFieldsProps"
:is-validated="isValidated"
/> />
<trigger-fields <trigger-fields
v-else-if="propsSource.triggerEvents.length" v-else-if="propsSource.triggerEvents.length"
...@@ -238,11 +241,13 @@ export default { ...@@ -238,11 +241,13 @@ export default {
v-for="field in propsSource.fields" v-for="field in propsSource.fields"
:key="`${currentKey}-${field.name}`" :key="`${currentKey}-${field.name}`"
v-bind="field" v-bind="field"
:is-validated="isValidated"
/> />
<jira-issues-fields <jira-issues-fields
v-if="isJira && !isInstanceOrGroupLevel" v-if="isJira && !isInstanceOrGroupLevel"
:key="`${currentKey}-jira-issues-fields`" :key="`${currentKey}-jira-issues-fields`"
v-bind="propsSource.jiraIssuesProps" v-bind="propsSource.jiraIssuesProps"
:is-validated="isValidated"
@request-jira-issue-types="onRequestJiraIssueTypes" @request-jira-issue-types="onRequestJiraIssueTypes"
/> />
......
<script> <script>
import { GlFormGroup, GlFormCheckbox, GlFormInput, GlSprintf, GlLink } from '@gitlab/ui'; import { GlFormGroup, GlFormCheckbox, GlFormInput, GlSprintf, GlLink } from '@gitlab/ui';
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import { VALIDATE_INTEGRATION_FORM_EVENT } from '~/integrations/constants';
import { s__, __ } from '~/locale'; import { s__, __ } from '~/locale';
import eventHub from '../event_hub';
import JiraUpgradeCta from './jira_upgrade_cta.vue'; import JiraUpgradeCta from './jira_upgrade_cta.vue';
export default { export default {
...@@ -64,29 +62,22 @@ export default { ...@@ -64,29 +62,22 @@ export default {
required: false, required: false,
default: '', default: '',
}, },
isValidated: {
type: Boolean,
required: false,
default: false,
},
}, },
data() { data() {
return { return {
enableJiraIssues: this.initialEnableJiraIssues, enableJiraIssues: this.initialEnableJiraIssues,
projectKey: this.initialProjectKey, projectKey: this.initialProjectKey,
validated: false,
}; };
}, },
computed: { computed: {
...mapGetters(['isInheriting']), ...mapGetters(['isInheriting']),
validProjectKey() { validProjectKey() {
return !this.enableJiraIssues || Boolean(this.projectKey) || !this.validated; return !this.enableJiraIssues || Boolean(this.projectKey) || !this.isValidated;
},
},
created() {
eventHub.$on(VALIDATE_INTEGRATION_FORM_EVENT, this.validateForm);
},
beforeDestroy() {
eventHub.$off(VALIDATE_INTEGRATION_FORM_EVENT, this.validateForm);
},
methods: {
validateForm() {
this.validated = true;
}, },
}, },
i18n: { i18n: {
......
...@@ -9,9 +9,7 @@ import { ...@@ -9,9 +9,7 @@ import {
} from '@gitlab/ui'; } from '@gitlab/ui';
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import { helpPagePath } from '~/helpers/help_page_helper'; import { helpPagePath } from '~/helpers/help_page_helper';
import { VALIDATE_INTEGRATION_FORM_EVENT } from '~/integrations/constants';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import eventHub from '../event_hub';
const commentDetailOptions = [ const commentDetailOptions = [
{ {
...@@ -92,10 +90,14 @@ export default { ...@@ -92,10 +90,14 @@ export default {
required: false, required: false,
default: '', default: '',
}, },
isValidated: {
type: Boolean,
required: false,
default: false,
},
}, },
data() { data() {
return { return {
validated: false,
triggerCommit: this.initialTriggerCommit, triggerCommit: this.initialTriggerCommit,
triggerMergeRequest: this.initialTriggerMergeRequest, triggerMergeRequest: this.initialTriggerMergeRequest,
enableComments: this.initialEnableComments, enableComments: this.initialEnableComments,
...@@ -115,19 +117,10 @@ export default { ...@@ -115,19 +117,10 @@ export default {
return this.triggerCommit || this.triggerMergeRequest; return this.triggerCommit || this.triggerMergeRequest;
}, },
validIssueTransitionId() { validIssueTransitionId() {
return !this.validated || Boolean(this.jiraIssueTransitionId); return !this.isValidated || Boolean(this.jiraIssueTransitionId);
}, },
}, },
created() {
eventHub.$on(VALIDATE_INTEGRATION_FORM_EVENT, this.validateForm);
},
beforeDestroy() {
eventHub.$off(VALIDATE_INTEGRATION_FORM_EVENT, this.validateForm);
},
methods: { methods: {
validateForm() {
this.validated = true;
},
showCustomIssueTransitions(currentOption) { showCustomIssueTransitions(currentOption) {
return ( return (
this.jiraIssueTransitionAutomatic === ISSUE_TRANSITION_CUSTOM && this.jiraIssueTransitionAutomatic === ISSUE_TRANSITION_CUSTOM &&
......
import createEventHub from '~/helpers/event_hub_factory';
export default createEventHub();
import { import {
VALIDATE_INTEGRATION_FORM_EVENT,
I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE, I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE,
I18N_DEFAULT_ERROR_MESSAGE, I18N_DEFAULT_ERROR_MESSAGE,
} from '~/integrations/constants'; } from '~/integrations/constants';
import { testIntegrationSettings } from '../api'; import { testIntegrationSettings } from '../api';
import eventHub from '../event_hub';
import * as types from './mutation_types'; import * as types from './mutation_types';
export const setOverride = ({ commit }, override) => commit(types.SET_OVERRIDE, override); export const setOverride = ({ commit }, override) => commit(types.SET_OVERRIDE, override);
...@@ -19,7 +17,6 @@ export const requestJiraIssueTypes = ({ commit, dispatch, getters }, formData) = ...@@ -19,7 +17,6 @@ export const requestJiraIssueTypes = ({ commit, dispatch, getters }, formData) =
data: { issuetypes, error, message = I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE }, data: { issuetypes, error, message = I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE },
}) => { }) => {
if (error || !issuetypes?.length) { if (error || !issuetypes?.length) {
eventHub.$emit(VALIDATE_INTEGRATION_FORM_EVENT);
throw new Error(message); throw new Error(message);
} }
......
export const SET_OVERRIDE = 'SET_OVERRIDE'; export const SET_OVERRIDE = 'SET_OVERRIDE';
export const SET_IS_RESETTING = 'SET_IS_RESETTING';
export const SET_IS_LOADING_JIRA_ISSUE_TYPES = 'SET_IS_LOADING_JIRA_ISSUE_TYPES'; export const SET_IS_LOADING_JIRA_ISSUE_TYPES = 'SET_IS_LOADING_JIRA_ISSUE_TYPES';
export const SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE = 'SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE'; export const SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE = 'SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE';
export const SET_JIRA_ISSUE_TYPES = 'SET_JIRA_ISSUE_TYPES'; export const SET_JIRA_ISSUE_TYPES = 'SET_JIRA_ISSUE_TYPES';
export const REQUEST_RESET_INTEGRATION = 'REQUEST_RESET_INTEGRATION';
export const RECEIVE_RESET_INTEGRATION_ERROR = 'RECEIVE_RESET_INTEGRATION_ERROR';
...@@ -2,22 +2,14 @@ import { GlFormGroup, GlFormCheckbox, GlFormInput, GlFormSelect, GlFormTextarea ...@@ -2,22 +2,14 @@ import { GlFormGroup, GlFormCheckbox, GlFormInput, GlFormSelect, GlFormTextarea
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import DynamicField from '~/integrations/edit/components/dynamic_field.vue'; import DynamicField from '~/integrations/edit/components/dynamic_field.vue';
import { mockField } from '../mock_data';
describe('DynamicField', () => { describe('DynamicField', () => {
let wrapper; let wrapper;
const defaultProps = {
help: 'The URL of the project',
name: 'project_url',
placeholder: 'https://jira.example.com',
title: 'Project URL',
type: 'text',
value: '1',
};
const createComponent = (props, isInheriting = false) => { const createComponent = (props, isInheriting = false) => {
wrapper = mount(DynamicField, { wrapper = mount(DynamicField, {
propsData: { ...defaultProps, ...props }, propsData: { ...mockField, ...props },
computed: { computed: {
isInheriting: () => isInheriting, isInheriting: () => isInheriting,
}, },
...@@ -61,7 +53,7 @@ describe('DynamicField', () => { ...@@ -61,7 +53,7 @@ describe('DynamicField', () => {
}); });
it(`renders GlFormCheckbox with correct text content when checkboxLabel is ${checkboxLabel}`, () => { it(`renders GlFormCheckbox with correct text content when checkboxLabel is ${checkboxLabel}`, () => {
expect(findGlFormCheckbox().text()).toContain(checkboxLabel ?? defaultProps.title); expect(findGlFormCheckbox().text()).toContain(checkboxLabel ?? mockField.title);
}); });
it('does not render other types of input', () => { it('does not render other types of input', () => {
...@@ -160,7 +152,7 @@ describe('DynamicField', () => { ...@@ -160,7 +152,7 @@ describe('DynamicField', () => {
type: 'text', type: 'text',
id: 'service_project_url', id: 'service_project_url',
name: 'service[project_url]', name: 'service[project_url]',
placeholder: defaultProps.placeholder, placeholder: mockField.placeholder,
required: 'required', required: 'required',
}); });
expect(findGlFormInput().attributes('readonly')).toBe(readonly); expect(findGlFormInput().attributes('readonly')).toBe(readonly);
...@@ -179,7 +171,7 @@ describe('DynamicField', () => { ...@@ -179,7 +171,7 @@ describe('DynamicField', () => {
it('renders description with help text', () => { it('renders description with help text', () => {
createComponent(); createComponent();
expect(findGlFormGroup().find('small').text()).toBe(defaultProps.help); expect(findGlFormGroup().find('small').text()).toBe(mockField.help);
}); });
describe('when type is checkbox', () => { describe('when type is checkbox', () => {
...@@ -189,7 +181,7 @@ describe('DynamicField', () => { ...@@ -189,7 +181,7 @@ describe('DynamicField', () => {
}); });
expect(findGlFormGroup().find('small').exists()).toBe(false); expect(findGlFormGroup().find('small').exists()).toBe(false);
expect(findGlFormCheckbox().text()).toContain(defaultProps.help); expect(findGlFormCheckbox().text()).toContain(mockField.help);
}); });
}); });
...@@ -221,40 +213,36 @@ describe('DynamicField', () => { ...@@ -221,40 +213,36 @@ describe('DynamicField', () => {
it('renders label with title', () => { it('renders label with title', () => {
createComponent(); createComponent();
expect(findGlFormGroup().find('label').text()).toBe(defaultProps.title); expect(findGlFormGroup().find('label').text()).toBe(mockField.title);
}); });
}); });
describe('validations', () => { describe('password field validations', () => {
describe('password field', () => { describe('without value', () => {
beforeEach(() => { it('requires validation', () => {
createComponent({ createComponent({
type: 'password', type: 'password',
required: true, required: true,
value: null, value: null,
isValidated: true,
}); });
wrapper.vm.validated = true; expect(findGlFormGroup().classes('is-invalid')).toBe(true);
}); expect(findGlFormInput().classes('is-invalid')).toBe(true);
describe('without value', () => {
it('requires validation', () => {
expect(wrapper.vm.valid).toBe(false);
expect(findGlFormGroup().classes('is-invalid')).toBe(true);
expect(findGlFormInput().classes('is-invalid')).toBe(true);
});
}); });
});
describe('with value', () => { describe('with value', () => {
beforeEach(() => { it('does not require validation', () => {
wrapper.setProps({ value: 'true' }); createComponent({
type: 'password',
required: true,
value: 'test value',
isValidated: true,
}); });
it('does not require validation', () => { expect(findGlFormGroup().classes('is-valid')).toBe(true);
expect(wrapper.vm.valid).toBe(true); expect(findGlFormInput().classes('is-valid')).toBe(true);
expect(findGlFormGroup().classes('is-valid')).toBe(true);
expect(findGlFormInput().classes('is-valid')).toBe(true);
});
}); });
}); });
}); });
......
...@@ -17,16 +17,13 @@ import TriggerFields from '~/integrations/edit/components/trigger_fields.vue'; ...@@ -17,16 +17,13 @@ import TriggerFields from '~/integrations/edit/components/trigger_fields.vue';
import { import {
integrationLevels, integrationLevels,
I18N_SUCCESSFUL_CONNECTION_MESSAGE, I18N_SUCCESSFUL_CONNECTION_MESSAGE,
VALIDATE_INTEGRATION_FORM_EVENT,
I18N_DEFAULT_ERROR_MESSAGE, I18N_DEFAULT_ERROR_MESSAGE,
} from '~/integrations/constants'; } from '~/integrations/constants';
import { createStore } from '~/integrations/edit/store'; import { createStore } from '~/integrations/edit/store';
import eventHub from '~/integrations/edit/event_hub';
import httpStatus from '~/lib/utils/http_status'; import httpStatus from '~/lib/utils/http_status';
import { refreshCurrentPage } from '~/lib/utils/url_utility'; import { refreshCurrentPage } from '~/lib/utils/url_utility';
import { mockIntegrationProps } from '../mock_data'; import { mockIntegrationProps, mockField } from '../mock_data';
jest.mock('~/integrations/edit/event_hub');
jest.mock('@sentry/browser'); jest.mock('@sentry/browser');
jest.mock('~/lib/utils/url_utility'); jest.mock('~/lib/utils/url_utility');
...@@ -97,6 +94,7 @@ describe('IntegrationForm', () => { ...@@ -97,6 +94,7 @@ describe('IntegrationForm', () => {
const findGlForm = () => wrapper.findComponent(GlForm); const findGlForm = () => wrapper.findComponent(GlForm);
const findRedirectToField = () => wrapper.findByTestId('redirect-to-field'); const findRedirectToField = () => wrapper.findByTestId('redirect-to-field');
const findFormElement = () => (vueIntegrationFormFeatureFlag ? findGlForm().element : mockForm); const findFormElement = () => (vueIntegrationFormFeatureFlag ? findGlForm().element : mockForm);
const findDynamicField = () => wrapper.findComponent(DynamicField);
const mockFormFunctions = ({ checkValidityReturn }) => { const mockFormFunctions = ({ checkValidityReturn }) => {
jest.spyOn(findFormElement(), 'checkValidity').mockReturnValue(checkValidityReturn); jest.spyOn(findFormElement(), 'checkValidity').mockReturnValue(checkValidityReturn);
...@@ -490,6 +488,7 @@ describe('IntegrationForm', () => { ...@@ -490,6 +488,7 @@ describe('IntegrationForm', () => {
showActive: true, showActive: true,
canTest: true, canTest: true,
initialActivated: true, initialActivated: true,
fields: [mockField],
}, },
mountFn: mountExtended, mountFn: mountExtended,
}); });
...@@ -510,27 +509,28 @@ describe('IntegrationForm', () => { ...@@ -510,27 +509,28 @@ describe('IntegrationForm', () => {
expect(findTestButton().props('disabled')).toBe(false); expect(findTestButton().props('disabled')).toBe(false);
}); });
it('emits `VALIDATE_INTEGRATION_FORM_EVENT`', () => { it('sets `isValidated` props on form fields', () => {
expect(eventHub.$emit).toHaveBeenCalledWith(VALIDATE_INTEGRATION_FORM_EVENT); expect(findDynamicField().props('isValidated')).toBe(true);
}); });
}); });
}); });
describe('when `test` button is clicked', () => { describe('when `test` button is clicked', () => {
describe('when form is invalid', () => { describe('when form is invalid', () => {
it('emits `VALIDATE_INTEGRATION_FORM_EVENT` event to the event hub', () => { it('sets `isValidated` props on form fields', async () => {
createComponent({ createComponent({
customStateProps: { customStateProps: {
showActive: true, showActive: true,
canTest: true, canTest: true,
fields: [mockField],
}, },
mountFn: mountExtended, mountFn: mountExtended,
}); });
mockFormFunctions({ checkValidityReturn: false }); mockFormFunctions({ checkValidityReturn: false });
findTestButton().vm.$emit('click', new Event('click')); await findTestButton().vm.$emit('click', new Event('click'));
expect(eventHub.$emit).toHaveBeenCalledWith(VALIDATE_INTEGRATION_FORM_EVENT); expect(findDynamicField().props('isValidated')).toBe(true);
}); });
}); });
......
import { GlFormCheckbox, GlFormInput } from '@gitlab/ui'; import { GlFormCheckbox, GlFormInput } from '@gitlab/ui';
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { VALIDATE_INTEGRATION_FORM_EVENT } from '~/integrations/constants';
import JiraIssuesFields from '~/integrations/edit/components/jira_issues_fields.vue'; import JiraIssuesFields from '~/integrations/edit/components/jira_issues_fields.vue';
import eventHub from '~/integrations/edit/event_hub';
import { createStore } from '~/integrations/edit/store'; import { createStore } from '~/integrations/edit/store';
describe('JiraIssuesFields', () => { describe('JiraIssuesFields', () => {
...@@ -222,7 +220,7 @@ describe('JiraIssuesFields', () => { ...@@ -222,7 +220,7 @@ describe('JiraIssuesFields', () => {
}); });
describe('Project key input field', () => { describe('Project key input field', () => {
beforeEach(() => { it('sets Project Key `state` attribute to `true` by default', () => {
createComponent({ createComponent({
props: { props: {
initialProjectKey: '', initialProjectKey: '',
...@@ -230,29 +228,32 @@ describe('JiraIssuesFields', () => { ...@@ -230,29 +228,32 @@ describe('JiraIssuesFields', () => {
}, },
mountFn: shallowMountExtended, mountFn: shallowMountExtended,
}); });
});
it('sets Project Key `state` attribute to `true` by default', () => {
assertProjectKeyState('true'); assertProjectKeyState('true');
}); });
describe('when event hub recieves `VALIDATE_INTEGRATION_FORM_EVENT` event', () => { describe('when `isValidated` prop is true', () => {
beforeEach(() => {
createComponent({
props: {
initialProjectKey: '',
initialEnableJiraIssues: true,
isValidated: true,
},
mountFn: shallowMountExtended,
});
});
describe('with no project key', () => { describe('with no project key', () => {
it('sets Project Key `state` attribute to `undefined`', async () => { it('sets Project Key `state` attribute to `undefined`', async () => {
eventHub.$emit(VALIDATE_INTEGRATION_FORM_EVENT);
await wrapper.vm.$nextTick();
assertProjectKeyState(undefined); assertProjectKeyState(undefined);
}); });
}); });
describe('when project key is set', () => { describe('when project key is set', () => {
it('sets Project Key `state` attribute to `true`', async () => { it('sets Project Key `state` attribute to `true`', async () => {
eventHub.$emit(VALIDATE_INTEGRATION_FORM_EVENT);
// set the project key // set the project key
await findProjectKey().vm.$emit('input', 'AB'); await findProjectKey().vm.$emit('input', 'AB');
await wrapper.vm.$nextTick();
assertProjectKeyState('true'); assertProjectKeyState('true');
}); });
......
...@@ -20,3 +20,12 @@ export const mockJiraIssueTypes = [ ...@@ -20,3 +20,12 @@ export const mockJiraIssueTypes = [
{ id: '2', name: 'bug', description: 'bug' }, { id: '2', name: 'bug', description: 'bug' },
{ id: '3', name: 'epic', description: 'epic' }, { id: '3', name: 'epic', description: 'epic' },
]; ];
export const mockField = {
help: 'The URL of the project',
name: 'project_url',
placeholder: 'https://jira.example.com',
title: 'Project URL',
type: 'text',
value: '1',
};
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