resolve.spec.jsx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. import React from 'react';
  2. import {mountWithTheme} from 'sentry-test/enzyme';
  3. import $ from 'jquery';
  4. import ResolveActions from 'app/components/actions/resolve';
  5. describe('ResolveActions', function() {
  6. describe('disabled', function() {
  7. let component, button;
  8. const spy = jest.fn();
  9. beforeEach(function() {
  10. component = mountWithTheme(
  11. <ResolveActions
  12. onUpdate={spy}
  13. disabled
  14. hasRelease={false}
  15. orgId="org-1"
  16. projectId="proj-1"
  17. />,
  18. TestStubs.routerContext()
  19. );
  20. button = component.find('a.btn.btn-default').first();
  21. });
  22. it('has disabled prop', function() {
  23. expect(button.prop('disabled')).toBe(true);
  24. });
  25. it('does not call onUpdate when clicked', function() {
  26. button.simulate('click');
  27. expect(spy).not.toHaveBeenCalled();
  28. });
  29. });
  30. describe('disableDropdown', function() {
  31. let component, button;
  32. const spy = jest.fn();
  33. beforeEach(function() {
  34. component = mountWithTheme(
  35. <ResolveActions
  36. onUpdate={spy}
  37. disableDropdown
  38. hasRelease={false}
  39. orgId="org-1"
  40. projectId="proj-1"
  41. />,
  42. TestStubs.routerContext()
  43. );
  44. });
  45. it('main button is enabled', function() {
  46. button = component.find('ActionLink[title="Resolve"]');
  47. expect(button.prop('disabled')).toBeFalsy();
  48. });
  49. it('main button calls onUpdate when clicked', function() {
  50. button = component.find('ActionLink[title="Resolve"]');
  51. button.simulate('click');
  52. expect(spy).toHaveBeenCalled();
  53. });
  54. it('dropdown menu is disabled', function() {
  55. button = component.find('DropdownLink');
  56. expect(button.prop('disabled')).toBe(true);
  57. });
  58. });
  59. describe('resolved', function() {
  60. let component;
  61. const spy = jest.fn();
  62. beforeEach(function() {
  63. component = mountWithTheme(
  64. <ResolveActions
  65. onUpdate={spy}
  66. disabled
  67. hasRelease={false}
  68. orgId="org-1"
  69. projectId="proj-1"
  70. isResolved
  71. />,
  72. TestStubs.routerContext()
  73. );
  74. });
  75. it('displays resolved view', function() {
  76. const button = component.find('a.btn.active');
  77. expect(button).toHaveLength(1);
  78. expect(button.text()).toBe('');
  79. });
  80. it('calls onUpdate with unresolved status when clicked', function() {
  81. component.find('a.btn.active').simulate('click');
  82. expect(spy).toHaveBeenCalledWith({status: 'unresolved'});
  83. });
  84. });
  85. describe('auto resolved', function() {
  86. it('cannot be unresolved manually', function() {
  87. const spy = jest.fn();
  88. const component = mountWithTheme(
  89. <ResolveActions
  90. onUpdate={spy}
  91. disabled
  92. hasRelease={false}
  93. orgId="org-1"
  94. projectId="proj-1"
  95. isResolved
  96. isAutoResolved
  97. />,
  98. TestStubs.routerContext()
  99. );
  100. component.find('a.btn').simulate('click');
  101. expect(spy).not.toHaveBeenCalled();
  102. });
  103. });
  104. describe('without confirmation', function() {
  105. let component;
  106. const spy = jest.fn();
  107. beforeEach(function() {
  108. component = mountWithTheme(
  109. <ResolveActions
  110. onUpdate={spy}
  111. hasRelease={false}
  112. orgId="org-1"
  113. projectId="proj-1"
  114. />,
  115. TestStubs.routerContext()
  116. );
  117. });
  118. it('renders', function() {
  119. expect(component).toMatchSnapshot();
  120. });
  121. it('calls spy with resolved status when clicked', function() {
  122. const button = component.find('a.btn.btn-default').first();
  123. button.simulate('click');
  124. expect(spy).toHaveBeenCalledTimes(1);
  125. expect(spy).toHaveBeenCalledWith({status: 'resolved'});
  126. });
  127. });
  128. describe('with confirmation step', function() {
  129. let component, button;
  130. const spy = jest.fn();
  131. beforeEach(function() {
  132. component = mountWithTheme(
  133. <ResolveActions
  134. onUpdate={spy}
  135. hasRelease={false}
  136. orgId="org-1"
  137. projectId="proj-1"
  138. shouldConfirm
  139. confirmMessage="Are you sure???"
  140. />,
  141. TestStubs.routerContext()
  142. );
  143. button = component.find('a.btn.btn-default').first();
  144. });
  145. it('renders', function() {
  146. expect(component).toMatchSnapshot();
  147. });
  148. it('displays confirmation modal with message provided', function() {
  149. button.simulate('click');
  150. const modal = $(document.body).find('.modal');
  151. expect(modal.text()).toContain('Are you sure???');
  152. expect(spy).not.toHaveBeenCalled();
  153. $(document.body)
  154. .find('.modal button:contains("Resolve")')
  155. .click();
  156. expect(spy).toHaveBeenCalled();
  157. });
  158. });
  159. it('can resolve in "another version"', async function() {
  160. const onUpdate = jest.fn();
  161. MockApiClient.addMockResponse({
  162. url: '/projects/org-slug/project-slug/releases/',
  163. body: [TestStubs.Release()],
  164. });
  165. const wrapper = mountWithTheme(
  166. <ResolveActions
  167. hasRelease
  168. orgId="org-slug"
  169. projectId="project-slug"
  170. onUpdate={onUpdate}
  171. />,
  172. TestStubs.routerContext()
  173. );
  174. wrapper
  175. .find('ActionLink')
  176. .last()
  177. .simulate('click');
  178. await tick();
  179. wrapper.update();
  180. expect(wrapper.find('CustomResolutionModal Select').prop('options')).toEqual([
  181. expect.objectContaining({
  182. value: '92eccef279d966b2319f0802fa4b22b430a5f72b',
  183. label: expect.anything(),
  184. }),
  185. ]);
  186. wrapper.find('input[id="version"]').simulate('change', {target: {value: '9'}});
  187. await tick();
  188. wrapper.update();
  189. wrapper.find('input[id="version"]').simulate('keyDown', {keyCode: 13});
  190. wrapper.find('CustomResolutionModal form').simulate('submit');
  191. expect(onUpdate).toHaveBeenCalledWith({
  192. status: 'resolved',
  193. statusDetails: {
  194. inRelease: '92eccef279d966b2319f0802fa4b22b430a5f72b',
  195. },
  196. });
  197. });
  198. });