Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
83516c6aa6
commit
ba44d5ef19
|
@ -8,6 +8,7 @@ import {
|
||||||
GlButton,
|
GlButton,
|
||||||
GlCard,
|
GlCard,
|
||||||
} from '@gitlab/ui';
|
} from '@gitlab/ui';
|
||||||
|
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||||
import eventHub from '../event_hub';
|
import eventHub from '../event_hub';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -20,18 +21,36 @@ export default {
|
||||||
GlLink,
|
GlLink,
|
||||||
GlButton,
|
GlButton,
|
||||||
GlCard,
|
GlCard,
|
||||||
|
JiraIssueCreationVulnerabilities: () =>
|
||||||
|
import('ee_component/integrations/edit/components/jira_issue_creation_vulnerabilities.vue'),
|
||||||
},
|
},
|
||||||
|
mixins: [glFeatureFlagsMixin()],
|
||||||
props: {
|
props: {
|
||||||
showJiraIssuesIntegration: {
|
showJiraIssuesIntegration: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
showJiraVulnerabilitiesIntegration: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
initialEnableJiraIssues: {
|
initialEnableJiraIssues: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
initialEnableJiraVulnerabilities: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
initialVulnerabilitiesIssuetype: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
initialProjectKey: {
|
initialProjectKey: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
|
@ -45,12 +64,12 @@ export default {
|
||||||
upgradePlanPath: {
|
upgradePlanPath: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: null,
|
default: '',
|
||||||
},
|
},
|
||||||
editProjectPath: {
|
editProjectPath: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: null,
|
default: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -64,6 +83,13 @@ export default {
|
||||||
validProjectKey() {
|
validProjectKey() {
|
||||||
return !this.enableJiraIssues || Boolean(this.projectKey) || !this.validated;
|
return !this.enableJiraIssues || Boolean(this.projectKey) || !this.validated;
|
||||||
},
|
},
|
||||||
|
showJiraVulnerabilitiesOptions() {
|
||||||
|
return (
|
||||||
|
this.enableJiraIssues &&
|
||||||
|
this.showJiraVulnerabilitiesIntegration &&
|
||||||
|
this.glFeatures.jiraForVulnerabilities
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
eventHub.$on('validateForm', this.validateForm);
|
eventHub.$on('validateForm', this.validateForm);
|
||||||
|
@ -75,6 +101,9 @@ export default {
|
||||||
validateForm() {
|
validateForm() {
|
||||||
this.validated = true;
|
this.validated = true;
|
||||||
},
|
},
|
||||||
|
getJiraIssueTypes() {
|
||||||
|
eventHub.$emit('getJiraIssueTypes');
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -105,6 +134,14 @@ export default {
|
||||||
}}
|
}}
|
||||||
</template>
|
</template>
|
||||||
</gl-form-checkbox>
|
</gl-form-checkbox>
|
||||||
|
<jira-issue-creation-vulnerabilities
|
||||||
|
v-if="showJiraVulnerabilitiesOptions"
|
||||||
|
:project-key="projectKey"
|
||||||
|
:initial-is-enabled="initialEnableJiraVulnerabilities"
|
||||||
|
:initial-issue-type-id="initialVulnerabilitiesIssuetype"
|
||||||
|
data-testid="jira-for-vulnerabilities"
|
||||||
|
@request-get-issue-types="getJiraIssueTypes"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<gl-card v-else class="gl-mt-7">
|
<gl-card v-else class="gl-mt-7">
|
||||||
<strong>{{ __('This is a Premium feature') }}</strong>
|
<strong>{{ __('This is a Premium feature') }}</strong>
|
||||||
|
|
|
@ -27,6 +27,7 @@ function parseDatasetToProps(data) {
|
||||||
cancelPath,
|
cancelPath,
|
||||||
testPath,
|
testPath,
|
||||||
resetPath,
|
resetPath,
|
||||||
|
vulnerabilitiesIssuetype,
|
||||||
...booleanAttributes
|
...booleanAttributes
|
||||||
} = data;
|
} = data;
|
||||||
const {
|
const {
|
||||||
|
@ -38,7 +39,9 @@ function parseDatasetToProps(data) {
|
||||||
mergeRequestEvents,
|
mergeRequestEvents,
|
||||||
enableComments,
|
enableComments,
|
||||||
showJiraIssuesIntegration,
|
showJiraIssuesIntegration,
|
||||||
|
showJiraVulnerabilitiesIntegration,
|
||||||
enableJiraIssues,
|
enableJiraIssues,
|
||||||
|
enableJiraVulnerabilities,
|
||||||
gitlabIssuesEnabled,
|
gitlabIssuesEnabled,
|
||||||
} = parseBooleanInData(booleanAttributes);
|
} = parseBooleanInData(booleanAttributes);
|
||||||
|
|
||||||
|
@ -59,7 +62,10 @@ function parseDatasetToProps(data) {
|
||||||
},
|
},
|
||||||
jiraIssuesProps: {
|
jiraIssuesProps: {
|
||||||
showJiraIssuesIntegration,
|
showJiraIssuesIntegration,
|
||||||
|
showJiraVulnerabilitiesIntegration,
|
||||||
initialEnableJiraIssues: enableJiraIssues,
|
initialEnableJiraIssues: enableJiraIssues,
|
||||||
|
initialEnableJiraVulnerabilities: enableJiraVulnerabilities,
|
||||||
|
initialVulnerabilitiesIssuetype: vulnerabilitiesIssuetype,
|
||||||
initialProjectKey: projectKey,
|
initialProjectKey: projectKey,
|
||||||
gitlabIssuesEnabled,
|
gitlabIssuesEnabled,
|
||||||
upgradePlanPath,
|
upgradePlanPath,
|
||||||
|
|
|
@ -26,3 +26,18 @@ export const fetchResetIntegration = ({ dispatch, getters }) => {
|
||||||
.then(() => dispatch('receiveResetIntegrationSuccess'))
|
.then(() => dispatch('receiveResetIntegrationSuccess'))
|
||||||
.catch(() => dispatch('receiveResetIntegrationError'));
|
.catch(() => dispatch('receiveResetIntegrationError'));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const requestJiraIssueTypes = ({ commit }) => {
|
||||||
|
commit(types.SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE, '');
|
||||||
|
commit(types.SET_IS_LOADING_JIRA_ISSUE_TYPES, true);
|
||||||
|
};
|
||||||
|
export const receiveJiraIssueTypesSuccess = ({ commit }, issueTypes = []) => {
|
||||||
|
commit(types.SET_IS_LOADING_JIRA_ISSUE_TYPES, false);
|
||||||
|
commit(types.SET_JIRA_ISSUE_TYPES, issueTypes);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const receiveJiraIssueTypesError = ({ commit }, errorMessage) => {
|
||||||
|
commit(types.SET_IS_LOADING_JIRA_ISSUE_TYPES, false);
|
||||||
|
commit(types.SET_JIRA_ISSUE_TYPES, []);
|
||||||
|
commit(types.SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE, errorMessage);
|
||||||
|
};
|
||||||
|
|
|
@ -3,5 +3,9 @@ export const SET_IS_SAVING = 'SET_IS_SAVING';
|
||||||
export const SET_IS_TESTING = 'SET_IS_TESTING';
|
export const SET_IS_TESTING = 'SET_IS_TESTING';
|
||||||
export const SET_IS_RESETTING = 'SET_IS_RESETTING';
|
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_JIRA_ISSUE_TYPES_ERROR_MESSAGE = 'SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE';
|
||||||
|
export const SET_JIRA_ISSUE_TYPES = 'SET_JIRA_ISSUE_TYPES';
|
||||||
|
|
||||||
export const REQUEST_RESET_INTEGRATION = 'REQUEST_RESET_INTEGRATION';
|
export const REQUEST_RESET_INTEGRATION = 'REQUEST_RESET_INTEGRATION';
|
||||||
export const RECEIVE_RESET_INTEGRATION_ERROR = 'RECEIVE_RESET_INTEGRATION_ERROR';
|
export const RECEIVE_RESET_INTEGRATION_ERROR = 'RECEIVE_RESET_INTEGRATION_ERROR';
|
||||||
|
|
|
@ -19,4 +19,13 @@ export default {
|
||||||
[types.RECEIVE_RESET_INTEGRATION_ERROR](state) {
|
[types.RECEIVE_RESET_INTEGRATION_ERROR](state) {
|
||||||
state.isResetting = false;
|
state.isResetting = false;
|
||||||
},
|
},
|
||||||
|
[types.SET_JIRA_ISSUE_TYPES](state, jiraIssueTypes) {
|
||||||
|
state.jiraIssueTypes = jiraIssueTypes;
|
||||||
|
},
|
||||||
|
[types.SET_IS_LOADING_JIRA_ISSUE_TYPES](state, isLoadingJiraIssueTypes) {
|
||||||
|
state.isLoadingJiraIssueTypes = isLoadingJiraIssueTypes;
|
||||||
|
},
|
||||||
|
[types.SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE](state, errorMessage) {
|
||||||
|
state.loadingJiraIssueTypesErrorMessage = errorMessage;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,5 +8,8 @@ export default ({ defaultState = null, customState = {} } = {}) => {
|
||||||
isSaving: false,
|
isSaving: false,
|
||||||
isTesting: false,
|
isTesting: false,
|
||||||
isResetting: false,
|
isResetting: false,
|
||||||
|
isLoadingJiraIssueTypes: false,
|
||||||
|
loadingJiraIssueTypesErrorMessage: '',
|
||||||
|
jiraIssueTypes: [],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,6 +33,12 @@ export default class IntegrationSettingsForm {
|
||||||
eventHub.$on('saveIntegration', () => {
|
eventHub.$on('saveIntegration', () => {
|
||||||
this.saveIntegration();
|
this.saveIntegration();
|
||||||
});
|
});
|
||||||
|
eventHub.$on('getJiraIssueTypes', () => {
|
||||||
|
// eslint-disable-next-line no-jquery/no-serialize
|
||||||
|
this.getJiraIssueTypes(this.$form.serialize());
|
||||||
|
});
|
||||||
|
|
||||||
|
eventHub.$emit('formInitialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
saveIntegration() {
|
saveIntegration() {
|
||||||
|
@ -79,16 +85,59 @@ export default class IntegrationSettingsForm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of Jira issue types for the currently configured project
|
||||||
|
*
|
||||||
|
* @param {string} formData - URL encoded string containing the form data
|
||||||
|
*
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
|
getJiraIssueTypes(formData) {
|
||||||
|
const {
|
||||||
|
$store: { dispatch },
|
||||||
|
} = this.vue;
|
||||||
|
|
||||||
|
dispatch('requestJiraIssueTypes');
|
||||||
|
|
||||||
|
return this.fetchTestSettings(formData)
|
||||||
|
.then(
|
||||||
|
({
|
||||||
|
data: {
|
||||||
|
issuetypes,
|
||||||
|
error,
|
||||||
|
message = s__('Integrations|Connection failed. Please check your settings.'),
|
||||||
|
},
|
||||||
|
}) => {
|
||||||
|
if (error || !issuetypes?.length) {
|
||||||
|
eventHub.$emit('validateForm');
|
||||||
|
throw new Error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch('receiveJiraIssueTypesSuccess', issuetypes);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.catch(({ message = __('Something went wrong on our end.') }) => {
|
||||||
|
dispatch('receiveJiraIssueTypesError', message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send request to the test endpoint which checks if the current config is valid
|
||||||
|
*/
|
||||||
|
fetchTestSettings(formData) {
|
||||||
|
return axios.put(this.testEndPoint, formData);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test Integration config
|
* Test Integration config
|
||||||
*/
|
*/
|
||||||
testSettings(formData) {
|
testSettings(formData) {
|
||||||
return axios
|
return this.fetchTestSettings(formData)
|
||||||
.put(this.testEndPoint, formData)
|
|
||||||
.then(({ data }) => {
|
.then(({ data }) => {
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
toast(`${data.message} ${data.service_response}`);
|
toast(`${data.message} ${data.service_response}`);
|
||||||
} else {
|
} else {
|
||||||
|
this.vue.$store.dispatch('receiveJiraIssueTypesSuccess', data.issuetypes);
|
||||||
toast(s__('Integrations|Connection successful.'));
|
toast(s__('Integrations|Connection successful.'));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -16091,15 +16091,27 @@ msgstr ""
|
||||||
msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
|
msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "JiraService|An error occured while fetching issue list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
|
msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "JiraService|Enable Jira issues"
|
msgid "JiraService|Enable Jira issues"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "JiraService|Enable Jira issues creation from vulnerabilities"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "JiraService|Events for %{noteable_model_name} are disabled."
|
msgid "JiraService|Events for %{noteable_model_name} are disabled."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "JiraService|Fetch issue types for this Jira project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "JiraService|For example, 12, 24"
|
msgid "JiraService|For example, 12, 24"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -16109,6 +16121,9 @@ msgstr ""
|
||||||
msgid "JiraService|Issue List"
|
msgid "JiraService|Issue List"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "JiraService|Issues created from vulnerabilities in this project will be Jira issues, even if GitLab issues are enabled."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "JiraService|Jira API URL"
|
msgid "JiraService|Jira API URL"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -16124,6 +16139,9 @@ msgstr ""
|
||||||
msgid "JiraService|Jira issue tracker"
|
msgid "JiraService|Jira issue tracker"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "JiraService|Jira issue type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "JiraService|Jira project key"
|
msgid "JiraService|Jira project key"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -16136,6 +16154,15 @@ msgstr ""
|
||||||
msgid "JiraService|Password or API token"
|
msgid "JiraService|Password or API token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "JiraService|Project key changed, refresh list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "JiraService|Project key is required to generate issue types"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "JiraService|Select issue type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "JiraService|Set transition IDs for Jira workflow transitions. %{link_start}Learn more%{link_end}"
|
msgid "JiraService|Set transition IDs for Jira workflow transitions. %{link_start}Learn more%{link_end}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -3,18 +3,22 @@ import { mount } from '@vue/test-utils';
|
||||||
import { GlFormCheckbox, GlFormInput } from '@gitlab/ui';
|
import { GlFormCheckbox, GlFormInput } from '@gitlab/ui';
|
||||||
|
|
||||||
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';
|
||||||
|
|
||||||
describe('JiraIssuesFields', () => {
|
describe('JiraIssuesFields', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
showJiraIssuesIntegration: true,
|
|
||||||
editProjectPath: '/edit',
|
editProjectPath: '/edit',
|
||||||
|
showJiraIssuesIntegration: true,
|
||||||
|
showJiraVulnerabilitiesIntegration: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const createComponent = (props) => {
|
const createComponent = ({ props, ...options } = {}) => {
|
||||||
wrapper = mount(JiraIssuesFields, {
|
wrapper = mount(JiraIssuesFields, {
|
||||||
propsData: { ...defaultProps, ...props },
|
propsData: { ...defaultProps, ...props },
|
||||||
|
stubs: ['jira-issue-creation-vulnerabilities'],
|
||||||
|
...options,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,11 +32,14 @@ describe('JiraIssuesFields', () => {
|
||||||
const findEnableCheckbox = () => wrapper.find(GlFormCheckbox);
|
const findEnableCheckbox = () => wrapper.find(GlFormCheckbox);
|
||||||
const findProjectKey = () => wrapper.find(GlFormInput);
|
const findProjectKey = () => wrapper.find(GlFormInput);
|
||||||
const expectedBannerText = 'This is a Premium feature';
|
const expectedBannerText = 'This is a Premium feature';
|
||||||
|
const findJiraForVulnerabilities = () => wrapper.find('[data-testid="jira-for-vulnerabilities"]');
|
||||||
|
const setEnableCheckbox = async (isEnabled = true) =>
|
||||||
|
findEnableCheckbox().vm.$emit('input', isEnabled);
|
||||||
|
|
||||||
describe('template', () => {
|
describe('template', () => {
|
||||||
describe('upgrade banner for non-Premium user', () => {
|
describe('upgrade banner for non-Premium user', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
createComponent({ initialProjectKey: '', showJiraIssuesIntegration: false });
|
createComponent({ props: { initialProjectKey: '', showJiraIssuesIntegration: false } });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows upgrade banner', () => {
|
it('shows upgrade banner', () => {
|
||||||
|
@ -47,7 +54,7 @@ describe('JiraIssuesFields', () => {
|
||||||
|
|
||||||
describe('Enable Jira issues checkbox', () => {
|
describe('Enable Jira issues checkbox', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
createComponent({ initialProjectKey: '' });
|
createComponent({ props: { initialProjectKey: '' } });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not show upgrade banner', () => {
|
it('does not show upgrade banner', () => {
|
||||||
|
@ -69,20 +76,16 @@ describe('JiraIssuesFields', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('on enable issues', () => {
|
describe('on enable issues', () => {
|
||||||
it('enables project_key input', () => {
|
it('enables project_key input', async () => {
|
||||||
findEnableCheckbox().vm.$emit('input', true);
|
await setEnableCheckbox(true);
|
||||||
|
|
||||||
return wrapper.vm.$nextTick().then(() => {
|
expect(findProjectKey().attributes('disabled')).toBeUndefined();
|
||||||
expect(findProjectKey().attributes('disabled')).toBeUndefined();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('requires project_key input', () => {
|
it('requires project_key input', async () => {
|
||||||
findEnableCheckbox().vm.$emit('input', true);
|
await setEnableCheckbox(true);
|
||||||
|
|
||||||
return wrapper.vm.$nextTick().then(() => {
|
expect(findProjectKey().attributes('required')).toBe('required');
|
||||||
expect(findProjectKey().attributes('required')).toBe('required');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -103,10 +106,46 @@ describe('JiraIssuesFields', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not contain warning when GitLab issues is disabled', () => {
|
it('does not contain warning when GitLab issues is disabled', () => {
|
||||||
createComponent({ gitlabIssuesEnabled: false });
|
createComponent({ props: { gitlabIssuesEnabled: false } });
|
||||||
|
|
||||||
expect(wrapper.text()).not.toContain(expectedText);
|
expect(wrapper.text()).not.toContain(expectedText);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Vulnerabilities creation', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
createComponent({ provide: { glFeatures: { jiraForVulnerabilities: true } } });
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each([true, false])(
|
||||||
|
'shows the jira-vulnerabilities component correctly when jira issues enables is set to "%s"',
|
||||||
|
async (hasJiraIssuesEnabled) => {
|
||||||
|
await setEnableCheckbox(hasJiraIssuesEnabled);
|
||||||
|
|
||||||
|
expect(findJiraForVulnerabilities().exists()).toBe(hasJiraIssuesEnabled);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
it('emits "getJiraIssueTypes" to the eventHub when the jira-vulnerabilities component requests to fetch issue types', async () => {
|
||||||
|
const eventHubEmitSpy = jest.spyOn(eventHub, '$emit');
|
||||||
|
|
||||||
|
await setEnableCheckbox(true);
|
||||||
|
await findJiraForVulnerabilities().vm.$emit('request-get-issue-types');
|
||||||
|
|
||||||
|
expect(eventHubEmitSpy).toHaveBeenCalledWith('getJiraIssueTypes');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with "jiraForVulnerabilities" feature flag disabled', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
createComponent({
|
||||||
|
provide: { glFeatures: { jiraForVulnerabilities: false } },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not show section', () => {
|
||||||
|
expect(findJiraForVulnerabilities().exists()).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,6 +9,9 @@ import {
|
||||||
requestResetIntegration,
|
requestResetIntegration,
|
||||||
receiveResetIntegrationSuccess,
|
receiveResetIntegrationSuccess,
|
||||||
receiveResetIntegrationError,
|
receiveResetIntegrationError,
|
||||||
|
requestJiraIssueTypes,
|
||||||
|
receiveJiraIssueTypesSuccess,
|
||||||
|
receiveJiraIssueTypesError,
|
||||||
} from '~/integrations/edit/store/actions';
|
} from '~/integrations/edit/store/actions';
|
||||||
import * as types from '~/integrations/edit/store/mutation_types';
|
import * as types from '~/integrations/edit/store/mutation_types';
|
||||||
|
|
||||||
|
@ -70,4 +73,34 @@ describe('Integration form store actions', () => {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('requestJiraIssueTypes', () => {
|
||||||
|
it('should commit SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE and SET_IS_LOADING_JIRA_ISSUE_TYPES mutations', () => {
|
||||||
|
return testAction(requestJiraIssueTypes, null, state, [
|
||||||
|
{ type: types.SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE, payload: '' },
|
||||||
|
{ type: types.SET_IS_LOADING_JIRA_ISSUE_TYPES, payload: true },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('receiveJiraIssueTypesSuccess', () => {
|
||||||
|
it('should commit SET_IS_LOADING_JIRA_ISSUE_TYPES and SET_JIRA_ISSUE_TYPES mutations', () => {
|
||||||
|
const issueTypes = ['issue', 'epic'];
|
||||||
|
return testAction(receiveJiraIssueTypesSuccess, issueTypes, state, [
|
||||||
|
{ type: types.SET_IS_LOADING_JIRA_ISSUE_TYPES, payload: false },
|
||||||
|
{ type: types.SET_JIRA_ISSUE_TYPES, payload: issueTypes },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('receiveJiraIssueTypesError', () => {
|
||||||
|
it('should commit SET_IS_LOADING_JIRA_ISSUE_TYPES, SET_JIRA_ISSUE_TYPES and SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE mutations', () => {
|
||||||
|
const errorMessage = 'something went wrong';
|
||||||
|
return testAction(receiveJiraIssueTypesError, errorMessage, state, [
|
||||||
|
{ type: types.SET_IS_LOADING_JIRA_ISSUE_TYPES, payload: false },
|
||||||
|
{ type: types.SET_JIRA_ISSUE_TYPES, payload: [] },
|
||||||
|
{ type: types.SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE, payload: errorMessage },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -56,4 +56,30 @@ describe('Integration form store mutations', () => {
|
||||||
expect(state.isResetting).toBe(false);
|
expect(state.isResetting).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe(`${types.SET_JIRA_ISSUE_TYPES}`, () => {
|
||||||
|
it('sets jiraIssueTypes', () => {
|
||||||
|
const jiraIssueTypes = ['issue', 'epic'];
|
||||||
|
mutations[types.SET_JIRA_ISSUE_TYPES](state, jiraIssueTypes);
|
||||||
|
|
||||||
|
expect(state.jiraIssueTypes).toBe(jiraIssueTypes);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(`${types.SET_IS_LOADING_JIRA_ISSUE_TYPES}`, () => {
|
||||||
|
it.each([true, false])('sets isLoadingJiraIssueTypes to "%s"', (isLoading) => {
|
||||||
|
mutations[types.SET_IS_LOADING_JIRA_ISSUE_TYPES](state, isLoading);
|
||||||
|
|
||||||
|
expect(state.isLoadingJiraIssueTypes).toBe(isLoading);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(`${types.SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE}`, () => {
|
||||||
|
it('sets loadingJiraIssueTypesErrorMessage', () => {
|
||||||
|
const errorMessage = 'something went wrong';
|
||||||
|
mutations[types.SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE](state, errorMessage);
|
||||||
|
|
||||||
|
expect(state.loadingJiraIssueTypesErrorMessage).toBe(errorMessage);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,6 +9,9 @@ describe('Integration form state factory', () => {
|
||||||
isTesting: false,
|
isTesting: false,
|
||||||
isResetting: false,
|
isResetting: false,
|
||||||
override: false,
|
override: false,
|
||||||
|
isLoadingJiraIssueTypes: false,
|
||||||
|
jiraIssueTypes: [],
|
||||||
|
loadingJiraIssueTypesErrorMessage: '',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -132,4 +132,83 @@ describe('IntegrationSettingsForm', () => {
|
||||||
expect(dispatchSpy).toHaveBeenCalledWith('setIsTesting', false);
|
expect(dispatchSpy).toHaveBeenCalledWith('setIsTesting', false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getJiraIssueTypes', () => {
|
||||||
|
let integrationSettingsForm;
|
||||||
|
let formData;
|
||||||
|
let mock;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mock = new MockAdaptor(axios);
|
||||||
|
|
||||||
|
jest.spyOn(axios, 'put');
|
||||||
|
|
||||||
|
integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form');
|
||||||
|
integrationSettingsForm.init();
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-jquery/no-serialize
|
||||||
|
formData = integrationSettingsForm.$form.serialize();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
mock.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should always dispatch `requestJiraIssueTypes`', async () => {
|
||||||
|
const dispatchSpy = jest.fn();
|
||||||
|
|
||||||
|
mock.onPut(integrationSettingsForm.testEndPoint).networkError();
|
||||||
|
|
||||||
|
integrationSettingsForm.vue.$store = { dispatch: dispatchSpy };
|
||||||
|
|
||||||
|
await integrationSettingsForm.getJiraIssueTypes();
|
||||||
|
|
||||||
|
expect(dispatchSpy).toHaveBeenCalledWith('requestJiraIssueTypes');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should make an ajax request with provided `formData`', async () => {
|
||||||
|
await integrationSettingsForm.getJiraIssueTypes(formData);
|
||||||
|
|
||||||
|
expect(axios.put).toHaveBeenCalledWith(integrationSettingsForm.testEndPoint, formData);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should dispatch `receiveJiraIssueTypesSuccess` with the correct payload if ajax request is successful', async () => {
|
||||||
|
const mockData = ['ISSUE', 'EPIC'];
|
||||||
|
const dispatchSpy = jest.fn();
|
||||||
|
|
||||||
|
mock.onPut(integrationSettingsForm.testEndPoint).reply(200, {
|
||||||
|
error: false,
|
||||||
|
issuetypes: mockData,
|
||||||
|
});
|
||||||
|
|
||||||
|
integrationSettingsForm.vue.$store = { dispatch: dispatchSpy };
|
||||||
|
|
||||||
|
await integrationSettingsForm.getJiraIssueTypes(formData);
|
||||||
|
|
||||||
|
expect(dispatchSpy).toHaveBeenCalledWith('receiveJiraIssueTypesSuccess', mockData);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each(['something went wrong', undefined])(
|
||||||
|
'should dispatch "receiveJiraIssueTypesError" with a message if the backend responds with error',
|
||||||
|
async (responseErrorMessage) => {
|
||||||
|
const defaultErrorMessage = 'Connection failed. Please check your settings.';
|
||||||
|
const expectedErrorMessage = responseErrorMessage || defaultErrorMessage;
|
||||||
|
const dispatchSpy = jest.fn();
|
||||||
|
|
||||||
|
mock.onPut(integrationSettingsForm.testEndPoint).reply(200, {
|
||||||
|
error: true,
|
||||||
|
message: responseErrorMessage,
|
||||||
|
});
|
||||||
|
|
||||||
|
integrationSettingsForm.vue.$store = { dispatch: dispatchSpy };
|
||||||
|
|
||||||
|
await integrationSettingsForm.getJiraIssueTypes(formData);
|
||||||
|
|
||||||
|
expect(dispatchSpy).toHaveBeenCalledWith(
|
||||||
|
'receiveJiraIssueTypesError',
|
||||||
|
expectedErrorMessage,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue