ticketRuleModal.spec.jsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import fetchMock from 'jest-fetch-mock';
  2. import {mountWithTheme} from 'sentry-test/enzyme';
  3. import {initializeOrg} from 'sentry-test/initializeOrg';
  4. import {selectByQuery, selectByValue} from 'sentry-test/select-new';
  5. import TicketRuleModal from 'sentry/views/alerts/rules/issue/ticketRuleModal';
  6. jest.unmock('sentry/utils/recreateRoute');
  7. jest.mock('sentry/actionCreators/onboardingTasks');
  8. describe('ProjectAlerts -> TicketRuleModal', function () {
  9. const closeModal = jest.fn();
  10. const modalElements = {
  11. Header: p => p.children,
  12. Body: p => p.children,
  13. Footer: p => p.children,
  14. };
  15. beforeEach(function () {
  16. fetchMock.enableMocks();
  17. fetch.resetMocks();
  18. });
  19. afterEach(function () {
  20. closeModal.mockReset();
  21. MockApiClient.clearMockResponses();
  22. });
  23. const _submit = wrapper => {
  24. wrapper.find('Button[data-test-id="form-submit"]').simulate('submit');
  25. return wrapper.find('FieldErrorReason');
  26. };
  27. const submitSuccess = wrapper => {
  28. const errors = _submit(wrapper);
  29. expect(errors).toHaveLength(0);
  30. expect(closeModal).toHaveBeenCalled();
  31. };
  32. const submitErrors = (wrapper, errorCount) => {
  33. const errors = _submit(wrapper);
  34. expect(errors).toHaveLength(errorCount);
  35. expect(errors.first().text()).toEqual('Field is required');
  36. expect(closeModal).toHaveBeenCalledTimes(0);
  37. };
  38. const addMockConfigsAPICall = (otherFields = {}) => {
  39. return MockApiClient.addMockResponse({
  40. url: '/organizations/org-slug/integrations/1/?ignored=Sprint',
  41. method: 'GET',
  42. body: {
  43. createIssueConfig: [
  44. {
  45. name: 'project',
  46. label: 'Jira Project',
  47. choices: [['10000', 'TEST']],
  48. default: '10000',
  49. type: 'select',
  50. updatesForm: true,
  51. },
  52. {
  53. name: 'issuetype',
  54. label: 'Issue Type',
  55. default: '10001',
  56. type: 'select',
  57. choices: [
  58. ['10001', 'Improvement'],
  59. ['10002', 'Task'],
  60. ['10003', 'Sub-task'],
  61. ['10004', 'New Feature'],
  62. ['10005', 'Bug'],
  63. ['10000', 'Epic'],
  64. ],
  65. updatesForm: true,
  66. required: true,
  67. },
  68. otherFields,
  69. ],
  70. },
  71. });
  72. };
  73. /**
  74. * We need to use this alternate mocking scheme because `fetch` isn't available.
  75. * @param names String[]
  76. */
  77. const addMockUsersAPICall = (names = []) => {
  78. fetch.mockResponseOnce(
  79. JSON.stringify(
  80. names.map(name => {
  81. return {
  82. label: name,
  83. value: name,
  84. };
  85. })
  86. )
  87. );
  88. };
  89. const createWrapper = (props = {}) => {
  90. const {organization, routerContext} = initializeOrg(props);
  91. addMockConfigsAPICall({
  92. label: 'Reporter',
  93. required: true,
  94. choices: [['a', 'a']],
  95. type: 'select',
  96. name: 'reporter',
  97. });
  98. return mountWithTheme(
  99. <TicketRuleModal
  100. {...modalElements}
  101. closeModal={closeModal}
  102. formFields={{}}
  103. link=""
  104. ticketType=""
  105. instance={{...(props.data || {}), integration: 1}}
  106. index={0}
  107. onSubmitAction={() => {}}
  108. organization={organization}
  109. />,
  110. routerContext
  111. );
  112. };
  113. describe('Create Rule', function () {
  114. it('should render the Ticket Rule modal', function () {
  115. const wrapper = createWrapper();
  116. expect(wrapper.find('Button[data-test-id="form-submit"]').text()).toEqual(
  117. 'Apply Changes'
  118. );
  119. const formFields = wrapper.find('FormField');
  120. expect(formFields.at(0).text()).toEqual('Title');
  121. expect(formFields.at(1).text()).toEqual('Description');
  122. });
  123. it('should save the modal data when "Apply Changes" is clicked with valid data', function () {
  124. const wrapper = createWrapper();
  125. selectByValue(wrapper, 'a', {name: 'reporter'});
  126. submitSuccess(wrapper);
  127. });
  128. it('should raise validation errors when "Apply Changes" is clicked with invalid data', function () {
  129. // This doesn't test anything TicketRules specific but I'm leaving it here as an example.
  130. const wrapper = createWrapper();
  131. submitErrors(wrapper, 1);
  132. });
  133. it('should reload fields when an "updatesForm" field changes', function () {
  134. const wrapper = createWrapper();
  135. selectByValue(wrapper, 'a', {name: 'reporter'});
  136. addMockConfigsAPICall({
  137. label: 'Assignee',
  138. required: true,
  139. choices: [['b', 'b']],
  140. type: 'select',
  141. name: 'assignee',
  142. });
  143. selectByValue(wrapper, '10000', {name: 'issuetype'});
  144. selectByValue(wrapper, 'b', {name: 'assignee'});
  145. submitSuccess(wrapper);
  146. });
  147. it('should persist values when the modal is reopened', function () {
  148. const wrapper = createWrapper({data: {reporter: 'a'}});
  149. submitSuccess(wrapper);
  150. });
  151. it('should get async options from URL', async function () {
  152. const wrapper = createWrapper();
  153. addMockConfigsAPICall({
  154. label: 'Assignee',
  155. required: true,
  156. url: 'http://example.com',
  157. type: 'select',
  158. name: 'assignee',
  159. });
  160. selectByValue(wrapper, '10000', {name: 'issuetype'});
  161. addMockUsersAPICall(['Marcos']);
  162. await selectByQuery(wrapper, 'Marcos', {name: 'assignee'});
  163. submitSuccess(wrapper);
  164. });
  165. });
  166. });