addCodeOwnerModal.spec.tsx 4.3 KB

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