]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-20023 Create required types for the issues page's new taxonomy
author7PH <benjamin.raymond@sonarsource.com>
Wed, 26 Jul 2023 12:43:46 +0000 (14:43 +0200)
committersonartech <sonartech@sonarsource.com>
Fri, 18 Aug 2023 20:02:47 +0000 (20:02 +0000)
Co-authored-by: Stanislav <31501873+stanislavhh@users.noreply.github.com>
server/sonar-web/src/main/js/api/issues.ts
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineIssueList-test.tsx.snap
server/sonar-web/src/main/js/components/SourceViewer/helpers/__tests__/__snapshots__/loadIssues-test.ts.snap
server/sonar-web/src/main/js/helpers/issues.ts
server/sonar-web/src/main/js/helpers/testMocks.ts
server/sonar-web/src/main/js/types/issues.ts
server/sonar-web/src/main/js/types/types.ts
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 23e47c35d88ae1fb4a800f734e4ed9fc8d104c47..e1996afbdf50e509b3ea5c07d9036776612b45dc 100644 (file)
@@ -52,6 +52,10 @@ type FacetName =
   | 'types';
 
 export function searchIssues(query: RequestData): Promise<RawIssuesResponse> {
+  // TODO: Remove this before final merge. Needed because backend sends an error
+  if (query.facets) {
+    query.facets = query.facets.replace(/cleanCodeAttributes/, '').replace(/impacts/, '');
+  }
   return getJSON('/api/issues/search', query).catch(throwGlobalError);
 }
 
index 9a03583ab365acc048b99a0111308359e6ffdd58..4f776d6e497355f377fd4f2a0b900909bb00d8a5 100644 (file)
@@ -17,6 +17,8 @@ exports[`should render issues 1`] = `
     issue={
       {
         "actions": [],
+        "cleanCodeAttribute": "RESPECTFUL",
+        "cleanCodeAttributeCategory": "RESPONSIBLE",
         "component": "main.js",
         "componentEnabled": true,
         "componentLongName": "main.js",
@@ -25,6 +27,12 @@ exports[`should render issues 1`] = `
         "creationDate": "2017-03-01T09:36:01+0100",
         "flows": [],
         "flowsWithType": [],
+        "impacts": [
+          {
+            "severity": "MEDIUM",
+            "softwareQuality": "MAINTAINABILITY",
+          },
+        ],
         "key": "issue",
         "line": 25,
         "message": "Reduce the number of conditional operators (4) used in the expression",
index 20f82563531fea9887f908f27f43505ed7e63a12..698b7a9aab13de611a6456876e53934597f41323 100644 (file)
@@ -10,6 +10,8 @@ exports[`loadIssues should load issues with listIssues if re-indexing 1`] = `
     ],
     "assignee": "luke",
     "author": "luke@sonarsource.com",
+    "cleanCodeAttribute": "LAWFUL",
+    "cleanCodeAttributeCategory": "RESPONSIBLE",
     "comments": [],
     "component": "foo.java",
     "componentEnabled": true,
@@ -22,6 +24,12 @@ exports[`loadIssues should load issues with listIssues if re-indexing 1`] = `
     "flows": [],
     "flowsWithType": [],
     "hash": "78417dcee7ba927b7e7c9161e29e02b8",
+    "impacts": [
+      {
+        "severity": "HIGH",
+        "softwareQuality": "MAINTAINABILITY",
+      },
+    ],
     "key": "AWaqVGl3tut9VbnJvk6M",
     "line": 62,
     "message": "Make sure this file handling is safe here.",
@@ -67,6 +75,8 @@ exports[`loadIssues should load issues with searchIssues if not re-indexing 1`]
     "assigneeLogin": "luke",
     "assigneeName": "Luke",
     "author": "luke@sonarsource.com",
+    "cleanCodeAttribute": "LAWFUL",
+    "cleanCodeAttributeCategory": "RESPONSIBLE",
     "comments": [],
     "component": "foo.java",
     "componentEnabled": true,
@@ -79,6 +89,12 @@ exports[`loadIssues should load issues with searchIssues if not re-indexing 1`]
     "flows": [],
     "flowsWithType": [],
     "hash": "78417dcee7ba927b7e7c9161e29e02b8",
+    "impacts": [
+      {
+        "severity": "HIGH",
+        "softwareQuality": "MAINTAINABILITY",
+      },
+    ],
     "key": "AWaqVGl3tut9VbnJvk6M",
     "line": 62,
     "message": "Make sure this file handling is safe here.",
index 7572276d6c4e0f1eea8b04e78af95a254cf09620..eaf21e703c37b728ebb0bf83bf86e970a0ed01ff 100644 (file)
  */
 import { BugIcon, CodeSmellIcon, SecurityHotspotIcon, VulnerabilityIcon } from 'design-system';
 import { flatten, sortBy } from 'lodash';
-import { IssueType, RawIssue } from '../types/issues';
+import {
+  CleanCodeAttribute,
+  CleanCodeAttributeCategory,
+  IssueType,
+  RawIssue,
+  SoftwareImpactSeverity,
+  SoftwareQuality,
+} from '../types/issues';
 import { MetricKey } from '../types/metrics';
 import { Dict, Flow, FlowLocation, FlowType, Issue, TextRange } from '../types/types';
 import { UserBase } from '../types/users';
@@ -160,6 +167,15 @@ export function parseIssueFromResponse(
     ...splitFlows(issue, components),
     ...prepareClosed(issue),
     ...ensureTextRange(issue),
+    cleanCodeAttributeCategory:
+      issue.cleanCodeAttributeCategory || CleanCodeAttributeCategory.Responsible,
+    cleanCodeAttribute: issue.cleanCodeAttribute || CleanCodeAttribute.Lawful,
+    impacts: issue.impacts || [
+      {
+        softwareQuality: SoftwareQuality.Maintainability,
+        severity: SoftwareImpactSeverity.High,
+      },
+    ],
   } as Issue;
 }
 
index 474e43af88143a6fc0350dafc74381203f85e211..5c59fb9e9f573a60d55465d2e6abc469a32e1698 100644 (file)
@@ -26,7 +26,17 @@ import { Location, Router } from '../components/hoc/withRouter';
 import { AppState } from '../types/appstate';
 import { RuleRepository } from '../types/coding-rules';
 import { EditionKey } from '../types/editions';
-import { IssueScope, IssueSeverity, IssueStatus, IssueType, RawIssue } from '../types/issues';
+import {
+  CleanCodeAttribute,
+  CleanCodeAttributeCategory,
+  IssueScope,
+  IssueSeverity,
+  IssueStatus,
+  IssueType,
+  RawIssue,
+  SoftwareImpactSeverity,
+  SoftwareQuality,
+} from '../types/issues';
 import { Language } from '../types/languages';
 import { Notification } from '../types/notifications';
 import { DumpStatus, DumpTask } from '../types/project-dump';
@@ -302,6 +312,11 @@ export function mockRawIssue(withLocations = false, overrides: Partial<RawIssue>
     type: IssueType.CodeSmell,
     transitions: [],
     scope: IssueScope.Main,
+    cleanCodeAttributeCategory: CleanCodeAttributeCategory.Responsible,
+    cleanCodeAttribute: CleanCodeAttribute.Respectful,
+    impacts: [
+      { softwareQuality: SoftwareQuality.Maintainability, severity: SoftwareImpactSeverity.Medium },
+    ],
     ...overrides,
   };
 
@@ -350,6 +365,11 @@ export function mockIssue(withLocations = false, overrides: Partial<Issue> = {})
     textRange: { startLine: 25, endLine: 26, startOffset: 0, endOffset: 15 },
     transitions: [],
     type: 'BUG',
+    cleanCodeAttributeCategory: CleanCodeAttributeCategory.Responsible,
+    cleanCodeAttribute: CleanCodeAttribute.Respectful,
+    impacts: [
+      { softwareQuality: SoftwareQuality.Maintainability, severity: SoftwareImpactSeverity.Medium },
+    ],
   };
 
   const loc = mockFlowLocation;
index 57ce60737e1f297dc57ba12383137434c49b123c..bfc40585d858aa60dd51c72d287a13a536e341e0 100644 (file)
@@ -30,6 +30,12 @@ export enum IssueType {
 }
 
 // Keep this enum in the correct order (most severe to least severe).
+export enum SoftwareImpactSeverity {
+  High = 'HIGH',
+  Medium = 'MEDIUM',
+  Low = 'LOW',
+}
+
 export enum IssueSeverity {
   Blocker = 'BLOCKER',
   Critical = 'CRITICAL',
@@ -38,6 +44,38 @@ export enum IssueSeverity {
   Info = 'INFO',
 }
 
+export enum CleanCodeAttributeCategory {
+  Consistent = 'CONSISTENT',
+  Intentional = 'INTENTIONAL',
+  Adaptable = 'ADAPTABLE',
+  Responsible = 'RESPONSIBLE',
+  Unclassified = 'UNCLASSIFIED',
+}
+
+export enum CleanCodeAttribute {
+  Clear = 'CLEAR',
+  Complete = 'COMPLETE',
+  Conventional = 'CONVENTIONAL',
+  Distinct = 'DISTINCT',
+  Efficient = 'EFFICIENT',
+  Focused = 'FOCUSED',
+  Formatted = 'FORMATTED',
+  Identifiable = 'IDENTIFIABLE',
+  Lawful = 'LAWFUL',
+  Logical = 'LOGICAL',
+  Modular = 'MODULAR',
+  Respectful = 'RESPECTFUL',
+  Tested = 'TESTED',
+  Trustworthy = 'TRUSTWORTHY',
+  Unclassified = 'UNCLASSIFIED',
+}
+
+export enum SoftwareQuality {
+  Security = 'SECURITY',
+  Reliability = 'RELIABILITY',
+  Maintainability = 'MAINTAINABILITY',
+}
+
 export enum IssueScope {
   Main = 'MAIN',
   Test = 'TEST',
@@ -109,6 +147,12 @@ export interface RawIssue {
   tags?: string[];
   assignee?: string;
   author?: string;
+  cleanCodeAttributeCategory: CleanCodeAttributeCategory;
+  cleanCodeAttribute: CleanCodeAttribute;
+  impacts: Array<{
+    softwareQuality: SoftwareQuality;
+    severity: SoftwareImpactSeverity;
+  }>;
   codeVariants?: string[];
   comments?: Comment[];
   creationDate: string;
index b0ca6302af15b07848d1615eae923ed1593838e9..ee999308d9083a212dc1ad1d1b584b22e0b3b302 100644 (file)
  */
 import { RuleDescriptionSection } from '../apps/coding-rules/rule';
 import { ComponentQualifier, Visibility } from './component';
-import { MessageFormatting } from './issues';
+import {
+  CleanCodeAttribute,
+  CleanCodeAttributeCategory,
+  MessageFormatting,
+  SoftwareImpactSeverity,
+  SoftwareQuality,
+} from './issues';
 import { NewCodeDefinitionType } from './new-code-definition';
 import { UserActive, UserBase } from './users';
 
@@ -247,6 +253,12 @@ export interface Issue {
   assigneeName?: string;
   author?: string;
   branch?: string;
+  cleanCodeAttributeCategory: CleanCodeAttributeCategory;
+  cleanCodeAttribute: CleanCodeAttribute;
+  impacts: Array<{
+    softwareQuality: SoftwareQuality;
+    severity: SoftwareImpactSeverity;
+  }>;
   codeVariants?: string[];
   comments?: IssueComment[];
   component: string;
index eda63d5a5996da05dd7a95999a6c30255cd86e78..a99857b87f40a4513f78fb188261c8501d533c06 100644 (file)
@@ -964,6 +964,33 @@ issue.type.BUG.plural=Bugs
 issue.type.VULNERABILITY.plural=Vulnerabilities
 issue.type.SECURITY_HOTSPOT.plural=Security Hotspots
 
+issue.software_quality.SECURITY=Security
+issue.software_quality.RELIABILITY=Reliability
+issue.software_quality.MAINTAINABILITY=Maintainability
+
+
+issue.clean_code_attribute_category.CONSISTENCY=Consistency
+issue.clean_code_attribute_category.INTENTIONALITY=Intentionality
+issue.clean_code_attribute_category.ADAPTABILITY=Adaptability
+issue.clean_code_attribute_category.RESPONSABILITY=Responsability
+issue.clean_code_attribute_category.UNCLASSIFIED=Unclassified
+
+issue.clean_code_attribute.CLEAR=Clear
+issue.clean_code_attribute.COMPLETE=Complete
+issue.clean_code_attribute.CONVENTIONAL=Conventional
+issue.clean_code_attribute.DISTINCT=Distinct
+issue.clean_code_attribute.EFFICIENT=Efficient
+issue.clean_code_attribute.FOCUSED=Focused
+issue.clean_code_attribute.FORMATTED=Formatted
+issue.clean_code_attribute.IDENTIFIABLE=Identifiable
+issue.clean_code_attribute.LAWFUL=Lawful
+issue.clean_code_attribute.LOGICAL=Logical
+issue.clean_code_attribute.MODULAR=Modular
+issue.clean_code_attribute.RESPECTFUL=Respectful
+issue.clean_code_attribute.TESTED=Tested
+issue.clean_code_attribute.TRUSTWORTHY=Trustworthy
+issue.clean_code_attribute.UNCLASSIFIED=Unclassified
+
 issue.status.REOPENED=Reopened
 issue.status.RESOLVED=Resolved
 issue.status.OPEN=Open
@@ -2454,6 +2481,14 @@ severity.MINOR.description=Potential for moderate to minor impact.
 severity.INFO=Info
 severity.INFO.description=Neither a bug nor a quality flaw. Just a finding.
 
+# New severities
+severity.HIGH=High
+severity.HIGH.description=Must be fixed immediately.
+severity.MEDIUM=Medium
+severity.MEDIUM.description=High potential for significant to moderate impact.
+severity.LOW=Low
+severity.LOW.description=Potential for moderate to minor impact.
+
 #------------------------------------------------------------------------------
 #
 # METRIC DOMAINS