addCodeOwnerModal.spec.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import selectEvent from 'react-select-event';
  2. import {Repository} from 'sentry-fixture/repository';
  3. import {RepositoryProjectPathConfig} from 'sentry-fixture/repositoryProjectPathConfig';
  4. import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
  5. import {
  6. makeClosableHeader,
  7. makeCloseButton,
  8. ModalBody,
  9. ModalFooter,
  10. } from 'sentry/components/globalModal/components';
  11. import {AddCodeOwnerModal} from 'sentry/views/settings/project/projectOwnership/addCodeOwnerModal';
  12. describe('AddCodeOwnerModal', function () {
  13. const org = TestStubs.Organization({features: ['integrations-codeowners']});
  14. const project = TestStubs.Project();
  15. const integration = TestStubs.GitHubIntegration();
  16. const repo = Repository({
  17. integrationId: integration.id,
  18. id: '5',
  19. name: 'example/hello-there',
  20. });
  21. const codeMapping = RepositoryProjectPathConfig({
  22. project,
  23. repo,
  24. integration,
  25. stackRoot: 'stack/root',
  26. sourceRoot: 'source/root',
  27. });
  28. beforeEach(function () {
  29. MockApiClient.addMockResponse({
  30. url: `/organizations/${org.slug}/code-mappings/`,
  31. method: 'GET',
  32. body: [codeMapping],
  33. });
  34. MockApiClient.addMockResponse({
  35. url: `/organizations/${org.slug}/integrations/`,
  36. method: 'GET',
  37. body: [integration],
  38. });
  39. });
  40. it('renders', function () {
  41. render(
  42. <AddCodeOwnerModal
  43. Body={ModalBody}
  44. closeModal={jest.fn()}
  45. CloseButton={makeCloseButton(jest.fn())}
  46. Header={makeClosableHeader(jest.fn())}
  47. Footer={ModalFooter}
  48. organization={org}
  49. project={project}
  50. />
  51. );
  52. expect(screen.getByRole('button', {name: 'Add File'})).toBeDisabled();
  53. });
  54. it('renders codeowner file', async function () {
  55. MockApiClient.addMockResponse({
  56. url: `/organizations/${org.slug}/code-mappings/${codeMapping.id}/codeowners/`,
  57. method: 'GET',
  58. body: {html_url: 'blah', filepath: 'CODEOWNERS', raw: '* @MeredithAnya\n'},
  59. });
  60. render(
  61. <AddCodeOwnerModal
  62. Body={ModalBody}
  63. closeModal={jest.fn()}
  64. CloseButton={makeCloseButton(jest.fn())}
  65. Header={makeClosableHeader(jest.fn())}
  66. Footer={ModalFooter}
  67. organization={org}
  68. project={project}
  69. />
  70. );
  71. await selectEvent.select(screen.getByText('--'), 'example/hello-there');
  72. expect(screen.getByTestId('icon-check-mark')).toBeInTheDocument();
  73. expect(screen.getByRole('button', {name: 'Preview File'})).toHaveAttribute(
  74. 'href',
  75. 'blah'
  76. );
  77. });
  78. it('renders no codeowner file found', async function () {
  79. MockApiClient.addMockResponse({
  80. url: `/organizations/${org.slug}/code-mappings/${codeMapping.id}/codeowners/`,
  81. method: 'GET',
  82. statusCode: 404,
  83. });
  84. render(
  85. <AddCodeOwnerModal
  86. Body={ModalBody}
  87. closeModal={jest.fn()}
  88. CloseButton={makeCloseButton(jest.fn())}
  89. Header={makeClosableHeader(jest.fn())}
  90. Footer={ModalFooter}
  91. organization={org}
  92. project={project}
  93. />
  94. );
  95. await selectEvent.select(screen.getByText('--'), 'example/hello-there');
  96. expect(screen.getByText('No codeowner file found.')).toBeInTheDocument();
  97. });
  98. it('adds codeowner file', async function () {
  99. MockApiClient.addMockResponse({
  100. url: `/organizations/${org.slug}/code-mappings/${codeMapping.id}/codeowners/`,
  101. method: 'GET',
  102. body: {html_url: 'blah', filepath: 'CODEOWNERS', raw: '* @MeredithAnya\n'},
  103. });
  104. const addFileRequest = MockApiClient.addMockResponse({
  105. url: `/projects/${org.slug}/${project.slug}/codeowners/`,
  106. method: 'POST',
  107. body: {},
  108. });
  109. const handleCloseModal = jest.fn();
  110. render(
  111. <AddCodeOwnerModal
  112. Body={ModalBody}
  113. closeModal={handleCloseModal}
  114. CloseButton={makeCloseButton(jest.fn())}
  115. Header={makeClosableHeader(jest.fn())}
  116. Footer={ModalFooter}
  117. organization={org}
  118. project={project}
  119. />
  120. );
  121. await selectEvent.select(screen.getByText('--'), 'example/hello-there');
  122. await userEvent.click(screen.getByRole('button', {name: 'Add File'}));
  123. await waitFor(() => {
  124. expect(addFileRequest).toHaveBeenCalledWith(
  125. `/projects/${org.slug}/${project.slug}/codeowners/`,
  126. expect.objectContaining({
  127. data: {codeMappingId: '2', raw: '* @MeredithAnya\n'},
  128. })
  129. );
  130. });
  131. expect(handleCloseModal).toHaveBeenCalled();
  132. });
  133. });