repositoryRow.spec.jsx 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. import {
  2. render,
  3. renderGlobalModal,
  4. screen,
  5. userEvent,
  6. } from 'sentry-test/reactTestingLibrary';
  7. import {Client} from 'sentry/api';
  8. import RepositoryRow from 'sentry/components/repositoryRow';
  9. describe('RepositoryRow', function () {
  10. beforeEach(function () {
  11. Client.clearMockResponses();
  12. });
  13. const repository = TestStubs.Repository();
  14. const pendingRepo = TestStubs.Repository({
  15. status: 'pending_deletion',
  16. });
  17. const customRepo = TestStubs.Repository({
  18. provider: {
  19. id: 'integrations:custom_scm',
  20. },
  21. });
  22. const customPendingRepo = TestStubs.Repository({
  23. provider: {
  24. id: 'integrations:custom_scm',
  25. },
  26. status: 'pending_deletion',
  27. });
  28. const api = new Client();
  29. describe('rendering with access', function () {
  30. const organization = TestStubs.Organization({
  31. access: ['org:integrations'],
  32. });
  33. const routerContext = TestStubs.routerContext([{organization}]);
  34. it('displays provider information', function () {
  35. render(
  36. <RepositoryRow
  37. repository={repository}
  38. api={api}
  39. orgId={organization.slug}
  40. organization={organization}
  41. />,
  42. {context: routerContext}
  43. );
  44. expect(screen.getByText(repository.name)).toBeInTheDocument();
  45. expect(screen.getByText('github.com/example/repo-name')).toBeInTheDocument();
  46. // Trash button should display enabled
  47. expect(screen.getByRole('button', {name: 'delete'})).toBeEnabled();
  48. // No cancel button
  49. expect(screen.queryByRole('button', {name: 'Cancel'})).not.toBeInTheDocument();
  50. });
  51. it('displays cancel pending button', function () {
  52. render(
  53. <RepositoryRow
  54. repository={pendingRepo}
  55. api={api}
  56. orgId={organization.slug}
  57. organization={organization}
  58. />,
  59. {context: routerContext}
  60. );
  61. // Trash button should be disabled
  62. expect(screen.getByRole('button', {name: 'delete'})).toBeDisabled();
  63. // Cancel button active
  64. expect(screen.getByRole('button', {name: 'Cancel'})).toBeInTheDocument();
  65. expect(screen.getByRole('button', {name: 'Cancel'})).toBeEnabled();
  66. });
  67. });
  68. describe('rendering without access', function () {
  69. const organization = TestStubs.Organization({
  70. access: ['org:write'],
  71. });
  72. const routerContext = TestStubs.routerContext([{organization}]);
  73. it('displays disabled trash', function () {
  74. render(
  75. <RepositoryRow
  76. repository={repository}
  77. api={api}
  78. orgId={organization.slug}
  79. organization={organization}
  80. />,
  81. {context: routerContext}
  82. );
  83. // Trash button should be disabled
  84. expect(screen.getByRole('button', {name: 'delete'})).toBeDisabled();
  85. });
  86. it('displays disabled cancel', function () {
  87. render(
  88. <RepositoryRow
  89. repository={pendingRepo}
  90. api={api}
  91. orgId={organization.slug}
  92. organization={organization}
  93. />,
  94. {context: routerContext}
  95. );
  96. // Cancel should be disabled
  97. expect(screen.getByRole('button', {name: 'Cancel'})).toBeDisabled();
  98. });
  99. });
  100. describe('deletion', function () {
  101. const organization = TestStubs.Organization({
  102. access: ['org:integrations'],
  103. });
  104. const routerContext = TestStubs.routerContext([{organization}]);
  105. it('sends api request on delete', function () {
  106. const deleteRepo = Client.addMockResponse({
  107. url: `/organizations/${organization.slug}/repos/${repository.id}/`,
  108. method: 'DELETE',
  109. statusCode: 204,
  110. body: {},
  111. });
  112. render(
  113. <RepositoryRow
  114. repository={repository}
  115. api={api}
  116. orgId={organization.slug}
  117. organization={organization}
  118. />,
  119. {context: routerContext}
  120. );
  121. renderGlobalModal();
  122. userEvent.click(screen.getByRole('button', {name: 'delete'}));
  123. // Confirm modal
  124. userEvent.click(screen.getByRole('button', {name: 'Confirm'}));
  125. expect(deleteRepo).toHaveBeenCalled();
  126. });
  127. });
  128. describe('cancel deletion', function () {
  129. const organization = TestStubs.Organization({
  130. access: ['org:integrations'],
  131. });
  132. const routerContext = TestStubs.routerContext([{organization}]);
  133. it('sends api request to cancel', function () {
  134. const cancel = Client.addMockResponse({
  135. url: `/organizations/${organization.slug}/repos/${pendingRepo.id}/`,
  136. method: 'PUT',
  137. statusCode: 204,
  138. body: {},
  139. });
  140. render(
  141. <RepositoryRow
  142. repository={pendingRepo}
  143. api={api}
  144. orgId={organization.slug}
  145. organization={organization}
  146. />,
  147. {context: routerContext}
  148. );
  149. userEvent.click(screen.getByRole('button', {name: 'Cancel'}));
  150. expect(cancel).toHaveBeenCalled();
  151. });
  152. });
  153. describe('renders custom_scm repo', function () {
  154. const organization = TestStubs.Organization({
  155. access: ['org:integrations'],
  156. features: ['integrations-custom-scm'],
  157. });
  158. const routerContext = TestStubs.routerContext([{organization}]);
  159. it('displays edit button', function () {
  160. render(
  161. <RepositoryRow
  162. repository={customRepo}
  163. api={api}
  164. orgId={organization.slug}
  165. organization={organization}
  166. />,
  167. {context: routerContext}
  168. );
  169. // Trash button should display enabled
  170. expect(screen.getByRole('button', {name: 'delete'})).toBeEnabled();
  171. // No cancel button
  172. expect(screen.queryByRole('button', {name: 'Cancel'})).not.toBeInTheDocument();
  173. // Edit button should display enabled
  174. expect(screen.getByRole('button', {name: 'edit'})).toBeEnabled();
  175. });
  176. it('disables edit button when cancel pending', function () {
  177. render(
  178. <RepositoryRow
  179. repository={customPendingRepo}
  180. api={api}
  181. orgId={organization.slug}
  182. organization={organization}
  183. />,
  184. {context: routerContext}
  185. );
  186. // Trash button should be disabled
  187. expect(screen.getByRole('button', {name: 'delete'})).toBeDisabled();
  188. // Edit button should be disabled
  189. expect(screen.getByRole('button', {name: 'edit'})).toBeDisabled();
  190. // Cancel button active
  191. expect(screen.queryByRole('button', {name: 'Cancel'})).toBeEnabled();
  192. });
  193. });
  194. });