repositoryRow.spec.tsx 5.9 KB

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