index.spec.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import {GitHubIntegrationConfigFixture} from 'sentry-fixture/integrationListDirectory';
  2. import {OrganizationFixture} from 'sentry-fixture/organization';
  3. import {RouterContextFixture} from 'sentry-fixture/routerContextFixture';
  4. import {initializeOrg} from 'sentry-test/initializeOrg';
  5. import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
  6. import {openModal} from 'sentry/actionCreators/modal';
  7. import ProjectOwnership from 'sentry/views/settings/project/projectOwnership';
  8. jest.mock('sentry/actionCreators/modal');
  9. describe('Project Ownership', () => {
  10. const {organization, project, routerProps} = initializeOrg();
  11. beforeEach(() => {
  12. MockApiClient.addMockResponse({
  13. url: `/projects/${organization.slug}/${project.slug}/ownership/`,
  14. method: 'GET',
  15. body: {
  16. fallthrough: false,
  17. autoAssignment: 'Auto Assign to Suspect Commits',
  18. codeownersAutoSync: false,
  19. },
  20. });
  21. MockApiClient.addMockResponse({
  22. url: `/organizations/${organization.slug}/code-mappings/?project=${project.id}`,
  23. method: 'GET',
  24. body: [],
  25. });
  26. MockApiClient.addMockResponse({
  27. url: `/organizations/${organization.slug}/integrations/?features=codeowners`,
  28. method: 'GET',
  29. body: [GitHubIntegrationConfigFixture()],
  30. });
  31. MockApiClient.addMockResponse({
  32. url: `/projects/${organization.slug}/${project.slug}/codeowners/`,
  33. method: 'GET',
  34. body: [],
  35. });
  36. });
  37. afterEach(() => {
  38. MockApiClient.clearMockResponses();
  39. });
  40. describe('without codeowners', () => {
  41. it('renders', async () => {
  42. render(
  43. <ProjectOwnership
  44. {...routerProps}
  45. params={{projectId: project.slug}}
  46. organization={organization}
  47. project={project}
  48. />
  49. );
  50. expect(await screen.findByText('No ownership rules found')).toBeInTheDocument();
  51. // Does not render codeowners for orgs without 'integrations-codeowners' feature
  52. expect(
  53. screen.queryByRole('button', {name: 'Add CODEOWNERS'})
  54. ).not.toBeInTheDocument();
  55. });
  56. it('renders allows users to edit ownership rules', async () => {
  57. render(
  58. <ProjectOwnership
  59. {...routerProps}
  60. params={{projectId: project.slug}}
  61. organization={organization}
  62. project={project}
  63. />,
  64. {organization: OrganizationFixture({access: ['project:read']})}
  65. );
  66. expect(await screen.findByTestId('project-permission-alert')).toBeInTheDocument();
  67. expect(screen.queryByRole('button', {name: 'Edit Rules'})).toBeEnabled();
  68. // eslint-disable-next-line jest-dom/prefer-in-document
  69. expect(screen.getAllByTestId('project-permission-alert')).toHaveLength(1);
  70. });
  71. });
  72. describe('with codeowners', () => {
  73. it('codeowners button opens modal', async () => {
  74. const org = OrganizationFixture({
  75. features: ['integrations-codeowners'],
  76. access: ['org:integrations'],
  77. });
  78. render(
  79. <ProjectOwnership
  80. {...routerProps}
  81. params={{projectId: project.slug}}
  82. organization={org}
  83. project={project}
  84. />,
  85. {context: RouterContextFixture([{organization: org}])}
  86. );
  87. // Renders button
  88. expect(
  89. await screen.findByRole('button', {name: 'Import CODEOWNERS'})
  90. ).toBeInTheDocument();
  91. // Opens modal
  92. await userEvent.click(screen.getByRole('button', {name: 'Import CODEOWNERS'}));
  93. expect(openModal).toHaveBeenCalled();
  94. });
  95. });
  96. describe('issue owners settings', () => {
  97. it('should set autoAssignment with commit-context string', async () => {
  98. const updateOwnership = MockApiClient.addMockResponse({
  99. url: `/projects/${organization.slug}/${project.slug}/ownership/`,
  100. method: 'PUT',
  101. body: {
  102. fallthrough: false,
  103. autoAssignment: 'Assign To Issue Owner',
  104. codeownersAutoSync: false,
  105. },
  106. });
  107. render(
  108. <ProjectOwnership
  109. {...routerProps}
  110. params={{projectId: project.slug}}
  111. organization={organization}
  112. project={project}
  113. />
  114. );
  115. // Switch to Assign To Issue Owner
  116. await userEvent.click(await screen.findByText('Auto-assign to suspect commits'));
  117. await userEvent.click(screen.getByText('Auto-assign to issue owner'));
  118. await waitFor(() => {
  119. expect(updateOwnership).toHaveBeenCalledWith(
  120. expect.anything(),
  121. expect.objectContaining({
  122. data: {
  123. autoAssignment: 'Auto Assign to Issue Owner',
  124. },
  125. })
  126. );
  127. });
  128. });
  129. });
  130. });