Commit e0727b2a authored by Savas Vedova's avatar Savas Vedova

Merge branch '289815-jira-integration-fe' into 'master'

Display create jira issue button when available

See merge request gitlab-org/gitlab!53469
parents cadc4528 3eeef9cf
......@@ -5,7 +5,6 @@ import SplitButton from 'ee/vue_shared/security_reports/components/split_button.
import { s__ } from '~/locale';
export default {
name: 'ModalFooter',
components: {
DismissButton,
GlButton,
......@@ -58,15 +57,26 @@ export default {
type: Boolean,
required: true,
},
vulnerability: {
type: Object,
required: true,
},
},
computed: {
createIssueButtonText() {
return this.vulnerability.create_jira_issue_url
? s__('ciReport|Create Jira issue')
: s__('ciReport|Create issue');
},
actionButtons() {
const buttons = [];
const issueButton = {
name: s__('ciReport|Create issue'),
name: this.createIssueButtonText,
tagline: s__('ciReport|Investigate this vulnerability by creating an issue'),
isLoading: this.isCreatingIssue,
action: 'createNewIssue',
action: this.vulnerability.create_jira_issue_url ? undefined : 'createNewIssue',
href: this.vulnerability.create_jira_issue_url,
};
const MRButton = {
name: s__('ciReport|Resolve with merge request'),
......@@ -128,11 +138,13 @@ export default {
<gl-button
v-else-if="actionButtons.length > 0"
:loading="actionButtons[0].isLoading"
:disabled="actionButtons[0].isLoading || disabled"
:disabled="disabled"
variant="success"
category="secondary"
class="js-action-button"
data-testid="create-issue-button"
data-qa-selector="create_issue_button"
:target="actionButtons[0].href ? '_blank' : undefined"
:href="actionButtons[0].href"
@click="$emit(actionButtons[0].action)"
>
{{ __(actionButtons[0].name) }}
......
<script>
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { visitUrl } from '~/lib/utils/url_utility';
export default {
components: {
......@@ -28,7 +29,11 @@ export default {
this.selectedButton = button;
},
handleClick() {
if (this.selectedButton.href) {
visitUrl(this.selectedButton.href, true);
} else {
this.$emit(this.selectedButton.action);
}
},
},
};
......@@ -40,6 +45,7 @@ export default {
:disabled="disabled"
variant="success"
:text="selectedButton.name"
:href="selectedButton.href"
split
@click="handleClick"
>
......
......@@ -13,11 +13,14 @@ describe('Security Reports modal footer', () => {
isCreatingIssue: false,
isDismissingVulnerability: false,
isCreatingMergeRequest: false,
vulnerability: {},
...propsData,
},
});
};
const findActionButton = () => wrapper.find('[data-testid=create-issue-button]');
describe('can only create issue', () => {
beforeEach(() => {
const propsData = {
......@@ -33,11 +36,11 @@ describe('Security Reports modal footer', () => {
it('only renders the create issue button', () => {
expect(wrapper.vm.actionButtons[0].name).toBe('Create issue');
expect(wrapper.find('.js-action-button').text()).toBe('Create issue');
expect(findActionButton().text()).toBe('Create issue');
});
it('emits createIssue when create issue button is clicked', () => {
wrapper.find('.js-action-button').trigger('click');
findActionButton().trigger('click');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted().createNewIssue).toBeTruthy();
......@@ -45,6 +48,34 @@ describe('Security Reports modal footer', () => {
});
});
describe('can only create jira issue', () => {
const url = 'https://gitlab.atlassian.net/create-issue';
beforeEach(() => {
const propsData = {
modal: createState().modal,
canCreateIssue: true,
vulnerability: {
create_jira_issue_url: url,
},
};
mountComponent(propsData);
});
it('has target property properly set', () => {
expect(findActionButton().props('target')).toBe('_blank');
expect(findActionButton().props('action')).toBeUndefined();
});
it('has href attribute properly set', () => {
expect(findActionButton().attributes('href')).toBe(url);
});
it('has the correct text', () => {
expect(findActionButton().text()).toBe('Create Jira issue');
});
});
describe('can only create merge request', () => {
beforeEach(() => {
const propsData = {
......@@ -56,11 +87,11 @@ describe('Security Reports modal footer', () => {
it('only renders the create merge request button', () => {
expect(wrapper.vm.actionButtons[0].name).toBe('Resolve with merge request');
expect(wrapper.find('.js-action-button').text()).toBe('Resolve with merge request');
expect(findActionButton().text()).toBe('Resolve with merge request');
});
it('emits createMergeRequest when create merge request button is clicked', () => {
wrapper.find('.js-action-button').trigger('click');
findActionButton().trigger('click');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted().createMergeRequest).toBeTruthy();
......@@ -79,11 +110,11 @@ describe('Security Reports modal footer', () => {
it('renders the download patch button', () => {
expect(wrapper.vm.actionButtons[0].name).toBe('Download patch to resolve');
expect(wrapper.find('.js-action-button').text()).toBe('Download patch to resolve');
expect(findActionButton().text()).toBe('Download patch to resolve');
});
it('emits downloadPatch when download patch button is clicked', () => {
wrapper.find('.js-action-button').trigger('click');
findActionButton().trigger('click');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted().downloadPatch).toBeTruthy();
......
......@@ -108,6 +108,8 @@ describe('Security Reports modal', () => {
});
describe('with merge request created', () => {
const findActionButton = () => wrapper.find('[data-testid=create-issue-button]');
it('renders the issue button as a single button', (done) => {
const propsData = {
modal: createState().modal,
......@@ -122,11 +124,9 @@ describe('Security Reports modal', () => {
Vue.nextTick()
.then(() => {
expect(wrapper.find('.js-split-button').exists()).toBe(false);
expect(wrapper.find('.js-action-button').exists()).toBe(true);
expect(wrapper.find('.js-action-button').text()).not.toContain(
'Resolve with merge request',
);
expect(wrapper.find('.js-action-button').text()).toContain('Create issue');
expect(findActionButton().exists()).toBe(true);
expect(findActionButton().text()).not.toContain('Resolve with merge request');
expect(findActionButton().text()).toContain('Create issue');
done();
})
.catch(done.fail);
......
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import SplitButton from 'ee/vue_shared/security_reports/components/split_button.vue';
import * as urlUtility from '~/lib/utils/url_utility';
const buttons = [
{
......@@ -64,6 +65,20 @@ describe('Split Button', () => {
expect(wrapper.emitted('button1Action')).toHaveLength(1);
});
it('visits url if href property is specified', () => {
const spy = jest.spyOn(urlUtility, 'visitUrl').mockReturnValue({});
const href = 'https://gitlab.com';
createComponent({
buttons: [{ ...buttons.slice(0), action: undefined, href }],
});
findDropdown().vm.$emit('click');
expect(wrapper.emitted('button1Action')).toBeUndefined();
expect(spy).toHaveBeenCalledWith(href, true);
});
it('renders a correct amount of dropdown items', () => {
createComponent({
buttons,
......
......@@ -34149,6 +34149,9 @@ msgstr ""
msgid "ciReport|Coverage fuzzing"
msgstr ""
msgid "ciReport|Create Jira issue"
msgstr ""
msgid "ciReport|Create a merge request to implement this solution, or download and apply the patch manually."
msgstr ""
......
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