You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test-utils.tsx 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2023 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. import { waitFor } from '@testing-library/react';
  21. import React from 'react';
  22. import { Outlet, Route } from 'react-router-dom';
  23. import BranchesServiceMock from '../../api/mocks/BranchesServiceMock';
  24. import ComponentsServiceMock from '../../api/mocks/ComponentsServiceMock';
  25. import IssuesServiceMock from '../../api/mocks/IssuesServiceMock';
  26. import { mockComponent } from '../../helpers/mocks/component';
  27. import { mockCurrentUser } from '../../helpers/testMocks';
  28. import { renderApp, renderAppWithComponentContext } from '../../helpers/testReactTestingUtils';
  29. import { byLabelText, byPlaceholderText, byRole, byTestId } from '../../helpers/testSelector';
  30. import {
  31. CleanCodeAttributeCategory,
  32. SoftwareImpactSeverity,
  33. SoftwareQuality,
  34. } from '../../types/clean-code-taxonomy';
  35. import { Component } from '../../types/types';
  36. import { NoticeType } from '../../types/users';
  37. import IssuesApp from './components/IssuesApp';
  38. import { projectIssuesRoutes } from './routes';
  39. export const issuesHandler = new IssuesServiceMock();
  40. export const componentsHandler = new ComponentsServiceMock();
  41. export const branchHandler = new BranchesServiceMock();
  42. export const ui = {
  43. loading: byLabelText('loading'),
  44. issuePageHeadering: byRole('heading', { level: 1, name: 'issues.page' }),
  45. issueItemAction1: byRole('link', { name: 'Issue with no location message' }),
  46. issueItemAction2: byRole('link', { name: 'FlowIssue' }),
  47. issueItemAction3: byRole('link', { name: 'Issue on file' }),
  48. issueItemAction4: byRole('link', { name: 'Fix this' }),
  49. issueItemAction5: byRole('link', { name: 'Fix that' }),
  50. issueItemAction6: byRole('link', { name: 'Second issue' }),
  51. issueItemAction7: byRole('link', { name: 'Issue with tags' }),
  52. issueItemAction8: byRole('link', { name: 'Issue on page 2' }),
  53. issueItems: byRole('region'),
  54. issueItem1: byRole('region', { name: 'Issue with no location message' }),
  55. issueItem2: byRole('region', { name: 'FlowIssue' }),
  56. issueItem3: byRole('region', { name: 'Issue on file' }),
  57. issueItem4: byRole('region', { name: 'Fix this' }),
  58. issueItem5: byRole('region', { name: 'Fix that' }),
  59. issueItem6: byRole('region', { name: 'Second issue' }),
  60. issueItem7: byRole('region', { name: 'Issue with tags' }),
  61. issueItem8: byRole('region', { name: 'Issue on page 2' }),
  62. projectIssueItem6: byRole('button', { name: 'Second issue', exact: false }),
  63. assigneeFacet: byRole('button', { name: 'issues.facet.assignees' }),
  64. authorFacet: byRole('button', { name: 'issues.facet.authors' }),
  65. codeVariantsFacet: byRole('button', { name: 'issues.facet.codeVariants' }),
  66. creationDateFacet: byRole('button', { name: 'issues.facet.createdAt' }),
  67. languageFacet: byRole('button', { name: 'issues.facet.languages' }),
  68. projectFacet: byRole('button', { name: 'issues.facet.projects' }),
  69. resolutionFacet: byRole('button', { name: 'issues.facet.resolutions' }),
  70. ruleFacet: byRole('button', { name: 'issues.facet.rules' }),
  71. scopeFacet: byRole('button', { name: 'issues.facet.scopes' }),
  72. issueStatusFacet: byRole('button', { name: 'issues.facet.issueStatuses' }),
  73. tagFacet: byRole('button', { name: 'issues.facet.tags' }),
  74. typeFacet: byRole('button', { name: 'issues.facet.types' }),
  75. cleanCodeAttributeCategoryFacet: byRole('button', {
  76. name: 'issues.facet.cleanCodeAttributeCategories',
  77. }),
  78. softwareQualityFacet: byRole('button', {
  79. name: 'issues.facet.impactSoftwareQualities',
  80. }),
  81. severityFacet: byRole('button', { name: 'issues.facet.impactSeverities' }),
  82. clearCodeCategoryFacet: byTestId('clear-issues.facet.cleanCodeAttributeCategories'),
  83. clearSoftwareQualityFacet: byTestId('clear-issues.facet.impactSoftwareQualities'),
  84. clearAssigneeFacet: byTestId('clear-issues.facet.assignees'),
  85. clearAuthorFacet: byTestId('clear-issues.facet.authors'),
  86. clearCodeVariantsFacet: byTestId('clear-issues.facet.codeVariants'),
  87. clearCreationDateFacet: byTestId('clear-issues.facet.createdAt'),
  88. clearIssueTypeFacet: byTestId('clear-issues.facet.types'),
  89. clearProjectFacet: byTestId('clear-issues.facet.projects'),
  90. clearResolutionFacet: byTestId('clear-issues.facet.resolutions'),
  91. clearRuleFacet: byTestId('clear-issues.facet.rules'),
  92. clearScopeFacet: byTestId('clear-issues.facet.scopes'),
  93. clearSeverityFacet: byTestId('clear-issues.facet.impactSeverities'),
  94. clearIssueStatusFacet: byTestId('clear-issues.facet.issueStatuses'),
  95. clearTagFacet: byTestId('clear-issues.facet.tags'),
  96. responsibleCategoryFilter: byRole('checkbox', {
  97. name: `issue.clean_code_attribute_category.${CleanCodeAttributeCategory.Responsible}`,
  98. }),
  99. consistentCategoryFilter: byRole('checkbox', {
  100. name: `issue.clean_code_attribute_category.${CleanCodeAttributeCategory.Consistent}`,
  101. }),
  102. softwareQualityMaintainabilityFilter: byRole('checkbox', {
  103. name: `software_quality.${SoftwareQuality.Maintainability}`,
  104. }),
  105. codeSmellIssueTypeFilter: byRole('checkbox', { name: 'issue.type.CODE_SMELL' }),
  106. confirmedStatusFilter: byRole('checkbox', { name: 'issue.issue_status.CONFIRMED' }),
  107. fixedResolutionFilter: byRole('checkbox', { name: 'issue.resolution.FIXED' }),
  108. mainScopeFilter: byRole('checkbox', { name: 'issue.scope.MAIN' }),
  109. mediumSeverityFilter: byRole('checkbox', { name: `severity.${SoftwareImpactSeverity.Medium}` }),
  110. openStatusFilter: byRole('checkbox', { name: 'issue.issue_status.OPEN' }),
  111. vulnerabilityIssueTypeFilter: byRole('checkbox', { name: 'issue.type.VULNERABILITY' }),
  112. bulkChangeComment: byRole('textbox', { name: /issue_bulk_change.resolution_comment/ }),
  113. clearAllFilters: byRole('button', { name: 'clear_all_filters' }),
  114. dateInputMonthSelect: byTestId('month-select'),
  115. dateInputYearSelect: byTestId('year-select'),
  116. authorFacetSearch: byPlaceholderText('search.search_for_authors'),
  117. inNewCodeFilter: byRole('checkbox', { name: 'issues.new_code' }),
  118. languageFacetList: byRole('group', { name: 'issues.facet.languages' }),
  119. ruleFacetList: byRole('group', { name: 'issues.facet.rules' }),
  120. ruleFacetSearch: byPlaceholderText('search.search_for_rules'),
  121. tagFacetSearch: byPlaceholderText('search.search_for_tags'),
  122. guidePopup: byRole('alertdialog'),
  123. };
  124. export async function waitOnDataLoaded() {
  125. await waitFor(() => {
  126. expect(ui.loading.query()).not.toBeInTheDocument();
  127. });
  128. }
  129. export function renderIssueApp(
  130. currentUser = mockCurrentUser({ dismissedNotices: { [NoticeType.ISSUE_GUIDE]: true } }),
  131. ) {
  132. renderApp('issues', <IssuesApp />, { currentUser });
  133. }
  134. export function renderProjectIssuesApp(
  135. navigateTo?: string,
  136. overrides?: Partial<Component>,
  137. currentUser = mockCurrentUser({ dismissedNotices: { [NoticeType.ISSUE_GUIDE]: true } }),
  138. ) {
  139. renderAppWithComponentContext(
  140. 'project/issues',
  141. () => (
  142. <Route
  143. element={
  144. <div data-guiding-id="issue-5">
  145. <Outlet />
  146. </div>
  147. }
  148. >
  149. {projectIssuesRoutes()}
  150. </Route>
  151. ),
  152. { navigateTo, currentUser },
  153. { component: mockComponent(overrides) },
  154. );
  155. }