import {Fragment} from 'react';
import {mountWithTheme} from 'sentry-test/enzyme';
import GlobalModal from 'sentry/components/globalModal';
import SentryAppExternalIssueActions from 'sentry/components/group/sentryAppExternalIssueActions';
describe('SentryAppExternalIssueActions', () => {
let group;
let component;
let sentryApp;
let install;
let submitUrl;
let externalIssue;
let wrapper;
beforeEach(() => {
group = TestStubs.Group();
sentryApp = TestStubs.SentryApp();
component = TestStubs.SentryAppComponent({
sentryApp: {
uuid: sentryApp.uuid,
slug: sentryApp.slug,
name: sentryApp.name,
},
});
// unable to use the selectByValue here so remove the select option
component.schema.create.required_fields.pop();
install = TestStubs.SentryAppInstallation({sentryApp});
submitUrl = `/sentry-app-installations/${install.uuid}/external-issue-actions/`;
externalIssue = TestStubs.PlatformExternalIssue({
groupId: group.id,
serviceType: component.sentryApp.slug,
});
MockApiClient.addMockResponse({
url: `/sentry-apps/${sentryApp.slug}/interaction/`,
method: 'POST',
});
});
describe('without an external issue linked', () => {
beforeEach(() => {
wrapper = mountWithTheme(
);
});
it('renders a link to open the modal', () => {
expect(wrapper.find('StyledIntegrationLink a').text()).toEqual(
`${component.sentryApp.name} Issue`
);
});
it('renders the add icon', () => {
expect(wrapper.find('StyledIcon IconAdd')).toHaveLength(1);
});
it('opens the modal', async () => {
wrapper.find('StyledIntegrationLink a').simulate('click');
await tick();
wrapper.update();
expect(wrapper.find('GlobalModal[visible=true]').exists()).toEqual(true);
});
it('renders the Create Issue form fields, based on schema', async () => {
wrapper.find('StyledIntegrationLink a').simulate('click');
await tick();
wrapper.update();
wrapper.find('Modal NavTabs li.create a').first().simulate('click'); // Create
component.schema.create.required_fields.forEach(field => {
expect(wrapper.exists(`SentryAppExternalIssueForm #${field.name}`)).toBe(true);
});
(component.schema.create.optional_fields || []).forEach(field => {
expect(wrapper.exists(`SentryAppExternalIssueForm #${field.name}`)).toBe(true);
});
});
it('renders the Link Issue form fields, based on schema', async () => {
wrapper.find('StyledIntegrationLink a').simulate('click');
await tick();
wrapper.update();
wrapper.find('Modal NavTabs li.link a').first().simulate('click'); // Link
component.schema.link.required_fields.forEach(field => {
expect(wrapper.exists(`SentryAppExternalIssueForm #${field.name}`)).toBe(true);
});
(component.schema.link.optional_fields || []).forEach(field => {
expect(wrapper.exists(`SentryAppExternalIssueForm #${field.name}`)).toBe(true);
});
});
it('links to an existing Issue', async () => {
const request = MockApiClient.addMockResponse({
url: submitUrl,
method: 'POST',
body: externalIssue,
});
wrapper.find('StyledIntegrationLink a').simulate('click');
await tick();
wrapper.update();
wrapper.find('NavTabs li.link a').simulate('click');
wrapper.find('Input#issue').simulate('change', {target: {value: '99'}});
wrapper.find('Form form').simulate('submit');
expect(request).toHaveBeenCalledWith(
submitUrl,
expect.objectContaining({
data: expect.objectContaining({
action: 'link',
issue: '99',
groupId: group.id,
}),
})
);
});
it('creates a new Issue', async () => {
const request = MockApiClient.addMockResponse({
url: submitUrl,
method: 'POST',
body: externalIssue,
});
wrapper.find('StyledIntegrationLink a').simulate('click');
await tick();
wrapper.update();
wrapper.find('NavTabs li.create a').simulate('click');
wrapper.find('Input#title').simulate('change', {target: {value: 'foo'}});
wrapper.find('TextArea#description').simulate('change', {target: {value: 'bar'}});
wrapper.find('Form form').simulate('submit');
expect(request).toHaveBeenCalledWith(
submitUrl,
expect.objectContaining({
data: expect.objectContaining({
action: 'create',
title: 'foo',
description: 'bar',
groupId: group.id,
}),
})
);
});
});
describe('with an external issue linked', () => {
beforeEach(() => {
wrapper = mountWithTheme(
);
});
it('renders a link to the external issue', () => {
expect(wrapper.find('StyledIntegrationLink a').text()).toEqual(
externalIssue.displayName
);
});
it('links to the issue', () => {
expect(wrapper.find('StyledIntegrationLink').first().prop('href')).toEqual(
externalIssue.webUrl
);
});
it('renders the remove issue button', () => {
expect(wrapper.find('StyledIcon IconClose')).toHaveLength(1);
});
it('deletes a Linked Issue', () => {
const request = MockApiClient.addMockResponse({
url: `/issues/${group.id}/external-issues/${externalIssue.id}/`,
method: 'DELETE',
});
wrapper.find('StyledIcon').simulate('click');
expect(request).toHaveBeenCalled();
});
});
});