index.spec.tsx 4.8 KB

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