resolve.spec.jsx 4.8 KB

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