resolve.spec.jsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import selectEvent from 'react-select-event';
  2. import {
  3. act,
  4. render,
  5. renderGlobalModal,
  6. screen,
  7. userEvent,
  8. } from 'sentry-test/reactTestingLibrary';
  9. import ResolveActions from 'sentry/components/actions/resolve';
  10. import ModalStore from 'sentry/stores/modalStore';
  11. describe('ResolveActions', function () {
  12. const spy = jest.fn();
  13. beforeEach(() => {
  14. ModalStore.reset();
  15. });
  16. afterEach(() => {
  17. spy.mockClear();
  18. MockApiClient.clearMockResponses();
  19. ModalStore.teardown();
  20. });
  21. describe('disabled', function () {
  22. it('does not call onUpdate when clicked', function () {
  23. render(
  24. <ResolveActions
  25. onUpdate={spy}
  26. disabled
  27. hasRelease={false}
  28. orgSlug="org-1"
  29. projectSlug="proj-1"
  30. />
  31. );
  32. const button = screen.getByRole('button', {name: 'Resolve'});
  33. expect(button).toBeDisabled();
  34. userEvent.click(button);
  35. expect(spy).not.toHaveBeenCalled();
  36. });
  37. });
  38. describe('disableDropdown', function () {
  39. it('main button calls onUpdate when clicked and dropdown menu disabled', function () {
  40. render(
  41. <ResolveActions
  42. onUpdate={spy}
  43. disableDropdown
  44. hasRelease={false}
  45. orgSlug="org-1"
  46. projectSlug="proj-1"
  47. />
  48. );
  49. const button = screen.getByRole('button', {name: 'Resolve'});
  50. expect(button).toBeEnabled();
  51. userEvent.click(button);
  52. expect(spy).toHaveBeenCalled();
  53. // Dropdown menu is disabled
  54. expect(screen.getByRole('button', {name: 'More resolve options'})).toBeDisabled();
  55. });
  56. });
  57. describe('resolved', function () {
  58. it('calls onUpdate with unresolved status when clicked', function () {
  59. render(
  60. <ResolveActions
  61. onUpdate={spy}
  62. disabled
  63. hasRelease={false}
  64. orgSlug="org-1"
  65. projectSlug="proj-1"
  66. isResolved
  67. />
  68. );
  69. const button = screen.getByRole('button', {name: 'Unresolve'});
  70. expect(button).toBeInTheDocument();
  71. expect(button).toHaveTextContent('');
  72. userEvent.click(button);
  73. expect(spy).toHaveBeenCalledWith({status: 'unresolved'});
  74. });
  75. });
  76. describe('auto resolved', function () {
  77. it('cannot be unresolved manually', function () {
  78. render(
  79. <ResolveActions
  80. onUpdate={spy}
  81. disabled
  82. hasRelease={false}
  83. orgSlug="org-1"
  84. projectSlug="proj-1"
  85. isResolved
  86. isAutoResolved
  87. />
  88. );
  89. userEvent.click(screen.getByRole('button', {name: 'Unresolve'}));
  90. expect(spy).not.toHaveBeenCalled();
  91. });
  92. });
  93. describe('without confirmation', function () {
  94. it('calls spy with resolved status when clicked', function () {
  95. render(
  96. <ResolveActions
  97. onUpdate={spy}
  98. hasRelease={false}
  99. orgSlug="org-1"
  100. projectSlug="proj-1"
  101. />
  102. );
  103. userEvent.click(screen.getByRole('button', {name: 'Resolve'}));
  104. expect(spy).toHaveBeenCalledTimes(1);
  105. expect(spy).toHaveBeenCalledWith({status: 'resolved'});
  106. });
  107. });
  108. describe('with confirmation step', function () {
  109. it('displays confirmation modal with message provided', function () {
  110. render(
  111. <ResolveActions
  112. onUpdate={spy}
  113. hasRelease={false}
  114. orgSlug="org-1"
  115. projectSlug="proj-1"
  116. shouldConfirm
  117. confirmMessage="Are you sure???"
  118. />
  119. );
  120. renderGlobalModal();
  121. const button = screen.getByRole('button', {name: 'Resolve'});
  122. userEvent.click(button);
  123. const confirmButton = screen.getByTestId('confirm-button');
  124. expect(confirmButton).toBeInTheDocument();
  125. expect(spy).not.toHaveBeenCalled();
  126. userEvent.click(confirmButton);
  127. expect(spy).toHaveBeenCalled();
  128. });
  129. });
  130. it('can resolve in "another version"', async function () {
  131. const onUpdate = jest.fn();
  132. MockApiClient.addMockResponse({
  133. url: '/projects/org-slug/project-slug/releases/',
  134. body: [TestStubs.Release()],
  135. });
  136. render(
  137. <ResolveActions
  138. hasRelease
  139. orgSlug="org-slug"
  140. projectSlug="project-slug"
  141. onUpdate={onUpdate}
  142. />
  143. );
  144. renderGlobalModal();
  145. userEvent.click(screen.getByLabelText('More resolve options'));
  146. act(() => userEvent.click(screen.getByText('Another existing release…')));
  147. selectEvent.openMenu(screen.getByText('e.g. 1.0.4'));
  148. expect(await screen.findByText('1.2.0')).toBeInTheDocument();
  149. userEvent.click(screen.getByText('1.2.0'));
  150. userEvent.click(screen.getByRole('button', {name: 'Save Changes'}));
  151. expect(onUpdate).toHaveBeenCalledWith({
  152. status: 'resolved',
  153. statusDetails: {
  154. inRelease: 'sentry-android-shop@1.2.0',
  155. },
  156. });
  157. });
  158. });