repositoryRow.spec.jsx 6.9 KB

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