aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDejan Milisavljevic <130993898+dejan-milisavljevic-sonarsource@users.noreply.github.com>2024-09-18 14:03:50 +0200
committersonartech <sonartech@sonarsource.com>2024-09-18 20:02:59 +0000
commite55e29f6e2632c1eef4db2d659e685a50caa10a6 (patch)
treec178331b8d79e523a9c3bdbbc82f611781413dbc
parent7fe4eae27f3b725ea08c79d5a0373596200a1627 (diff)
downloadsonarqube-e55e29f6e2632c1eef4db2d659e685a50caa10a6.tar.gz
sonarqube-e55e29f6e2632c1eef4db2d659e685a50caa10a6.zip
SONAR-22951 Use 5 levels severities for Software Impact
Co-authored-by: Léo Geoffroy <leo.geoffroy@sonarsource.com> Co-authored-by: Stanislav <31501873+stanislavhh@users.noreply.github.com> Co-authored-by: Viktor Vorona <viktor.vorona@sonarsource.com> Co-authored-by: OrlovAlexander <35396155+OrlovAlexander85@users.noreply.github.com> Co-authored-by: stanislavh <stanislav.honcharov@sonarsource.com>
-rw-r--r--gradle.properties2
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java6
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java4
-rw-r--r--server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStepIT.java3
-rw-r--r--server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/rule/ExportAdHocRulesStepIT.java2
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java2
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java2
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitor.java6
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitor.java6
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistLiveMeasuresStep.java1
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/protobuf/project_dump.proto2
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java50
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java2
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java9
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java42
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitorTest.java69
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java36
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitorTest.java75
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java2
-rw-r--r--server/sonar-server-common/src/it/java/org/sonar/server/issue/index/IssueIndexerIT.java10
-rw-r--r--server/sonar-server-common/src/it/java/org/sonar/server/rule/index/RuleIndexIT.java107
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/measure/DebtRatingGrid.java11
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/measure/ImpactMeasureBuilder.java17
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/measure/Rating.java4
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/measure/index/ProjectMeasuresSoftwareQualityRatingsInitializer.java6
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityReviewRating.java10
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/measure/DebtRatingGridTest.java15
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/measure/ImpactMeasureBuilderTest.java86
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/measure/index/ProjectMeasuresSoftwareQualityRatingsInitializerTest.java36
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityReviewRatingTest.java25
-rw-r--r--server/sonar-web/config/jest/SetupReactTestingLibrary.ts33
-rw-r--r--server/sonar-web/design-system/src/components/ColorsLegend.tsx4
-rw-r--r--server/sonar-web/design-system/src/components/FacetBox.tsx66
-rw-r--r--server/sonar-web/design-system/src/components/Pill.tsx33
-rw-r--r--server/sonar-web/design-system/src/components/__tests__/Pill-test.tsx4
-rw-r--r--server/sonar-web/design-system/src/components/__tests__/__snapshots__/HotspotRating-test.tsx.snap2
-rw-r--r--server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityBlockerIcon.tsx43
-rw-r--r--server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityHighIcon.tsx4
-rw-r--r--server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityInfoIcon.tsx46
-rw-r--r--server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityLowIcon.tsx4
-rw-r--r--server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityMediumIcon.tsx4
-rw-r--r--server/sonar-web/design-system/src/components/icons/index.ts2
-rw-r--r--server/sonar-web/design-system/src/components/index.ts2
-rw-r--r--server/sonar-web/design-system/src/sonar-aligned/components/MetricsRatingBadge.tsx11
-rw-r--r--server/sonar-web/design-system/src/theme/light.ts89
-rw-r--r--server/sonar-web/src/main/js/app/components/ChangeInCalculationPill.tsx8
-rw-r--r--server/sonar-web/src/main/js/app/components/metrics/RatingComponent.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/code/__tests__/__snapshots__/utils-test.tsx.snap12
-rw-r--r--server/sonar-web/src/main/js/apps/code/components/CodeAppRenderer.tsx9
-rw-r--r--server/sonar-web/src/main/js/apps/code/utils.ts4
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/__tests__/CodingRules-it.ts2
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/__tests__/CustomRule-it.ts6
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/AttributeCategoryFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormFieldsCCT.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/FacetsList.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/InheritanceFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/PrioritizedRulesFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/RepositoryFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/SoftwareQualityFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/StatusFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/TagFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/TemplateFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/TypeFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/components/MeasureContent.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/drilldown/BubbleChartView.tsx12
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/drilldown/ColorRatingsLegend.tsx9
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/drilldown/TreeMapView.tsx20
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/utils.ts6
-rw-r--r--server/sonar-web/src/main/js/apps/issues/__tests__/IssueHeader-it.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/SeverityFacet.tsx69
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/Sidebar.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/Sidebar-it.tsx16
-rw-r--r--server/sonar-web/src/main/js/apps/issues/test-utils.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/overview/branches/OverallCodeMeasuresPanel.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureBreakdownCard.tsx131
-rw-r--r--server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureCard.tsx33
-rw-r--r--server/sonar-web/src/main/js/apps/overview/branches/__tests__/BranchOverview-it.tsx53
-rw-r--r--server/sonar-web/src/main/js/apps/overview/branches/test-utils.ts54
-rw-r--r--server/sonar-web/src/main/js/apps/overview/utils.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityApp-it.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx16
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/project-card/__tests__/ProjectCard-test.tsx27
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/RatingFacet.tsx29
-rw-r--r--server/sonar-web/src/main/js/apps/projects/utils.ts7
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionModal.tsx2
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/GraphHistory.tsx3
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/GraphsHistory.tsx5
-rw-r--r--server/sonar-web/src/main/js/components/charts/AdvancedTimeline.tsx6
-rw-r--r--server/sonar-web/src/main/js/components/charts/__tests__/AdvancedTimeline-test.tsx14
-rw-r--r--server/sonar-web/src/main/js/components/charts/__tests__/__snapshots__/AdvancedTimeline-test.tsx.snap500
-rw-r--r--server/sonar-web/src/main/js/components/facets/Facet.tsx (renamed from server/sonar-web/src/main/js/apps/coding-rules/components/Facet.tsx)17
-rw-r--r--server/sonar-web/src/main/js/components/facets/SeverityFacet.tsx (renamed from server/sonar-web/src/main/js/apps/coding-rules/components/SeverityFacet.tsx)48
-rw-r--r--server/sonar-web/src/main/js/components/icon-mappers/SoftwareImpactSeverityIcon.tsx15
-rw-r--r--server/sonar-web/src/main/js/components/measure/utils.ts1
-rw-r--r--server/sonar-web/src/main/js/components/shared/CleanCodeAttributePill.tsx52
-rw-r--r--server/sonar-web/src/main/js/components/shared/SoftwareImpactPill.tsx68
-rw-r--r--server/sonar-web/src/main/js/components/shared/SoftwareImpactPillList.tsx8
-rw-r--r--server/sonar-web/src/main/js/helpers/activity-graph.ts5
-rw-r--r--server/sonar-web/src/main/js/helpers/constants.ts21
-rw-r--r--server/sonar-web/src/main/js/sonar-aligned/types/metrics.ts9
-rw-r--r--server/sonar-web/src/main/js/types/clean-code-taxonomy.ts4
-rw-r--r--server/sonar-web/src/main/js/types/jest.d.ts1
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java44
-rw-r--r--server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java74
-rw-r--r--server/sonar-webserver-es/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java27
-rw-r--r--server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/enums/ImpactSeverityRestEnum.java4
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SearchProjectsActionIT.java22
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ListActionIT.java13
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/PullTaintActionIT.java8
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java256
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/CreateActionIT.java10
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/SearchActionIT.java5
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ImpactFormatter.java38
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseFormat.java3
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/pull/PullTaintActionProtobufObjectGenerator.java3
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java25
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java2
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleMapper.java3
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ImpactFormatterTest.java38
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImplTest.java264
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/MeasuresWsModuleTest.java4
-rw-r--r--sonar-core/src/main/java/org/sonar/core/metric/SoftwareQualitiesMetrics.java42
-rw-r--r--sonar-core/src/main/java/org/sonar/core/util/ProtobufJsonFormat.java17
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties71
-rw-r--r--sonar-core/src/test/java/org/sonar/core/metric/SoftwareQualitiesMetricsTest.java2
-rw-r--r--sonar-core/src/test/java/org/sonar/core/util/ProtobufJsonFormatTest.java15
-rw-r--r--sonar-core/src/test/protobuf/test.proto1
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java9
-rw-r--r--sonar-ws/src/main/protobuf/ws-commons.proto3
130 files changed, 1466 insertions, 1910 deletions
diff --git a/gradle.properties b/gradle.properties
index 435bf57a80c..fe52ff22787 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,7 +6,7 @@ version=10.7
# 30 months from the release date for LTA versions
# No change required for patch versions
versionEOL=2025-03-27
-pluginApiVersion=10.10.0.2391
+pluginApiVersion=10.11.0.2468
description=Open source platform for continuous inspection of code quality
projectTitle=SonarQube
org.gradle.jvmargs=-Xmx2048m
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
index 9110916977d..9ca57ae518d 100644
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
@@ -96,14 +96,16 @@ public class OneIssuePerLineSensor implements Sensor {
return null;
}
switch (severity) {
- case CRITICAL:
case BLOCKER:
+ return org.sonar.api.issue.impact.Severity.BLOCKER;
+ case CRITICAL:
return org.sonar.api.issue.impact.Severity.HIGH;
case MAJOR:
return org.sonar.api.issue.impact.Severity.MEDIUM;
case MINOR:
- case INFO:
return org.sonar.api.issue.impact.Severity.LOW;
+ case INFO:
+ return org.sonar.api.issue.impact.Severity.INFO;
default:
return null;
}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java
index 6468f7ef0d9..4dbd8085f62 100644
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java
@@ -127,7 +127,7 @@ public class XooRulesDefinition implements RulesDefinition {
NewRule oneIssuePerLine = repo.createRule(OneIssuePerLineSensor.RULE_KEY).setName("One Issue Per Line")
.setCleanCodeAttribute(CleanCodeAttribute.COMPLETE)
- .addDefaultImpact(SoftwareQuality.MAINTAINABILITY, Severity.MEDIUM)
+ .addDefaultImpact(SoftwareQuality.MAINTAINABILITY, Severity.INFO)
.setTags("line");
addDescriptionSectionsWithoutContexts(oneIssuePerLine, "Generate an issue on each line of a file. It requires the metric \"lines\".");
addHowToFixSectionsWithContexts(oneIssuePerLine);
@@ -138,7 +138,7 @@ public class XooRulesDefinition implements RulesDefinition {
NewRule oneQuickFixPerLine = repo.createRule(OneQuickFixPerLineSensor.RULE_KEY).setName("One Quick Fix Per Line")
.setCleanCodeAttribute(CleanCodeAttribute.DISTINCT)
- .addDefaultImpact(SoftwareQuality.MAINTAINABILITY, Severity.MEDIUM)
+ .addDefaultImpact(SoftwareQuality.MAINTAINABILITY, Severity.BLOCKER)
.setTags("line");
addAllDescriptionSections(oneQuickFixPerLine,
"Generate an issue with quick fix available on each line of a file. It requires the metric \"lines\".");
diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStepIT.java
index 3feed4fa16e..3dae30abdb8 100644
--- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStepIT.java
+++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStepIT.java
@@ -233,6 +233,7 @@ public class ExportIssuesStepIT {
.setIssueCreationTime(963L)
.setIssueUpdateTime(852L)
.addImpact(new ImpactDto().setSoftwareQuality(SoftwareQuality.MAINTAINABILITY).setSeverity(Severity.HIGH))
+ .addImpact(new ImpactDto().setSoftwareQuality(SoftwareQuality.SECURITY).setSeverity(Severity.BLOCKER))
.setIssueCloseTime(741L)
.setCodeVariants(List.of("v1", "v2"));
@@ -270,7 +271,7 @@ public class ExportIssuesStepIT {
assertThat(issue.getIssueClosedAt()).isEqualTo(issueDto.getIssueCloseTime());
assertThat(issue.getLocations()).isNotEmpty();
assertThat(issue.getImpactsList()).extracting(ProjectDump.Impact::getSoftwareQuality, ProjectDump.Impact::getSeverity)
- .containsOnly(tuple(ProjectDump.SoftwareQuality.MAINTAINABILITY, ProjectDump.Severity.HIGH));
+ .containsOnly(tuple(ProjectDump.SoftwareQuality.MAINTAINABILITY, ProjectDump.Severity.HIGH), tuple(ProjectDump.SoftwareQuality.SECURITY, ProjectDump.Severity.BLOCKER));
assertThat(issue.getMessageFormattingsList())
.isEqualTo(ExportIssuesStep.dbToDumpMessageFormatting(messageFormattings.getMessageFormattingList()));
assertThat(issue.getCodeVariants()).isEqualTo(issueDto.getCodeVariantsString());
diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/rule/ExportAdHocRulesStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/rule/ExportAdHocRulesStepIT.java
index 0d1ac24b094..94e6af5c4cf 100644
--- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/rule/ExportAdHocRulesStepIT.java
+++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/rule/ExportAdHocRulesStepIT.java
@@ -207,7 +207,7 @@ public class ExportAdHocRulesStepIT {
.setIsAdHoc(true)
.setCleanCodeAttribute(CleanCodeAttribute.CONVENTIONAL)
.addDefaultImpact(new ImpactDto().setSoftwareQuality(SoftwareQuality.MAINTAINABILITY).setSeverity(org.sonar.api.issue.impact.Severity.MEDIUM))
- .addDefaultImpact(new ImpactDto().setSoftwareQuality(SoftwareQuality.RELIABILITY).setSeverity(org.sonar.api.issue.impact.Severity.HIGH))
+ .addDefaultImpact(new ImpactDto().setSoftwareQuality(SoftwareQuality.RELIABILITY).setSeverity(org.sonar.api.issue.impact.Severity.BLOCKER))
.setRuleKey(ruleKey)
.setScope(RuleDto.Scope.ALL)
.setStatus(RuleStatus.READY);
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java
index 32b15ebaaca..bf7aedad8c2 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java
@@ -157,7 +157,7 @@ public class MaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<Main
}
private void addSoftwareQualityMaintainabilityRatingMeasure(Component component, double density) {
- Rating rating = ratingSettings.getDebtRatingGrid().getAToDRatingForDensity(density);
+ Rating rating = ratingSettings.getDebtRatingGrid().getRatingForDensity(density);
measureRepository.add(component, softwareQualityMaintainabilityRatingMetric, RatingMeasures.get(rating));
}
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java
index f39acc0c7d2..39ac9561d1c 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java
@@ -131,7 +131,7 @@ public class NewMaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<N
double densityBasedOnSoftwareQuality = computeDensity(path.current().getNewSoftwareQualityDebt(), path.current().getDevCost());
double newSoftwareQualityDebtRatio = 100.0 * densityBasedOnSoftwareQuality;
- int newSoftwareQualityMaintainabilityRating = ratingSettings.getDebtRatingGrid().getAToDRatingForDensity(densityBasedOnSoftwareQuality).getIndex();
+ int newSoftwareQualityMaintainabilityRating = ratingSettings.getDebtRatingGrid().getRatingForDensity(densityBasedOnSoftwareQuality).getIndex();
measureRepository.add(component, this.newSoftwareQualityMaintainabilityDebtRatioMetric, newMeasureBuilder().create(newSoftwareQualityDebtRatio));
measureRepository.add(component, this.newSoftwareQualityMaintainabilityRatingMetric, newMeasureBuilder().create(newSoftwareQualityMaintainabilityRating));
}
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitor.java
index e1b92e9b8fb..a6c3a5b32bd 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitor.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitor.java
@@ -36,8 +36,6 @@ import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_REVIEW_RATING_KEY;
import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT;
import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.POST_ORDER;
import static org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit.FILE;
-import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY;
-import static org.sonar.server.security.SecurityReviewRating.computeAToDRating;
import static org.sonar.server.security.SecurityReviewRating.computePercent;
import static org.sonar.server.security.SecurityReviewRating.computeRating;
@@ -46,7 +44,6 @@ public class NewSecurityReviewMeasuresVisitor extends PathAwareVisitorAdapter<Se
private final ComponentIssuesRepository componentIssuesRepository;
private final MeasureRepository measureRepository;
private final Metric newSecurityReviewRatingMetric;
- private final Metric newSoftwareQualitySecurityReviewRatingMetric;
private final Metric newSecurityHotspotsReviewedMetric;
private final Metric newSecurityHotspotsReviewedStatusMetric;
private final Metric newSecurityHotspotsToReviewStatusMetric;
@@ -58,7 +55,6 @@ public class NewSecurityReviewMeasuresVisitor extends PathAwareVisitorAdapter<Se
this.componentIssuesRepository = componentIssuesRepository;
this.measureRepository = measureRepository;
this.newSecurityReviewRatingMetric = metricRepository.getByKey(NEW_SECURITY_REVIEW_RATING_KEY);
- this.newSoftwareQualitySecurityReviewRatingMetric = metricRepository.getByKey(NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY);
this.newSecurityHotspotsReviewedMetric = metricRepository.getByKey(NEW_SECURITY_HOTSPOTS_REVIEWED_KEY);
this.newSecurityHotspotsReviewedStatusMetric = metricRepository.getByKey(NEW_SECURITY_HOTSPOTS_REVIEWED_STATUS_KEY);
this.newSecurityHotspotsToReviewStatusMetric = metricRepository.getByKey(NEW_SECURITY_HOTSPOTS_TO_REVIEW_STATUS_KEY);
@@ -96,8 +92,6 @@ public class NewSecurityReviewMeasuresVisitor extends PathAwareVisitorAdapter<Se
Optional<Double> percent = computePercent(path.current().getHotspotsToReview(), path.current().getHotspotsReviewed());
measureRepository.add(component, newSecurityReviewRatingMetric, Measure.newMeasureBuilder().create(computeRating(percent.orElse(null)).getIndex()));
- measureRepository.add(component, newSoftwareQualitySecurityReviewRatingMetric,
- Measure.newMeasureBuilder().create(computeAToDRating(percent.orElse(null)).getIndex()));
percent.ifPresent(p -> measureRepository.add(component, newSecurityHotspotsReviewedMetric, Measure.newMeasureBuilder().create(p)));
if (!path.isRoot()) {
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitor.java
index df9029b0328..c8e8ec02fc0 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitor.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitor.java
@@ -37,8 +37,6 @@ import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT;
import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.POST_ORDER;
import static org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit.FILE;
import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder;
-import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY;
-import static org.sonar.server.security.SecurityReviewRating.computeAToDRating;
import static org.sonar.server.security.SecurityReviewRating.computePercent;
import static org.sonar.server.security.SecurityReviewRating.computeRating;
@@ -47,7 +45,6 @@ public class SecurityReviewMeasuresVisitor extends PathAwareVisitorAdapter<Secur
private final ComponentIssuesRepository componentIssuesRepository;
private final MeasureRepository measureRepository;
private final Metric securityReviewRatingMetric;
- private final Metric softwareQualitySecurityReviewRatingMetric;
private final Metric securityHotspotsReviewedMetric;
private final Metric securityHotspotsReviewedStatusMetric;
private final Metric securityHotspotsToReviewStatusMetric;
@@ -57,7 +54,6 @@ public class SecurityReviewMeasuresVisitor extends PathAwareVisitorAdapter<Secur
this.componentIssuesRepository = componentIssuesRepository;
this.measureRepository = measureRepository;
this.securityReviewRatingMetric = metricRepository.getByKey(SECURITY_REVIEW_RATING_KEY);
- this.softwareQualitySecurityReviewRatingMetric = metricRepository.getByKey(SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY);
this.securityHotspotsReviewedMetric = metricRepository.getByKey(SECURITY_HOTSPOTS_REVIEWED_KEY);
this.securityHotspotsReviewedStatusMetric = metricRepository.getByKey(SECURITY_HOTSPOTS_REVIEWED_STATUS_KEY);
this.securityHotspotsToReviewStatusMetric = metricRepository.getByKey(SECURITY_HOTSPOTS_TO_REVIEW_STATUS_KEY);
@@ -88,8 +84,6 @@ public class SecurityReviewMeasuresVisitor extends PathAwareVisitorAdapter<Secur
measureRepository.add(component, securityHotspotsToReviewStatusMetric, newMeasureBuilder().create(path.current().getHotspotsToReview()));
Optional<Double> percent = computePercent(path.current().getHotspotsToReview(), path.current().getHotspotsReviewed());
measureRepository.add(component, securityReviewRatingMetric, RatingMeasures.get(computeRating(percent.orElse(null))));
- measureRepository.add(component, softwareQualitySecurityReviewRatingMetric,
- RatingMeasures.get(computeAToDRating(percent.orElse(null))));
percent.ifPresent(p -> measureRepository.add(component, securityHotspotsReviewedMetric, newMeasureBuilder().create(p, securityHotspotsReviewedMetric.getDecimalScale())));
if (!path.isRoot()) {
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistLiveMeasuresStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistLiveMeasuresStep.java
index 7ec45800832..42497ea5066 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistLiveMeasuresStep.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistLiveMeasuresStep.java
@@ -114,7 +114,6 @@ public class PersistLiveMeasuresStep implements ComputationStep {
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING_KEY,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING_KEY,
- SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY,
SoftwareQualitiesMetrics.EFFORT_TO_REACH_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_A_KEY,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY,
diff --git a/server/sonar-ce-task-projectanalysis/src/main/protobuf/project_dump.proto b/server/sonar-ce-task-projectanalysis/src/main/protobuf/project_dump.proto
index d1e3782b7f1..114fdda60f4 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/protobuf/project_dump.proto
+++ b/server/sonar-ce-task-projectanalysis/src/main/protobuf/project_dump.proto
@@ -253,4 +253,6 @@ enum Severity {
LOW = 0;
MEDIUM = 1;
HIGH = 2;
+ INFO = 3;
+ BLOCKER = 4;
}
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java
index 7ad66ed9b40..f47a6da5495 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java
@@ -126,6 +126,7 @@ import static org.sonar.ce.task.projectanalysis.issue.IssueCounter.IMPACT_TO_MET
import static org.sonar.ce.task.projectanalysis.issue.IssueCounter.IMPACT_TO_NEW_METRIC_KEY;
import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder;
import static org.sonar.ce.task.projectanalysis.measure.MeasureRepoEntry.entryOf;
+import static org.sonar.test.JsonAssert.assertJson;
class IssueCounterTest {
@@ -316,9 +317,11 @@ class IssueCounterTest {
underTest.beforeComponent(PROJECT);
underTest.afterComponent(PROJECT);
- assertIntValue(FILE1, entry(NEW_VIOLATIONS_KEY, 2), entry(NEW_CRITICAL_VIOLATIONS_KEY, 2), entry(NEW_BLOCKER_VIOLATIONS_KEY, 0), entry(NEW_MAJOR_VIOLATIONS_KEY, 0),
+ assertIntValue(FILE1, entry(NEW_VIOLATIONS_KEY, 2), entry(NEW_CRITICAL_VIOLATIONS_KEY, 2), entry(NEW_BLOCKER_VIOLATIONS_KEY, 0),
+ entry(NEW_MAJOR_VIOLATIONS_KEY, 0),
entry(NEW_CODE_SMELLS_KEY, 1), entry(NEW_BUGS_KEY, 1), entry(NEW_VULNERABILITIES_KEY, 0), entry(NEW_SECURITY_HOTSPOTS_KEY, 1));
- assertIntValue(PROJECT, entry(NEW_VIOLATIONS_KEY, 2), entry(NEW_CRITICAL_VIOLATIONS_KEY, 2), entry(NEW_BLOCKER_VIOLATIONS_KEY, 0), entry(NEW_MAJOR_VIOLATIONS_KEY, 0),
+ assertIntValue(PROJECT, entry(NEW_VIOLATIONS_KEY, 2), entry(NEW_CRITICAL_VIOLATIONS_KEY, 2), entry(NEW_BLOCKER_VIOLATIONS_KEY, 0),
+ entry(NEW_MAJOR_VIOLATIONS_KEY, 0),
entry(NEW_CODE_SMELLS_KEY, 1), entry(NEW_BUGS_KEY, 1), entry(NEW_VULNERABILITIES_KEY, 0), entry(NEW_SECURITY_HOTSPOTS_KEY, 1));
}
@@ -350,14 +353,14 @@ class IssueCounterTest {
when(newIssueClassifier.isEnabled()).thenReturn(true);
underTest.beforeComponent(FILE1);
- underTest.onIssue(FILE1, createIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.MAINTAINABILITY, HIGH));
+ underTest.onIssue(FILE1, createIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.MAINTAINABILITY, HIGH));
underTest.onIssue(FILE1, createIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.MAINTAINABILITY, MEDIUM));
underTest.onIssue(FILE1, createNewIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.MAINTAINABILITY, HIGH));
underTest.onIssue(FILE1, createNewIssue(RESOLUTION_WONT_FIX, STATUS_RESOLVED, SoftwareQuality.MAINTAINABILITY, HIGH));
underTest.onIssue(FILE1, createNewIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.MAINTAINABILITY, MEDIUM));
- underTest.onIssue(FILE1, createIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.SECURITY, HIGH));
+ underTest.onIssue(FILE1, createIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.SECURITY, HIGH));
underTest.onIssue(FILE1, createIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.SECURITY, MEDIUM));
underTest.onIssue(FILE1, createNewSecurityHotspot());
@@ -368,9 +371,9 @@ class IssueCounterTest {
Set<Map.Entry<String, Measure>> entries = measureRepository.getRawMeasures(FILE1).entrySet();
- assertOverallSoftwareQualityMeasures(SoftwareQuality.MAINTAINABILITY, getImpactMeasure(4, 2, 2, 0), entries);
- assertOverallSoftwareQualityMeasures(SoftwareQuality.SECURITY, getImpactMeasure(2, 1, 1, 0), entries);
- assertOverallSoftwareQualityMeasures(SoftwareQuality.RELIABILITY, getImpactMeasure(0, 0, 0, 0), entries);
+ assertOverallSoftwareQualityMeasures(SoftwareQuality.MAINTAINABILITY, getImpactMeasure(4, 2, 2, 0, 0, 0), entries);
+ assertOverallSoftwareQualityMeasures(SoftwareQuality.SECURITY, getImpactMeasure(2, 1, 1, 0, 0, 0), entries);
+ assertOverallSoftwareQualityMeasures(SoftwareQuality.RELIABILITY, getImpactMeasure(0, 0, 0, 0, 0, 0), entries);
}
@Test
@@ -378,17 +381,17 @@ class IssueCounterTest {
when(newIssueClassifier.isEnabled()).thenReturn(true);
underTest.beforeComponent(FILE1);
- underTest.onIssue(FILE1, createIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.MAINTAINABILITY, HIGH));
+ underTest.onIssue(FILE1, createIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.MAINTAINABILITY, HIGH));
underTest.onIssue(FILE1, createNewIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.MAINTAINABILITY, HIGH));
underTest.onIssue(FILE1, createNewIssue(RESOLUTION_WONT_FIX, STATUS_RESOLVED, SoftwareQuality.MAINTAINABILITY, HIGH));
underTest.onIssue(FILE1, createNewIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.MAINTAINABILITY, MEDIUM));
- underTest.onIssue(FILE1, createIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.RELIABILITY, HIGH));
+ underTest.onIssue(FILE1, createIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.RELIABILITY, HIGH));
underTest.onIssue(FILE1, createNewIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.RELIABILITY, LOW));
underTest.onIssue(FILE1, createNewIssue(RESOLUTION_WONT_FIX, STATUS_RESOLVED, SoftwareQuality.RELIABILITY, HIGH));
underTest.onIssue(FILE1, createNewIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.RELIABILITY, MEDIUM));
- underTest.onIssue(FILE1, createIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.SECURITY, MEDIUM));
+ underTest.onIssue(FILE1, createIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.SECURITY, MEDIUM));
underTest.onIssue(FILE1, createNewIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.SECURITY, LOW));
underTest.onIssue(FILE1, createNewIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.SECURITY, HIGH));
underTest.onIssue(FILE1, createNewIssue(RESOLUTION_WONT_FIX, STATUS_OPEN, SoftwareQuality.SECURITY, HIGH));
@@ -402,9 +405,9 @@ class IssueCounterTest {
Set<Map.Entry<String, Measure>> entries = measureRepository.getRawMeasures(FILE1).entrySet();
- assertNewSoftwareQualityMeasures(SoftwareQuality.MAINTAINABILITY, getImpactMeasure(2, 1, 1, 0), entries);
- assertNewSoftwareQualityMeasures(SoftwareQuality.RELIABILITY, getImpactMeasure(2, 0, 1, 1), entries);
- assertNewSoftwareQualityMeasures(SoftwareQuality.SECURITY, getImpactMeasure(4, 2, 1, 1), entries);
+ assertNewSoftwareQualityMeasures(SoftwareQuality.MAINTAINABILITY, getImpactMeasure(2, 1, 1, 0, 0, 0), entries);
+ assertNewSoftwareQualityMeasures(SoftwareQuality.RELIABILITY, getImpactMeasure(2, 0, 1, 1, 0, 0), entries);
+ assertNewSoftwareQualityMeasures(SoftwareQuality.SECURITY, getImpactMeasure(4, 2, 1, 1, 0, 0), entries);
}
private static Map<String, Long> getImpactMeasure(long total, long high, long medium, long low) {
@@ -416,6 +419,13 @@ class IssueCounterTest {
return map;
}
+ private static Map<String, Long> getImpactMeasure(long total, long high, long medium, long low, long info, long blocker) {
+ Map<String, Long> map = getImpactMeasure(total, high, medium, low);
+ map.put(Severity.INFO.name(), info);
+ map.put(Severity.BLOCKER.name(), blocker);
+ return map;
+ }
+
private void assertOverallSoftwareQualityMeasures(SoftwareQuality softwareQuality, Map<? extends String, Long> expectedMap,
Set<Map.Entry<String, Measure>> actualRaw) {
assertSoftwareQualityMeasures(softwareQuality, expectedMap, actualRaw, IMPACT_TO_METRIC_KEY);
@@ -434,7 +444,7 @@ class IssueCounterTest {
.findFirst()
.get();
- assertThat(softwareQualityMap.getValue().getData()).isEqualTo(new Gson().toJson(expectedMap));
+ assertJson(softwareQualityMap.getValue().getData()).isSimilarTo(new Gson().toJson(expectedMap));
}
@Test
@@ -513,9 +523,11 @@ class IssueCounterTest {
underTest.beforeComponent(PROJECT);
underTest.afterComponent(PROJECT);
- assertIntValue(FILE1, entry(NEW_VIOLATIONS_KEY, 0), entry(NEW_CRITICAL_VIOLATIONS_KEY, 0), entry(NEW_BLOCKER_VIOLATIONS_KEY, 0), entry(NEW_MAJOR_VIOLATIONS_KEY, 0),
+ assertIntValue(FILE1, entry(NEW_VIOLATIONS_KEY, 0), entry(NEW_CRITICAL_VIOLATIONS_KEY, 0), entry(NEW_BLOCKER_VIOLATIONS_KEY, 0),
+ entry(NEW_MAJOR_VIOLATIONS_KEY, 0),
entry(NEW_VULNERABILITIES_KEY, 0));
- assertIntValue(PROJECT, entry(NEW_VIOLATIONS_KEY, 0), entry(NEW_CRITICAL_VIOLATIONS_KEY, 0), entry(NEW_BLOCKER_VIOLATIONS_KEY, 0), entry(NEW_MAJOR_VIOLATIONS_KEY, 0),
+ assertIntValue(PROJECT, entry(NEW_VIOLATIONS_KEY, 0), entry(NEW_CRITICAL_VIOLATIONS_KEY, 0), entry(NEW_BLOCKER_VIOLATIONS_KEY, 0),
+ entry(NEW_MAJOR_VIOLATIONS_KEY, 0),
entry(NEW_VULNERABILITIES_KEY, 0));
}
@@ -546,7 +558,8 @@ class IssueCounterTest {
return createNewIssue(resolution, status, SoftwareQuality.MAINTAINABILITY, impactSeverity);
}
- private DefaultIssue createNewIssue(@Nullable String resolution, String status, SoftwareQuality softwareQuality, Severity impactSeverity) {
+ private DefaultIssue createNewIssue(@Nullable String resolution, String status, SoftwareQuality softwareQuality,
+ Severity impactSeverity) {
DefaultIssue issue = createNewIssue(resolution, status, MAJOR, CODE_SMELL);
issue.addImpact(softwareQuality, impactSeverity);
return issue;
@@ -566,7 +579,8 @@ class IssueCounterTest {
return createIssue(resolution, status, SoftwareQuality.MAINTAINABILITY, impactSeverity);
}
- private static DefaultIssue createIssue(@Nullable String resolution, String status, SoftwareQuality softwareQuality, Severity impactSeverity) {
+ private static DefaultIssue createIssue(@Nullable String resolution, String status, SoftwareQuality softwareQuality,
+ Severity impactSeverity) {
DefaultIssue issue = createIssue(resolution, status, MAJOR, CODE_SMELL);
issue.addImpact(softwareQuality, impactSeverity);
return issue;
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java
index e2741c6a5da..25779ab5480 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java
@@ -279,7 +279,7 @@ class MaintainabilityMeasuresVisitorTest {
verifyAddedRawMeasure(FILE_1_REF, SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, C);
verifyAddedRawMeasure(FILE_2_REF, SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, A);
verifyAddedRawMeasure(DIRECTORY_REF, SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, C);
- verifyAddedRawMeasure(PROJECT_REF, SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, D);
+ verifyAddedRawMeasure(PROJECT_REF, SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, E);
}
@ParameterizedTest
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java
index 19415757cec..ad891b15259 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java
@@ -358,7 +358,7 @@ public class NewMaintainabilityMeasuresVisitorTest {
@ParameterizedTest
@MethodSource("metrics")
- void compute_new_maintainability_rating_map_to_D(String remediationEffortKey, String debtRatioKey, String ratingKey) {
+ void compute_new_maintainability_rating_map_to_E(String remediationEffortKey, String debtRatioKey, String ratingKey) {
ReportComponent file = builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY, 1)).build();
treeRootHolder.setRoot(
builder(PROJECT, ROOT_REF)
@@ -375,12 +375,7 @@ public class NewMaintainabilityMeasuresVisitorTest {
setNewLines(file, 3, 4);
underTest.visit(treeRootHolder.getRoot());
-
- if (ratingKey.equals(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY)) {
- assertNewRating(ratingKey, LANGUAGE_1_FILE_REF, D);
- } else if (ratingKey.equals(NEW_MAINTAINABILITY_RATING_KEY)) {
- assertNewRating(ratingKey, LANGUAGE_1_FILE_REF, E);
- }
+ assertNewRating(ratingKey, LANGUAGE_1_FILE_REF, E);
}
@Test
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java
index f2d94abce7a..48eba3a7541 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java
@@ -186,7 +186,7 @@ class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
oldImpactIssue(SoftwareQuality.SECURITY, Severity.HIGH));
fillComponentIssuesVisitorRule.setIssues(FILE_2_REF,
newImpactIssue(SoftwareQuality.SECURITY, Severity.LOW),
- newImpactIssue(SoftwareQuality.SECURITY, Severity.HIGH),
+ newImpactIssue(SoftwareQuality.SECURITY, Severity.BLOCKER),
// Should not be taken into account
oldImpactIssue(SoftwareQuality.SECURITY, Severity.HIGH));
fillComponentIssuesVisitorRule.setIssues(ROOT_DIR_REF, newImpactIssue(SoftwareQuality.SECURITY, Severity.HIGH));
@@ -194,10 +194,10 @@ class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
verifyAddedRawMeasureOnLeakPeriod(FILE_1_REF, NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, C);
- verifyAddedRawMeasureOnLeakPeriod(FILE_2_REF, NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, D);
- verifyAddedRawMeasureOnLeakPeriod(DIRECTORY_REF, NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, D);
- verifyAddedRawMeasureOnLeakPeriod(ROOT_DIR_REF, NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, D);
- verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, D);
+ verifyAddedRawMeasureOnLeakPeriod(FILE_2_REF, NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, E);
+ verifyAddedRawMeasureOnLeakPeriod(DIRECTORY_REF, NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, E);
+ verifyAddedRawMeasureOnLeakPeriod(ROOT_DIR_REF, NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, E);
+ verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, E);
}
@Test
@@ -289,7 +289,7 @@ class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
// Should not be taken into account
oldImpactIssue(SoftwareQuality.RELIABILITY, Severity.HIGH));
fillComponentIssuesVisitorRule.setIssues(FILE_2_REF,
- newImpactIssue(SoftwareQuality.RELIABILITY, Severity.LOW),
+ newImpactIssue(SoftwareQuality.RELIABILITY, Severity.INFO),
newImpactIssue(SoftwareQuality.RELIABILITY, Severity.HIGH),
// Should not be taken into account
oldImpactIssue(SoftwareQuality.RELIABILITY, Severity.HIGH));
@@ -376,6 +376,21 @@ class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
}
@Test
+ void compute_E_software_quality_reliability_and_security_rating_on_blocker_severity_issue() {
+ treeRootHolder.setRoot(ROOT_PROJECT);
+ fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
+ newImpactIssue(SoftwareQuality.RELIABILITY, Severity.BLOCKER),
+ newImpactIssue(SoftwareQuality.SECURITY, Severity.BLOCKER),
+ // Should not be taken into account
+ newCodeSmellIssue(1L, MAJOR));
+
+ underTest.visit(ROOT_PROJECT);
+
+ verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, E);
+ verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, E);
+ }
+
+ @Test
void compute_D_reliability_and_security_rating_on_critical_issue() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
@@ -481,6 +496,21 @@ class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
}
@Test
+ void compute_A_software_quality_reliability_and_security_rating_on_info_severity_issue() {
+ treeRootHolder.setRoot(ROOT_PROJECT);
+ fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
+ newImpactIssue(SoftwareQuality.RELIABILITY, Severity.INFO),
+ newImpactIssue(SoftwareQuality.SECURITY, Severity.INFO),
+ // Should not be taken into account
+ newCodeSmellIssue(1L, MAJOR));
+
+ underTest.visit(ROOT_PROJECT);
+
+ verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, A);
+ verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, A);
+ }
+
+ @Test
void compute_A_software_quality_reliability_and_security_rating_when_no_issue() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitorTest.java
index 2fe66648466..83d8db3d25c 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitorTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitorTest.java
@@ -68,8 +68,6 @@ import static org.sonar.server.measure.Rating.B;
import static org.sonar.server.measure.Rating.C;
import static org.sonar.server.measure.Rating.D;
import static org.sonar.server.measure.Rating.E;
-import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING;
-import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY;
class NewSecurityReviewMeasuresVisitorTest {
private static final Offset<Double> VALUE_COMPARISON_OFFSET = Offset.offset(0.01);
@@ -98,7 +96,6 @@ class NewSecurityReviewMeasuresVisitorTest {
@RegisterExtension
private final MetricRepositoryRule metricRepository = new MetricRepositoryRule()
.add(NEW_SECURITY_REVIEW_RATING)
- .add(NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING)
.add(NEW_SECURITY_HOTSPOTS_REVIEWED)
.add(NEW_SECURITY_HOTSPOTS_REVIEWED_STATUS)
.add(NEW_SECURITY_HOTSPOTS_TO_REVIEW_STATUS);
@@ -134,11 +131,11 @@ class NewSecurityReviewMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyRatingAndReviewedMeasures(FILE_1_REF, A, A, 100.0);
- verifyRatingAndReviewedMeasures(FILE_2_REF, A, A, 100.0);
- verifyRatingAndReviewedMeasures(DIRECTORY_REF, A, A, 100.0);
- verifyRatingAndReviewedMeasures(ROOT_DIR_REF, A, A, 100.0);
- verifyRatingAndReviewedMeasures(PROJECT_REF, A, A, 100.0);
+ verifyRatingAndReviewedMeasures(FILE_1_REF, A, 100.0);
+ verifyRatingAndReviewedMeasures(FILE_2_REF, A, 100.0);
+ verifyRatingAndReviewedMeasures(DIRECTORY_REF, A, 100.0);
+ verifyRatingAndReviewedMeasures(ROOT_DIR_REF, A, 100.0);
+ verifyRatingAndReviewedMeasures(PROJECT_REF, A, 100.0);
}
@Test
@@ -163,11 +160,11 @@ class NewSecurityReviewMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyRatingAndReviewedMeasures(FILE_1_REF, A, A, 100.0);
- verifyRatingAndReviewedMeasures(FILE_2_REF, A, B, 80.0);
- verifyRatingAndReviewedMeasures(DIRECTORY_REF, A, B, 87.5);
- verifyRatingAndReviewedMeasures(ROOT_DIR_REF, A, B, 87.5);
- verifyRatingAndReviewedMeasures(PROJECT_REF, A, B, 87.5);
+ verifyRatingAndReviewedMeasures(FILE_1_REF, A, 100.0);
+ verifyRatingAndReviewedMeasures(FILE_2_REF, A, 80.0);
+ verifyRatingAndReviewedMeasures(DIRECTORY_REF, A, 87.5);
+ verifyRatingAndReviewedMeasures(ROOT_DIR_REF, A, 87.5);
+ verifyRatingAndReviewedMeasures(PROJECT_REF, A, 87.5);
}
@Test
@@ -192,11 +189,11 @@ class NewSecurityReviewMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyRatingAndReviewedMeasures(FILE_1_REF, A, A, 100.0);
- verifyRatingAndReviewedMeasures(FILE_2_REF, B, B, 71.42);
- verifyRatingAndReviewedMeasures(DIRECTORY_REF, B, B, 75.0);
- verifyRatingAndReviewedMeasures(ROOT_DIR_REF, B, B, 75.0);
- verifyRatingAndReviewedMeasures(PROJECT_REF, B, B, 75.0);
+ verifyRatingAndReviewedMeasures(FILE_1_REF, A, 100.0);
+ verifyRatingAndReviewedMeasures(FILE_2_REF, B, 71.42);
+ verifyRatingAndReviewedMeasures(DIRECTORY_REF, B, 75.0);
+ verifyRatingAndReviewedMeasures(ROOT_DIR_REF, B, 75.0);
+ verifyRatingAndReviewedMeasures(PROJECT_REF, B, 75.0);
}
@Test
@@ -220,11 +217,11 @@ class NewSecurityReviewMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyRatingAndReviewedMeasures(FILE_1_REF, C, C, 50.0);
- verifyRatingAndReviewedMeasures(FILE_2_REF, C, C, 60.0);
- verifyRatingAndReviewedMeasures(DIRECTORY_REF, C, C, 57.14);
- verifyRatingAndReviewedMeasures(ROOT_DIR_REF, C, C, 57.14);
- verifyRatingAndReviewedMeasures(PROJECT_REF, C, C, 57.14);
+ verifyRatingAndReviewedMeasures(FILE_1_REF, C, 50.0);
+ verifyRatingAndReviewedMeasures(FILE_2_REF, C, 60.0);
+ verifyRatingAndReviewedMeasures(DIRECTORY_REF, C, 57.14);
+ verifyRatingAndReviewedMeasures(ROOT_DIR_REF, C, 57.14);
+ verifyRatingAndReviewedMeasures(PROJECT_REF, C, 57.14);
}
@Test
@@ -249,11 +246,11 @@ class NewSecurityReviewMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyRatingAndReviewedMeasures(FILE_1_REF, D, D, 33.33);
- verifyRatingAndReviewedMeasures(FILE_2_REF, D, D, 40.0);
- verifyRatingAndReviewedMeasures(DIRECTORY_REF, D, D, 37.5);
- verifyRatingAndReviewedMeasures(ROOT_DIR_REF, D, D, 37.5);
- verifyRatingAndReviewedMeasures(PROJECT_REF, D, D, 37.5);
+ verifyRatingAndReviewedMeasures(FILE_1_REF, D, 33.33);
+ verifyRatingAndReviewedMeasures(FILE_2_REF, D, 40.0);
+ verifyRatingAndReviewedMeasures(DIRECTORY_REF, D, 37.5);
+ verifyRatingAndReviewedMeasures(ROOT_DIR_REF, D, 37.5);
+ verifyRatingAndReviewedMeasures(PROJECT_REF, D, 37.5);
}
@Test
@@ -276,11 +273,11 @@ class NewSecurityReviewMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyRatingAndReviewedMeasures(FILE_1_REF, D, D, 33.33);
- verifyRatingAndReviewedMeasures(FILE_2_REF, E, D, 0.0);
- verifyRatingAndReviewedMeasures(DIRECTORY_REF, E, D, 16.66);
- verifyRatingAndReviewedMeasures(ROOT_DIR_REF, E, D, 16.66);
- verifyRatingAndReviewedMeasures(PROJECT_REF, E, D, 16.66);
+ verifyRatingAndReviewedMeasures(FILE_1_REF, D, 33.33);
+ verifyRatingAndReviewedMeasures(FILE_2_REF, E, 0.0);
+ verifyRatingAndReviewedMeasures(DIRECTORY_REF, E, 16.66);
+ verifyRatingAndReviewedMeasures(ROOT_DIR_REF, E, 16.66);
+ verifyRatingAndReviewedMeasures(PROJECT_REF, E, 16.66);
}
@Test
@@ -293,7 +290,7 @@ class NewSecurityReviewMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyRatingAndReviewedMeasures(PROJECT_REF, A, A, null);
+ verifyRatingAndReviewedMeasures(PROJECT_REF, A, null);
}
@Test
@@ -343,10 +340,8 @@ class NewSecurityReviewMeasuresVisitorTest {
assertThat(measureRepository.getAddedRawMeasures(PROJECT_REF).values()).isEmpty();
}
- private void verifyRatingAndReviewedMeasures(int componentRef, Rating expectedReviewRating,
- Rating expectedSoftwareQualitySecurityReviewRating, @Nullable Double expectedHotspotsReviewed) {
+ private void verifyRatingAndReviewedMeasures(int componentRef, Rating expectedReviewRating, @Nullable Double expectedHotspotsReviewed) {
assertThat(measureRepository.getAddedRawMeasure(componentRef, NEW_SECURITY_REVIEW_RATING_KEY)).hasValue(expectedReviewRating.getIndex());
- assertThat(measureRepository.getAddedRawMeasure(componentRef, NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY)).hasValue(expectedSoftwareQualitySecurityReviewRating.getIndex());
if (expectedHotspotsReviewed != null) {
assertThat(measureRepository.getAddedRawMeasure(componentRef, NEW_SECURITY_HOTSPOTS_REVIEWED_KEY)).hasValue(expectedHotspotsReviewed,
VALUE_COMPARISON_OFFSET);
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java
index fae829957bb..9ce99a9556a 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java
@@ -163,7 +163,7 @@ class ReliabilityAndSecurityRatingMeasuresVisitorTest {
// Should not be taken into account
newImpactIssue(SoftwareQuality.SECURITY, Severity.HIGH));
- fillComponentIssuesVisitorRule.setIssues(PROJECT_REF, newImpactIssue(SoftwareQuality.RELIABILITY, Severity.HIGH));
+ fillComponentIssuesVisitorRule.setIssues(PROJECT_REF, newImpactIssue(SoftwareQuality.RELIABILITY, Severity.BLOCKER));
underTest.visit(ROOT_PROJECT);
@@ -171,7 +171,7 @@ class ReliabilityAndSecurityRatingMeasuresVisitorTest {
verifyAddedRawMeasure(FILE_2_REF, SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, C);
verifyAddedRawMeasure(FILE_3_REF, SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, A);
verifyAddedRawMeasure(DIRECTORY_REF, SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, C);
- verifyAddedRawMeasure(PROJECT_REF, SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, D);
+ verifyAddedRawMeasure(PROJECT_REF, SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, E);
}
@Test
@@ -197,13 +197,13 @@ class ReliabilityAndSecurityRatingMeasuresVisitorTest {
void compute_software_quality_security_rating() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
- newImpactIssue(SoftwareQuality.SECURITY, Severity.LOW),
+ newImpactIssue(SoftwareQuality.SECURITY, Severity.INFO),
// Should not be taken into account
newImpactIssue(SoftwareQuality.RELIABILITY, Severity.HIGH));
fillComponentIssuesVisitorRule.setIssues(FILE_2_REF,
newImpactIssue(SoftwareQuality.SECURITY, Severity.MEDIUM),
// Should not be taken into account
- newImpactIssue(SoftwareQuality.RELIABILITY, Severity.HIGH));
+ newImpactIssue(SoftwareQuality.RELIABILITY, Severity.BLOCKER));
fillComponentIssuesVisitorRule.setIssues(FILE_3_REF,
// Should not be taken into account
newImpactIssue(SoftwareQuality.RELIABILITY, Severity.HIGH));
@@ -212,7 +212,7 @@ class ReliabilityAndSecurityRatingMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyAddedRawMeasure(FILE_1_REF, SOFTWARE_QUALITY_SECURITY_RATING_KEY, B);
+ verifyAddedRawMeasure(FILE_1_REF, SOFTWARE_QUALITY_SECURITY_RATING_KEY, A);
verifyAddedRawMeasure(FILE_2_REF, SOFTWARE_QUALITY_SECURITY_RATING_KEY, C);
verifyAddedRawMeasure(FILE_3_REF, SOFTWARE_QUALITY_SECURITY_RATING_KEY, A);
verifyAddedRawMeasure(DIRECTORY_REF, SOFTWARE_QUALITY_SECURITY_RATING_KEY, C);
@@ -233,6 +233,19 @@ class ReliabilityAndSecurityRatingMeasuresVisitorTest {
}
@Test
+ void compute_E_software_quality_reliability_and_security_rating_on_blocker_issue() {
+ treeRootHolder.setRoot(ROOT_PROJECT);
+ fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newImpactIssue(SoftwareQuality.RELIABILITY, Severity.BLOCKER), newImpactIssue(SoftwareQuality.SECURITY, Severity.BLOCKER),
+ // Should not be taken into account
+ newImpactIssue(SoftwareQuality.MAINTAINABILITY, Severity.HIGH));
+
+ underTest.visit(ROOT_PROJECT);
+
+ verifyAddedRawMeasure(PROJECT_REF, SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, E);
+ verifyAddedRawMeasure(PROJECT_REF, SOFTWARE_QUALITY_SECURITY_RATING_KEY, E);
+ }
+
+ @Test
void compute_D_reliability_and_security_rating_on_critical_issue() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newBugIssue(10L, CRITICAL), newVulnerabilityIssue(15L, CRITICAL),
@@ -324,6 +337,19 @@ class ReliabilityAndSecurityRatingMeasuresVisitorTest {
}
@Test
+ void compute_A_software_quality_reliability_and_security_rating_on_info_issue() {
+ treeRootHolder.setRoot(ROOT_PROJECT);
+ fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, newImpactIssue(SoftwareQuality.RELIABILITY, Severity.INFO), newImpactIssue(SoftwareQuality.SECURITY, Severity.INFO),
+ // Should not be taken into account
+ newImpactIssue(SoftwareQuality.MAINTAINABILITY, Severity.HIGH));
+
+ underTest.visit(ROOT_PROJECT);
+
+ verifyAddedRawMeasure(PROJECT_REF, SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, A);
+ verifyAddedRawMeasure(PROJECT_REF, SOFTWARE_QUALITY_SECURITY_RATING_KEY, A);
+ }
+
+ @Test
void compute_A_software_quality_reliability_and_security_rating_when_no_issue() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitorTest.java
index 8d33cc5ddf5..ef5b6b59f8a 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitorTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitorTest.java
@@ -59,8 +59,6 @@ import static org.sonar.server.measure.Rating.B;
import static org.sonar.server.measure.Rating.C;
import static org.sonar.server.measure.Rating.D;
import static org.sonar.server.measure.Rating.E;
-import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING;
-import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY;
class SecurityReviewMeasuresVisitorTest {
@@ -87,7 +85,6 @@ class SecurityReviewMeasuresVisitorTest {
@RegisterExtension
private final MetricRepositoryRule metricRepository = new MetricRepositoryRule()
.add(SECURITY_REVIEW_RATING)
- .add(SOFTWARE_QUALITY_SECURITY_REVIEW_RATING)
.add(SECURITY_HOTSPOTS_REVIEWED)
.add(SECURITY_HOTSPOTS_REVIEWED_STATUS)
.add(SECURITY_HOTSPOTS_TO_REVIEW_STATUS);
@@ -115,11 +112,11 @@ class SecurityReviewMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyRatingAndReviewedMeasures(FILE_1_REF, A, A, 100.0);
- verifyRatingAndReviewedMeasures(FILE_2_REF, A, A, 100.0);
- verifyRatingAndReviewedMeasures(DIRECTORY_REF, A, A, 100.0);
- verifyRatingAndReviewedMeasures(ROOT_DIR_REF, A, A, 100.0);
- verifyRatingAndReviewedMeasures(PROJECT_REF, A, A, 100.0);
+ verifyRatingAndReviewedMeasures(FILE_1_REF, A, 100.0);
+ verifyRatingAndReviewedMeasures(FILE_2_REF, A, 100.0);
+ verifyRatingAndReviewedMeasures(DIRECTORY_REF, A, 100.0);
+ verifyRatingAndReviewedMeasures(ROOT_DIR_REF, A, 100.0);
+ verifyRatingAndReviewedMeasures(PROJECT_REF, A, 100.0);
}
@Test
@@ -141,11 +138,11 @@ class SecurityReviewMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyRatingAndReviewedMeasures(FILE_1_REF, A, A, 100.0);
- verifyRatingAndReviewedMeasures(FILE_2_REF, A, B, 80.0);
- verifyRatingAndReviewedMeasures(DIRECTORY_REF, A, B, 87.5);
- verifyRatingAndReviewedMeasures(ROOT_DIR_REF, A, B, 87.5);
- verifyRatingAndReviewedMeasures(PROJECT_REF, A, B, 87.5);
+ verifyRatingAndReviewedMeasures(FILE_1_REF, A, 100.0);
+ verifyRatingAndReviewedMeasures(FILE_2_REF, A, 80.0);
+ verifyRatingAndReviewedMeasures(DIRECTORY_REF, A, 87.5);
+ verifyRatingAndReviewedMeasures(ROOT_DIR_REF, A, 87.5);
+ verifyRatingAndReviewedMeasures(PROJECT_REF, A, 87.5);
}
@Test
@@ -167,11 +164,11 @@ class SecurityReviewMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyRatingAndReviewedMeasures(FILE_1_REF, A, A, 100.0);
- verifyRatingAndReviewedMeasures(FILE_2_REF, B, B, 71.4);
- verifyRatingAndReviewedMeasures(DIRECTORY_REF, B, B, 75.0);
- verifyRatingAndReviewedMeasures(ROOT_DIR_REF, B, B, 75.0);
- verifyRatingAndReviewedMeasures(PROJECT_REF, B, B, 75.0);
+ verifyRatingAndReviewedMeasures(FILE_1_REF, A, 100.0);
+ verifyRatingAndReviewedMeasures(FILE_2_REF, B, 71.4);
+ verifyRatingAndReviewedMeasures(DIRECTORY_REF, B, 75.0);
+ verifyRatingAndReviewedMeasures(ROOT_DIR_REF, B, 75.0);
+ verifyRatingAndReviewedMeasures(PROJECT_REF, B, 75.0);
}
@Test
@@ -192,11 +189,11 @@ class SecurityReviewMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyRatingAndReviewedMeasures(FILE_1_REF, C, C,50.0);
- verifyRatingAndReviewedMeasures(FILE_2_REF, C, C,60.0);
- verifyRatingAndReviewedMeasures(DIRECTORY_REF, C,C, 57.1);
- verifyRatingAndReviewedMeasures(ROOT_DIR_REF, C, C,57.1);
- verifyRatingAndReviewedMeasures(PROJECT_REF, C, C,57.1);
+ verifyRatingAndReviewedMeasures(FILE_1_REF, C, 50.0);
+ verifyRatingAndReviewedMeasures(FILE_2_REF, C, 60.0);
+ verifyRatingAndReviewedMeasures(DIRECTORY_REF, C, 57.1);
+ verifyRatingAndReviewedMeasures(ROOT_DIR_REF, C, 57.1);
+ verifyRatingAndReviewedMeasures(PROJECT_REF, C, 57.1);
}
@Test
@@ -218,11 +215,11 @@ class SecurityReviewMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyRatingAndReviewedMeasures(FILE_1_REF, D, D,33.3);
- verifyRatingAndReviewedMeasures(FILE_2_REF, D, D,40.0);
- verifyRatingAndReviewedMeasures(DIRECTORY_REF, D,D, 37.5);
- verifyRatingAndReviewedMeasures(ROOT_DIR_REF, D, D,37.5);
- verifyRatingAndReviewedMeasures(PROJECT_REF, D, D,37.5);
+ verifyRatingAndReviewedMeasures(FILE_1_REF, D, 33.3);
+ verifyRatingAndReviewedMeasures(FILE_2_REF, D, 40.0);
+ verifyRatingAndReviewedMeasures(DIRECTORY_REF, D, 37.5);
+ verifyRatingAndReviewedMeasures(ROOT_DIR_REF, D, 37.5);
+ verifyRatingAndReviewedMeasures(PROJECT_REF, D, 37.5);
}
@Test
@@ -242,11 +239,11 @@ class SecurityReviewMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyRatingAndReviewedMeasures(FILE_1_REF, D, D,33.3);
- verifyRatingAndReviewedMeasures(FILE_2_REF, E, D,0.0);
- verifyRatingAndReviewedMeasures(DIRECTORY_REF, E,D, 16.7);
- verifyRatingAndReviewedMeasures(ROOT_DIR_REF, E, D,16.7);
- verifyRatingAndReviewedMeasures(PROJECT_REF, E, D,16.7);
+ verifyRatingAndReviewedMeasures(FILE_1_REF, D, 33.3);
+ verifyRatingAndReviewedMeasures(FILE_2_REF, E, 0.0);
+ verifyRatingAndReviewedMeasures(DIRECTORY_REF, E, 16.7);
+ verifyRatingAndReviewedMeasures(ROOT_DIR_REF, E, 16.7);
+ verifyRatingAndReviewedMeasures(PROJECT_REF, E, 16.7);
}
@Test
@@ -255,7 +252,7 @@ class SecurityReviewMeasuresVisitorTest {
underTest.visit(ROOT_PROJECT);
- verifyRatingAndReviewedMeasures(PROJECT_REF, A, A,null);
+ verifyRatingAndReviewedMeasures(PROJECT_REF, A, null);
}
@Test
@@ -292,9 +289,8 @@ class SecurityReviewMeasuresVisitorTest {
verifyHotspotStatusMeasures(PROJECT_REF, 0, 0);
}
- private void verifyRatingAndReviewedMeasures(int componentRef, Rating expectedReviewRating, Rating expectedSoftwareQualityReviewRating,
- @Nullable Double expectedHotspotsReviewed) {
- verifySecurityReviewRating(componentRef, expectedReviewRating, expectedSoftwareQualityReviewRating);
+ private void verifyRatingAndReviewedMeasures(int componentRef, Rating expectedReviewRating, @Nullable Double expectedHotspotsReviewed) {
+ verifySecurityReviewRating(componentRef, expectedReviewRating);
if (expectedHotspotsReviewed != null) {
verifySecurityHotspotsReviewed(componentRef, expectedHotspotsReviewed);
} else {
@@ -302,13 +298,10 @@ class SecurityReviewMeasuresVisitorTest {
}
}
- private void verifySecurityReviewRating(int componentRef, Rating rating, Rating softwareQualityRating) {
+ private void verifySecurityReviewRating(int componentRef, Rating rating) {
Measure measure = measureRepository.getAddedRawMeasure(componentRef, SECURITY_REVIEW_RATING_KEY).get();
- Measure softwareQualityMeasure = measureRepository.getAddedRawMeasure(componentRef, SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY).get();
assertThat(measure.getIntValue()).isEqualTo(rating.getIndex());
assertThat(measure.getData()).isEqualTo(rating.name());
- assertThat(softwareQualityMeasure.getIntValue()).isEqualTo(softwareQualityRating.getIndex());
- assertThat(softwareQualityMeasure.getData()).isEqualTo(softwareQualityRating.name());
}
private void verifySecurityHotspotsReviewed(int componentRef, double percent) {
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java
index f7d898745b0..eb256bd6309 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java
@@ -77,9 +77,7 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING_KEY,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING_KEY,
- SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY,
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY,
- SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY,
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY,
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY
);
diff --git a/server/sonar-server-common/src/it/java/org/sonar/server/issue/index/IssueIndexerIT.java b/server/sonar-server-common/src/it/java/org/sonar/server/issue/index/IssueIndexerIT.java
index 39b9e1cd6b0..76897cb5743 100644
--- a/server/sonar-server-common/src/it/java/org/sonar/server/issue/index/IssueIndexerIT.java
+++ b/server/sonar-server-common/src/it/java/org/sonar/server/issue/index/IssueIndexerIT.java
@@ -48,6 +48,7 @@ import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.component.ProjectData;
import org.sonar.db.es.EsQueueDto;
+import org.sonar.db.issue.ImpactDto;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.issue.IssueTesting;
import org.sonar.db.project.ProjectDto;
@@ -174,7 +175,9 @@ public class IssueIndexerIT {
ComponentDto project = projectData.getMainBranchComponent();
ComponentDto dir = db.components().insertComponent(ComponentTesting.newDirectory(project, "src/main/java/foo"));
ComponentDto file = db.components().insertComponent(newFileDto(project, dir, "F1"));
- IssueDto issue = db.issues().insert(rule, project, file);
+ IssueDto issue = db.issues().insert(rule, project, file,
+ i -> i.replaceAllImpacts(List.of(new ImpactDto().setSoftwareQuality(SoftwareQuality.MAINTAINABILITY).setSeverity(Severity.HIGH),
+ new ImpactDto().setSoftwareQuality(SoftwareQuality.SECURITY).setSeverity(Severity.INFO))));
underTest.indexAllIssues();
@@ -205,7 +208,10 @@ public class IssueIndexerIT {
assertThat(doc.impacts())
.containsExactlyInAnyOrder(Map.of(
SUB_FIELD_SOFTWARE_QUALITY, SoftwareQuality.MAINTAINABILITY.name(),
- SUB_FIELD_SEVERITY, Severity.HIGH.name()));
+ SUB_FIELD_SEVERITY, Severity.HIGH.name()),
+ Map.of(
+ SUB_FIELD_SOFTWARE_QUALITY, SoftwareQuality.SECURITY.name(),
+ SUB_FIELD_SEVERITY, Severity.INFO.name()));
assertThat(doc.issueStatus()).isEqualTo(issue.getIssueStatus().name());
}
diff --git a/server/sonar-server-common/src/it/java/org/sonar/server/rule/index/RuleIndexIT.java b/server/sonar-server-common/src/it/java/org/sonar/server/rule/index/RuleIndexIT.java
index a7be47d330e..87c8474ffe6 100644
--- a/server/sonar-server-common/src/it/java/org/sonar/server/rule/index/RuleIndexIT.java
+++ b/server/sonar-server-common/src/it/java/org/sonar/server/rule/index/RuleIndexIT.java
@@ -50,11 +50,11 @@ import org.sonar.server.es.SearchOptions;
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
import org.sonar.server.security.SecurityStandards;
-import static com.google.common.collect.ImmutableSet.of;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
import static java.util.Collections.singletonList;
+import static java.util.Set.of;
import static java.util.stream.IntStream.rangeClosed;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -225,7 +225,8 @@ public class RuleIndexIT {
RuleDto rule1 = insertJavaRule("My great rule CWE-123 which makes your code 1000 times better!", "123", "rule 123");
RuleDto rule2 = insertJavaRule("Another great and shiny rule CWE-124", "124", "rule 124");
RuleDto rule3 = insertJavaRule("Another great rule CWE-1000", "1000", "rule 1000");
- RuleDto rule4 = insertJavaRule("<h1>HTML-Geeks</h1><p style=\"color:blue\">special formatting!</p><table><tr><td>inside</td><td>tables</td></tr></table>", "404", "rule 404");
+ RuleDto rule4 = insertJavaRule("<h1>HTML-Geeks</h1><p style=\"color:blue\">special " +
+ "formatting!</p><table><tr><td>inside</td><td>tables</td></tr></table>", "404", "rule 404");
RuleDto rule5 = insertJavaRule("internationalization missunderstandings alsdkjfnadklsjfnadkdfnsksdjfn", "405", "rule 405");
index();
@@ -323,7 +324,7 @@ public class RuleIndexIT {
@Test
public void tags_facet_supports_selected_value_with_regexp_special_characters() {
- createRule(r -> r.setTags(Set.of("misra++")));
+ createRule(r -> r.setTags(of("misra++")));
index();
RuleQuery query = new RuleQuery()
@@ -480,7 +481,8 @@ public class RuleIndexIT {
@Test
public void search_by_security_owaspTop10_2021_return_vulnerabilities_and_hotspots_only() {
- RuleDto rule1 = createRule(setSecurityStandards(of("owaspTop10-2021:a1", "owaspTop10-2021:a10", "cwe:543")), r -> r.setType(VULNERABILITY));
+ RuleDto rule1 = createRule(setSecurityStandards(of("owaspTop10-2021:a1", "owaspTop10-2021:a10", "cwe:543")),
+ r -> r.setType(VULNERABILITY));
RuleDto rule2 = createRule(setSecurityStandards(of("owaspTop10-2021:a10", "cwe:543")), r -> r.setType(SECURITY_HOTSPOT));
createRule(setSecurityStandards(of("cwe:543")), r -> r.setType(CODE_SMELL));
index();
@@ -521,7 +523,8 @@ public class RuleIndexIT {
// Creation of one rule for each standard security category defined (except other)
for (Map.Entry<SecurityStandards.SQCategory, Set<String>> sqCategorySetEntry : SecurityStandards.CWES_BY_SQ_CATEGORY.entrySet()) {
- rules.add(createRule(setSecurityStandards(of("cwe:" + sqCategorySetEntry.getValue().iterator().next())), r -> r.setType(SECURITY_HOTSPOT)));
+ rules.add(createRule(setSecurityStandards(of("cwe:" + sqCategorySetEntry.getValue().iterator().next())),
+ r -> r.setType(SECURITY_HOTSPOT)));
}
index();
@@ -553,9 +556,11 @@ public class RuleIndexIT {
db.qualityProfiles().activateRule(anotherProfile, anotherProfileRule2);
index();
- verifySearch(newRuleQuery().setActivation(false).setQProfile(profile).setCompareToQProfile(anotherProfile), anotherProfileRule1, anotherProfileRule2);
+ verifySearch(newRuleQuery().setActivation(false).setQProfile(profile).setCompareToQProfile(anotherProfile), anotherProfileRule1,
+ anotherProfileRule2);
verifySearch(newRuleQuery().setActivation(true).setQProfile(profile).setCompareToQProfile(anotherProfile), commonRule);
- verifySearch(newRuleQuery().setActivation(true).setQProfile(profile).setCompareToQProfile(profile), commonRule, profileRule1, profileRule2, profileRule3);
+ verifySearch(newRuleQuery().setActivation(true).setQProfile(profile).setCompareToQProfile(profile), commonRule, profileRule1,
+ profileRule2, profileRule3);
verifySearch(newRuleQuery().setActivation(false).setQProfile(profile).setCompareToQProfile(profile));
}
@@ -704,7 +709,8 @@ public class RuleIndexIT {
verifyEmptySearch(newRuleQuery().setActivation(true).setQProfile(parent).setInheritance(of(INHERITED.name(), OVERRIDES.name())));
// inherited AND overridden on child
- verifySearch(newRuleQuery().setActivation(true).setQProfile(child).setInheritance(of(INHERITED.name(), OVERRIDES.name())), rule1, rule2, rule3);
+ verifySearch(newRuleQuery().setActivation(true).setQProfile(child).setInheritance(of(INHERITED.name(), OVERRIDES.name())), rule1,
+ rule2, rule3);
}
@Test
@@ -812,17 +818,19 @@ public class RuleIndexIT {
index();
RuleQuery query = new RuleQuery();
- SearchIdResult result1 = underTest.search(query.setImpactSoftwareQualities(List.of(SoftwareQuality.MAINTAINABILITY.name())), new SearchOptions());
+ SearchIdResult result1 = underTest.search(query.setImpactSoftwareQualities(List.of(SoftwareQuality.MAINTAINABILITY.name())),
+ new SearchOptions());
assertThat(result1.getUuids()).isEmpty();
query = new RuleQuery();
- SearchIdResult result2 = underTest.search(query.setImpactSoftwareQualities(List.of(SoftwareQuality.SECURITY.name())), new SearchOptions());
+ SearchIdResult result2 = underTest.search(query.setImpactSoftwareQualities(List.of(SoftwareQuality.SECURITY.name())),
+ new SearchOptions());
assertThat(result2.getUuids()).containsOnly(phpRule.getUuid());
}
@Test
public void search_by_severity() {
- ImpactDto impactDto = new ImpactDto().setSoftwareQuality(SoftwareQuality.SECURITY).setSeverity(Severity.HIGH);
+ ImpactDto impactDto = new ImpactDto().setSoftwareQuality(SoftwareQuality.SECURITY).setSeverity(Severity.BLOCKER);
RuleDto phpRule = createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto)));
index();
@@ -831,7 +839,7 @@ public class RuleIndexIT {
assertThat(result1.getUuids()).isEmpty();
query = new RuleQuery();
- SearchIdResult result2 = underTest.search(query.setImpactSeverities(List.of(Severity.HIGH.name())), new SearchOptions());
+ SearchIdResult result2 = underTest.search(query.setImpactSeverities(List.of(Severity.BLOCKER.name())), new SearchOptions());
assertThat(result2.getUuids()).containsOnly(phpRule.getUuid());
}
@@ -846,7 +854,8 @@ public class RuleIndexIT {
SearchIdResult result2 = underTest.search(query, new SearchOptions().addFacets(singletonList("cleanCodeAttributeCategories")));
assertThat(result2.getFacets().getAll()).hasSize(1);
- assertThat(result2.getFacets().getAll().get("cleanCodeAttributeCategories")).containsOnly(entry("ADAPTABLE", 1L), entry("INTENTIONAL", 1L));
+ assertThat(result2.getFacets().getAll().get("cleanCodeAttributeCategories")).containsOnly(entry("ADAPTABLE", 1L), entry("INTENTIONAL"
+ , 1L));
}
@Test
@@ -859,7 +868,8 @@ public class RuleIndexIT {
RuleQuery query = new RuleQuery();
SearchIdResult result = underTest.search(
- query.setCleanCodeAttributesCategories(List.of(CleanCodeAttributeCategory.CONSISTENT.name(), CleanCodeAttributeCategory.ADAPTABLE.name())),
+ query.setCleanCodeAttributesCategories(List.of(CleanCodeAttributeCategory.CONSISTENT.name(),
+ CleanCodeAttributeCategory.ADAPTABLE.name())),
new SearchOptions().addFacets(singletonList("cleanCodeAttributeCategories")));
assertThat(result.getUuids()).containsExactlyInAnyOrder(php.getUuid(), java.getUuid());
@@ -895,7 +905,8 @@ public class RuleIndexIT {
RuleQuery query = new RuleQuery();
- SearchIdResult result2 = underTest.search(query.setImpactSeverities(Set.of(Severity.HIGH.name())), new SearchOptions().addFacets(singletonList("impactSoftwareQualities")));
+ SearchIdResult result2 = underTest.search(query.setImpactSeverities(of(Severity.HIGH.name())),
+ new SearchOptions().addFacets(singletonList("impactSoftwareQualities")));
assertThat(result2.getFacets().getAll()).hasSize(1);
assertThat(result2.getFacets().getAll().get("impactSoftwareQualities"))
@@ -910,14 +921,21 @@ public class RuleIndexIT {
ImpactDto impactDto = new ImpactDto().setSoftwareQuality(SoftwareQuality.MAINTAINABILITY).setSeverity(Severity.HIGH);
ImpactDto impactDto2 = new ImpactDto().setSoftwareQuality(SoftwareQuality.MAINTAINABILITY).setSeverity(Severity.LOW);
ImpactDto impactDto3 = new ImpactDto().setSoftwareQuality(SoftwareQuality.RELIABILITY).setSeverity(Severity.LOW);
+ ImpactDto impactDto4 = new ImpactDto().setSoftwareQuality(SoftwareQuality.RELIABILITY).setSeverity(Severity.BLOCKER);
+ ImpactDto impactDto5 = new ImpactDto().setSoftwareQuality(SoftwareQuality.MAINTAINABILITY).setSeverity(Severity.BLOCKER);
+ ImpactDto impactDto6 = new ImpactDto().setSoftwareQuality(SoftwareQuality.RELIABILITY).setSeverity(Severity.INFO);
createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto)));
- createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto2, impactDto3)));
+ createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto2)));
+ createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto3)));
+ createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto4)));
+ createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto5)));
+ createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto6)));
index();
RuleQuery query = new RuleQuery();
SearchIdResult result = underTest.search(
- query.setImpactSeverities(Set.of(Severity.LOW.name())).setImpactSoftwareQualities(List.of(SoftwareQuality.MAINTAINABILITY.name())),
+ query.setImpactSeverities(of(Severity.LOW.name())).setImpactSoftwareQualities(List.of(SoftwareQuality.MAINTAINABILITY.name())),
new SearchOptions().addFacets(List.of("impactSoftwareQualities", "impactSeverities")));
assertThat(result.getFacets().getAll()).hasSize(2);
@@ -931,15 +949,18 @@ public class RuleIndexIT {
.containsOnly(
entry("HIGH", 1L),
entry("MEDIUM", 0L),
- entry("LOW", 1L));
+ entry("LOW", 1L),
+ entry("INFO", 0L),
+ entry("BLOCKER", 1L));
}
@Test
public void search_should_support_severity_facet() {
ImpactDto impactDto = new ImpactDto().setSoftwareQuality(SoftwareQuality.SECURITY).setSeverity(Severity.HIGH);
ImpactDto impactDto2 = new ImpactDto().setSoftwareQuality(SoftwareQuality.MAINTAINABILITY).setSeverity(Severity.LOW);
+ ImpactDto impactDto3 = new ImpactDto().setSoftwareQuality(SoftwareQuality.RELIABILITY).setSeverity(Severity.BLOCKER);
createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto)));
- createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto2)));
+ createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto2, impactDto3)));
index();
RuleQuery query = new RuleQuery();
@@ -947,40 +968,65 @@ public class RuleIndexIT {
SearchIdResult result2 = underTest.search(query, new SearchOptions().addFacets(singletonList("impactSeverities")));
assertThat(result2.getFacets().getAll()).hasSize(1);
- assertThat(result2.getFacets().getAll().get("impactSeverities")).containsOnly(entry("LOW", 1L), entry("MEDIUM", 0L), entry("HIGH", 1L));
+ assertThat(result2.getFacets().getAll().get("impactSeverities"))
+ .containsOnly(
+ entry("LOW", 1L),
+ entry("MEDIUM", 0L),
+ entry("HIGH", 1L),
+ entry("INFO", 0L),
+ entry("BLOCKER", 1L));
}
@Test
public void search_should_support_severity_facet_with_filters() {
ImpactDto impactDto = new ImpactDto().setSoftwareQuality(SoftwareQuality.SECURITY).setSeverity(Severity.HIGH);
ImpactDto impactDto2 = new ImpactDto().setSoftwareQuality(SoftwareQuality.MAINTAINABILITY).setSeverity(Severity.LOW);
+ ImpactDto impactDto3 = new ImpactDto().setSoftwareQuality(SoftwareQuality.SECURITY).setSeverity(Severity.INFO);
+ ImpactDto impactDto4 = new ImpactDto().setSoftwareQuality(SoftwareQuality.MAINTAINABILITY).setSeverity(Severity.INFO);
+ ImpactDto impactDto5 = new ImpactDto().setSoftwareQuality(SoftwareQuality.SECURITY).setSeverity(Severity.BLOCKER);
createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto)));
- createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto2)));
+ createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto2, impactDto3)));
+ createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto4, impactDto5)));
index();
RuleQuery query = new RuleQuery();
- SearchIdResult result2 = underTest.search(query.setImpactSeverities(Set.of("LOW")), new SearchOptions().addFacets(singletonList("impactSeverities")));
+ SearchIdResult result2 = underTest.search(query.setImpactSeverities(of("LOW")), new SearchOptions().addFacets(singletonList(
+ "impactSeverities")));
assertThat(result2.getFacets().getAll()).hasSize(1);
- assertThat(result2.getFacets().getAll().get("impactSeverities")).containsOnly(entry("LOW", 1L), entry("MEDIUM", 0L), entry("HIGH", 1L));
+ assertThat(result2.getFacets().getAll().get("impactSeverities"))
+ .containsOnly(
+ entry("LOW", 1L),
+ entry("MEDIUM", 0L),
+ entry("HIGH", 1L),
+ entry("INFO", 2L),
+ entry("BLOCKER", 1L));
}
@Test
public void search_should_support_software_quality_and_severity_facets_with_filtering() {
ImpactDto impactDto = new ImpactDto().setSoftwareQuality(SoftwareQuality.SECURITY).setSeverity(Severity.HIGH);
ImpactDto impactDto2 = new ImpactDto().setSoftwareQuality(SoftwareQuality.MAINTAINABILITY).setSeverity(Severity.LOW);
+ ImpactDto impactDto3 = new ImpactDto().setSoftwareQuality(SoftwareQuality.MAINTAINABILITY).setSeverity(Severity.BLOCKER);
createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto)));
createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto2)));
+ createRule(setRepositoryKey("php"), setImpacts(List.of(impactDto3)));
index();
- RuleQuery query = new RuleQuery().setImpactSeverities(Set.of("LOW"))
- .setImpactSoftwareQualities(Set.of(SoftwareQuality.MAINTAINABILITY.name()));
+ RuleQuery query = new RuleQuery().setImpactSeverities(of("LOW"))
+ .setImpactSoftwareQualities(of(SoftwareQuality.MAINTAINABILITY.name()));
SearchOptions searchOptions = new SearchOptions().addFacets(List.of("impactSeverities", "impactSoftwareQualities"));
SearchIdResult result2 = underTest.search(query, searchOptions);
assertThat(result2.getFacets().getAll()).hasSize(2);
- assertThat(result2.getFacets().getAll().get("impactSeverities")).containsOnly(entry("LOW", 1L), entry("MEDIUM", 0L), entry("HIGH", 0L));
+ assertThat(result2.getFacets().getAll().get("impactSeverities"))
+ .containsOnly(
+ entry("LOW", 1L),
+ entry("MEDIUM", 0L),
+ entry("HIGH", 0L),
+ entry("INFO", 0L),
+ entry("BLOCKER", 1L));
assertThat(result2.getFacets().getAll().get("impactSoftwareQualities")).containsOnly(
entry(SoftwareQuality.SECURITY.name(), 0L),
entry(SoftwareQuality.MAINTAINABILITY.name(), 1L),
@@ -1000,7 +1046,8 @@ public class RuleIndexIT {
assertThat(result1.getFacets().getAll()).isEmpty();
// should not have any facet on non matching query!
- SearchIdResult result2 = underTest.search(new RuleQuery().setQueryText("aeiou"), new SearchOptions().addFacets(singletonList("repositories")));
+ SearchIdResult result2 = underTest.search(new RuleQuery().setQueryText("aeiou"), new SearchOptions().addFacets(singletonList(
+ "repositories")));
assertThat(result2.getFacets().getAll()).hasSize(1);
assertThat(result2.getFacets().getAll().get("repositories")).isEmpty();
@@ -1070,7 +1117,8 @@ public class RuleIndexIT {
setupStickyFacets();
RuleQuery query = new RuleQuery().setLanguages(ImmutableList.of("cpp"));
- SearchIdResult<String> result = underTest.search(query, new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS)));
+ SearchIdResult<String> result = underTest.search(query, new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES,
+ FACET_TAGS)));
assertThat(result.getUuids()).hasSize(3);
assertThat(result.getFacets().getAll()).hasSize(3);
assertThat(result.getFacets().get(FACET_LANGUAGES)).containsOnlyKeys("cpp", "java", "cobol");
@@ -1194,7 +1242,8 @@ public class RuleIndexIT {
.setTags(ImmutableList.of("T2"))
.setTypes(asList(BUG, CODE_SMELL));
- SearchIdResult<String> result = underTest.search(query, new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS,
+ SearchIdResult<String> result = underTest.search(query, new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES,
+ FACET_TAGS,
FACET_TYPES)));
assertThat(result.getUuids()).hasSize(2);
assertThat(result.getFacets().getAll()).hasSize(4);
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/measure/DebtRatingGrid.java b/server/sonar-server-common/src/main/java/org/sonar/server/measure/DebtRatingGrid.java
index 4bbc2b54ac7..247a1829f98 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/measure/DebtRatingGrid.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/measure/DebtRatingGrid.java
@@ -78,17 +78,6 @@ public class DebtRatingGrid {
.orElseThrow(() -> new IllegalArgumentException(format("Invalid value '%s'", value)));
}
- /**
- * Computes a rating from A to D, where E is converted to D.
- */
- public Rating getAToDRatingForDensity(double value) {
- return ratingBounds.entrySet().stream()
- .filter(e -> e.getValue().match(value))
- .map(e -> e.getKey() == E ? D : e.getKey())
- .findFirst()
- .orElseThrow(() -> new IllegalArgumentException(format("Invalid value '%s'", value)));
- }
-
public double getGradeLowerBound(Rating rating) {
if (rating.getIndex() > 1) {
return gridValues[rating.getIndex() - 2];
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/measure/ImpactMeasureBuilder.java b/server/sonar-server-common/src/main/java/org/sonar/server/measure/ImpactMeasureBuilder.java
index 3167b5d03ee..eae57b9d482 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/measure/ImpactMeasureBuilder.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/measure/ImpactMeasureBuilder.java
@@ -23,7 +23,6 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
-import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.annotation.CheckForNull;
@@ -32,7 +31,8 @@ import org.sonar.api.issue.impact.Severity;
import static org.sonar.api.utils.Preconditions.checkArgument;
/**
- * Builder class to help build measures based on impacts with payload such as @{link {@link org.sonar.api.measures.CoreMetrics#RELIABILITY_ISSUES}}.
+ * Builder class to help build measures based on impacts with payload such as @{link
+ * {@link org.sonar.api.measures.CoreMetrics#RELIABILITY_ISSUES}}.
*/
public class ImpactMeasureBuilder {
@@ -65,9 +65,16 @@ public class ImpactMeasureBuilder {
return new ImpactMeasureBuilder(map);
}
- private static void checkImpactMap(Map<String, Long> map) {
- checkArgument(map.containsKey(TOTAL_KEY), "Map must contain a total key");
- Arrays.stream(Severity.values()).forEach(severity -> checkArgument(map.containsKey(severity.name()), "Map must contain a key for severity " + severity.name()));
+ /**
+ * As we moved from 3 to 5 severities, we need to be able to handle measures saved with missing severities.
+ */
+ private static void checkImpactMap(Map<String, Long> impactMap) {
+ checkArgument(impactMap.containsKey(TOTAL_KEY), "Map must contain a total key");
+ for (Severity severity : Severity.values()) {
+ if (!impactMap.containsKey(severity.name())) {
+ impactMap.put(severity.name(), 0L);
+ }
+ }
}
public static ImpactMeasureBuilder fromString(String value) {
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/measure/Rating.java b/server/sonar-server-common/src/main/java/org/sonar/server/measure/Rating.java
index f00b8796dd8..3ba14d771a3 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/measure/Rating.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/measure/Rating.java
@@ -45,9 +45,11 @@ public enum Rating {
INFO, A);
public static final Map<Severity, Rating> RATING_BY_SOFTWARE_QUALITY_SEVERITY = Map.of(
+ Severity.BLOCKER, Rating.E,
Severity.HIGH, Rating.D,
Severity.MEDIUM, Rating.C,
- Severity.LOW, Rating.B);
+ Severity.LOW, Rating.B,
+ Severity.INFO, Rating.A);
private final int index;
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/measure/index/ProjectMeasuresSoftwareQualityRatingsInitializer.java b/server/sonar-server-common/src/main/java/org/sonar/server/measure/index/ProjectMeasuresSoftwareQualityRatingsInitializer.java
index fecce77fcd4..2c2a1d017b1 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/measure/index/ProjectMeasuresSoftwareQualityRatingsInitializer.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/measure/index/ProjectMeasuresSoftwareQualityRatingsInitializer.java
@@ -26,7 +26,7 @@ import org.sonar.server.measure.Rating;
/**
* This class defines "default" measures values for the "Software Quality Rating Metrics" when they do not exist.
- * The "default" value is the same as the equivalent "Rule Type Rating Metric", except for E Rating that is converted to D Rating
+ * The "default" value is the same as the equivalent "Rule Type Rating Metric"
* If the "Software Quality Rating Metrics" exists, then no changes are made
*/
public class ProjectMeasuresSoftwareQualityRatingsInitializer {
@@ -35,9 +35,7 @@ public class ProjectMeasuresSoftwareQualityRatingsInitializer {
CoreMetrics.SQALE_RATING_KEY, SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY,
CoreMetrics.RELIABILITY_RATING_KEY, SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING_KEY,
CoreMetrics.SECURITY_RATING_KEY, SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING_KEY,
- CoreMetrics.SECURITY_REVIEW_RATING_KEY, SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY,
CoreMetrics.NEW_SECURITY_RATING_KEY, SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY,
- CoreMetrics.NEW_SECURITY_REVIEW_RATING_KEY, SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY,
CoreMetrics.NEW_MAINTAINABILITY_RATING_KEY, SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY,
CoreMetrics.NEW_RELIABILITY_RATING_KEY, SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY
);
@@ -59,7 +57,7 @@ public class ProjectMeasuresSoftwareQualityRatingsInitializer {
Double value = measures.get(ruleTypeMetric);
if (value != null) {
- measures.put(softwareQualityMetric, value > Rating.D.getIndex() ? Double.valueOf(Rating.D.getIndex()) : value);
+ measures.put(softwareQualityMetric, value);
}
}
}
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityReviewRating.java b/server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityReviewRating.java
index 69791800a7b..1af9a5db8c8 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityReviewRating.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityReviewRating.java
@@ -56,14 +56,4 @@ public class SecurityReviewRating {
return E;
}
- public static Rating computeAToDRating(@Nullable Double percent) {
- if (percent == null || Math.abs(percent - 100.0D) < 10e-6) {
- return A;
- } else if (percent >= 70.0D) {
- return B;
- } else if (percent >= 50.0D) {
- return C;
- }
- return D;
- }
}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/measure/DebtRatingGridTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/measure/DebtRatingGridTest.java
index 6557e108815..8a312cba599 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/measure/DebtRatingGridTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/measure/DebtRatingGridTest.java
@@ -55,21 +55,6 @@ public class DebtRatingGridTest {
}
@Test
- public void getAToDRatingForDensity_returnsValueBetweenAAndD() {
- assertThat(ratingGrid.getAToDRatingForDensity(0)).isEqualTo(A);
- assertThat(ratingGrid.getAToDRatingForDensity(0.05)).isEqualTo(A);
- assertThat(ratingGrid.getAToDRatingForDensity(0.09999999)).isEqualTo(A);
- assertThat(ratingGrid.getAToDRatingForDensity(0.1)).isEqualTo(A);
- assertThat(ratingGrid.getAToDRatingForDensity(0.15)).isEqualTo(B);
- assertThat(ratingGrid.getAToDRatingForDensity(0.2)).isEqualTo(B);
- assertThat(ratingGrid.getAToDRatingForDensity(0.25)).isEqualTo(C);
- assertThat(ratingGrid.getAToDRatingForDensity(0.5)).isEqualTo(C);
- assertThat(ratingGrid.getAToDRatingForDensity(0.65)).isEqualTo(D);
- assertThat(ratingGrid.getAToDRatingForDensity(1)).isEqualTo(D);
- assertThat(ratingGrid.getAToDRatingForDensity(1.01)).isEqualTo(D);
- }
-
- @Test
public void density_matching_exact_grid_values() {
assertThat(ratingGrid.getRatingForDensity(0.1)).isEqualTo(A);
assertThat(ratingGrid.getRatingForDensity(0.2)).isEqualTo(B);
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/measure/ImpactMeasureBuilderTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/measure/ImpactMeasureBuilderTest.java
index 82f26c979c7..a7a393a6c62 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/measure/ImpactMeasureBuilderTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/measure/ImpactMeasureBuilderTest.java
@@ -19,12 +19,17 @@
*/
package org.sonar.server.measure;
+import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;
-import org.sonar.api.issue.impact.Severity;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.sonar.api.issue.impact.Severity.BLOCKER;
+import static org.sonar.api.issue.impact.Severity.HIGH;
+import static org.sonar.api.issue.impact.Severity.INFO;
+import static org.sonar.api.issue.impact.Severity.LOW;
+import static org.sonar.api.issue.impact.Severity.MEDIUM;
class ImpactMeasureBuilderTest {
@@ -32,17 +37,17 @@ class ImpactMeasureBuilderTest {
void createEmptyMeasure_shouldReturnMeasureWithAllFields() {
ImpactMeasureBuilder builder = ImpactMeasureBuilder.createEmpty();
assertThat(builder.buildAsMap())
- .containsAllEntriesOf(getImpactMap(0L, 0L, 0L, 0L));
- }
-
- private static Map<String, Long> getImpactMap(Long total, Long high, Long medium, Long low) {
- return Map.of("total", total, Severity.HIGH.name(), high, Severity.MEDIUM.name(), medium, Severity.LOW.name(), low);
+ .containsAllEntriesOf(getImpactMap(0L, 0L, 0L, 0L, 0L, 0L));
}
@Test
void fromMap_shouldInitializeCorrectlyTheBuilder() {
Map<String, Long> map = getImpactMap(6L, 3L, 2L, 1L);
ImpactMeasureBuilder builder = ImpactMeasureBuilder.fromMap(map);
+
+ map.put(INFO.name(), 0L);
+ map.put(BLOCKER.name(), 0L);
+
assertThat(builder.buildAsMap())
.isEqualTo(map);
}
@@ -65,8 +70,9 @@ class ImpactMeasureBuilderTest {
LOW: 1
}
""");
+ Map<String, Long> expectedMap = getImpactMap(6L, 3L, 2L, 1L, 0L, 0L);
assertThat(builder.buildAsMap())
- .isEqualTo(getImpactMap(6L, 3L, 2L, 1L));
+ .isEqualTo(expectedMap);
}
@Test
@@ -78,44 +84,30 @@ class ImpactMeasureBuilderTest {
}
@Test
- void buildAsMap_whenMissingSeverity_shouldThrowException() {
- ImpactMeasureBuilder impactMeasureBuilder = ImpactMeasureBuilder.newInstance()
- .setTotal(1L)
- .setSeverity(Severity.HIGH, 1L)
- .setSeverity(Severity.MEDIUM, 1L);
- assertThatThrownBy(impactMeasureBuilder::buildAsMap)
- .isInstanceOf(IllegalArgumentException.class)
- .hasMessage("Map must contain a key for severity LOW");
- }
-
- @Test
- void buildAsString_whenMissingSeverity_shouldThrowException() {
- ImpactMeasureBuilder impactMeasureBuilder = ImpactMeasureBuilder.newInstance()
- .setTotal(1L)
- .setSeverity(Severity.HIGH, 1L)
- .setSeverity(Severity.MEDIUM, 1L);
- assertThatThrownBy(impactMeasureBuilder::buildAsString)
- .isInstanceOf(IllegalArgumentException.class)
- .hasMessage("Map must contain a key for severity LOW");
- }
-
- @Test
void setSeverity_shouldInitializeSeverityValues() {
ImpactMeasureBuilder builder = ImpactMeasureBuilder.newInstance()
- .setSeverity(Severity.HIGH, 3L)
- .setSeverity(Severity.MEDIUM, 2L)
- .setSeverity(Severity.LOW, 1L)
- .setTotal(6L);
+ .setSeverity(HIGH, 3L)
+ .setSeverity(MEDIUM, 2L)
+ .setSeverity(LOW, 1L)
+ .setSeverity(INFO, 4L)
+ .setSeverity(BLOCKER, 5L)
+ .setTotal(15L);
assertThat(builder.buildAsMap())
- .isEqualTo(getImpactMap(6L, 3L, 2L, 1L));
+ .isEqualTo(getImpactMap(15L, 3L, 2L, 1L, 4L, 5L));
}
@Test
void add_shouldSumImpactsAndTotal() {
- ImpactMeasureBuilder builder = ImpactMeasureBuilder.fromMap(getImpactMap(6L, 3L, 2L, 1L))
- .add(ImpactMeasureBuilder.newInstance().setTotal(6L).setSeverity(Severity.HIGH, 3L).setSeverity(Severity.MEDIUM, 2L).setSeverity(Severity.LOW, 1L));
+ ImpactMeasureBuilder builder = ImpactMeasureBuilder.fromMap(getImpactMap(11L, 3L, 2L, 1L, 1L, 4L))
+ .add(ImpactMeasureBuilder.newInstance()
+ .setTotal(14L)
+ .setSeverity(HIGH, 3L)
+ .setSeverity(MEDIUM, 2L)
+ .setSeverity(LOW, 1L)
+ .setSeverity(INFO, 5L)
+ .setSeverity(BLOCKER, 3L));
assertThat(builder.buildAsMap())
- .isEqualTo(getImpactMap(12L, 6L, 4L, 2L));
+ .isEqualTo(getImpactMap(25L, 6L, 4L, 2L, 6L, 7L));
}
@Test
@@ -128,10 +120,28 @@ class ImpactMeasureBuilderTest {
}
@Test
- void getTotal_shoudReturnExpectedTotal() {
+ void getTotal_shouldReturnExpectedTotal() {
ImpactMeasureBuilder builder = ImpactMeasureBuilder.fromMap(getImpactMap(6L, 3L, 2L, 1L));
assertThat(builder.getTotal()).isEqualTo(6L);
}
+ private static Map<String, Long> getImpactMap(Long total, Long high, Long medium, Long low) {
+ return new HashMap<>() {
+ {
+ put("total", total);
+ put(HIGH.name(), high);
+ put(MEDIUM.name(), medium);
+ put(LOW.name(), low);
+ }
+ };
+ }
+
+ private static Map<String, Long> getImpactMap(Long total, Long high, Long medium, Long low, Long info, Long blocker) {
+ Map<String, Long> impactMap = getImpactMap(total, high, medium, low);
+ impactMap.put(INFO.name(), info);
+ impactMap.put(BLOCKER.name(), blocker);
+ return impactMap;
+ }
+
}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/measure/index/ProjectMeasuresSoftwareQualityRatingsInitializerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/measure/index/ProjectMeasuresSoftwareQualityRatingsInitializerTest.java
index ed9119174ec..e1dddaaafc0 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/measure/index/ProjectMeasuresSoftwareQualityRatingsInitializerTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/measure/index/ProjectMeasuresSoftwareQualityRatingsInitializerTest.java
@@ -49,10 +49,8 @@ class ProjectMeasuresSoftwareQualityRatingsInitializerTest {
initialMeasures.put(CoreMetrics.SQALE_RATING_KEY, 1.0);
initialMeasures.put(CoreMetrics.RELIABILITY_RATING_KEY, 2.0);
initialMeasures.put(CoreMetrics.SECURITY_RATING_KEY, 3.0);
- initialMeasures.put(CoreMetrics.SECURITY_REVIEW_RATING_KEY, 4.0);
initialMeasures.put(CoreMetrics.NEW_SECURITY_RATING_KEY, 4.0);
- initialMeasures.put(CoreMetrics.NEW_SECURITY_REVIEW_RATING_KEY, 3.0);
- initialMeasures.put(CoreMetrics.NEW_MAINTAINABILITY_RATING_KEY, 2.0);
+ initialMeasures.put(CoreMetrics.NEW_MAINTAINABILITY_RATING_KEY, 5.0);
initialMeasures.put(CoreMetrics.NEW_RELIABILITY_RATING_KEY, 1.0);
Map<String, Double> measures = new HashMap<>(initialMeasures);
@@ -64,38 +62,8 @@ class ProjectMeasuresSoftwareQualityRatingsInitializerTest {
.containsEntry(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, 1.0)
.containsEntry(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, 2.0)
.containsEntry(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING_KEY, 3.0)
- .containsEntry(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY, 4.0)
.containsEntry(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, 4.0)
- .containsEntry(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY, 3.0)
- .containsEntry(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, 2.0)
+ .containsEntry(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, 5.0)
.containsEntry(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, 1.0);
}
-
- @Test
- void initializeSoftwareQualityRatings_whenERating_thenSoftwareQualityRatingCreatedWithD() {
- Map<String, Double> initialMeasures = new HashMap<>();
- initialMeasures.put(CoreMetrics.SQALE_RATING_KEY, (double) Rating.E.getIndex());
- initialMeasures.put(CoreMetrics.RELIABILITY_RATING_KEY, (double) Rating.E.getIndex());
- initialMeasures.put(CoreMetrics.SECURITY_RATING_KEY, (double) Rating.E.getIndex());
- initialMeasures.put(CoreMetrics.SECURITY_REVIEW_RATING_KEY, (double) Rating.E.getIndex());
- initialMeasures.put(CoreMetrics.NEW_SECURITY_RATING_KEY, (double) Rating.E.getIndex());
- initialMeasures.put(CoreMetrics.NEW_SECURITY_REVIEW_RATING_KEY, (double) Rating.E.getIndex());
- initialMeasures.put(CoreMetrics.NEW_MAINTAINABILITY_RATING_KEY, (double) Rating.E.getIndex());
- initialMeasures.put(CoreMetrics.NEW_RELIABILITY_RATING_KEY, (double) Rating.E.getIndex());
-
- Map<String, Double> measures = new HashMap<>(initialMeasures);
-
- ProjectMeasuresSoftwareQualityRatingsInitializer.initializeSoftwareQualityRatings(measures);
-
- assertThat(measures).hasSize(initialMeasures.size() * 2)
- .containsAllEntriesOf(initialMeasures)
- .containsEntry(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, (double) Rating.D.getIndex())
- .containsEntry(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, (double) Rating.D.getIndex())
- .containsEntry(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING_KEY, (double) Rating.D.getIndex())
- .containsEntry(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY, (double) Rating.D.getIndex())
- .containsEntry(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, (double) Rating.D.getIndex())
- .containsEntry(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY, (double) Rating.D.getIndex())
- .containsEntry(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, (double) Rating.D.getIndex())
- .containsEntry(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, (double) Rating.D.getIndex());
- }
}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityReviewRatingTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityReviewRatingTest.java
index 1d586900a1b..ec7c91b03b2 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityReviewRatingTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityReviewRatingTest.java
@@ -33,7 +33,6 @@ import static org.sonar.server.measure.Rating.B;
import static org.sonar.server.measure.Rating.C;
import static org.sonar.server.measure.Rating.D;
import static org.sonar.server.measure.Rating.E;
-import static org.sonar.server.security.SecurityReviewRating.computeAToDRating;
import static org.sonar.server.security.SecurityReviewRating.computePercent;
import static org.sonar.server.security.SecurityReviewRating.computeRating;
@@ -56,36 +55,12 @@ class SecurityReviewRatingTest {
return res.toArray(new Object[res.size()][2]);
}
- private static Object[][] valuesForSoftwareQualityRatings() {
- List<Object[]> res = new ArrayList<>();
- res.add(new Object[] {100.0, A});
- res.add(new Object[] {99.999999, A});
- res.add(new Object[] {99.99999, B});
- res.add(new Object[] {99.9, B});
- res.add(new Object[] {90.0, B});
- res.add(new Object[] {80.0, B});
- res.add(new Object[] {75.0, B});
- res.add(new Object[] {70.0, B});
- res.add(new Object[] {60, C});
- res.add(new Object[] {50.0, C});
- res.add(new Object[] {40.0, D});
- res.add(new Object[] {30.0, D});
- res.add(new Object[] {29.9, D});
- return res.toArray(new Object[res.size()][2]);
- }
-
@ParameterizedTest
@MethodSource("values")
void compute_rating(double percent, Rating expectedRating) {
assertThat(computeRating(percent)).isEqualTo(expectedRating);
}
- @ParameterizedTest
- @MethodSource("valuesForSoftwareQualityRatings")
- void compute_ratingForSoftwareQuality(double percent, Rating expectedRating) {
- assertThat(computeAToDRating(percent)).isEqualTo(expectedRating);
- }
-
@Test
void compute_percent() {
assertThat(computePercent(0, 0)).isEmpty();
diff --git a/server/sonar-web/config/jest/SetupReactTestingLibrary.ts b/server/sonar-web/config/jest/SetupReactTestingLibrary.ts
index 6755fa753b9..d847ef36ad7 100644
--- a/server/sonar-web/config/jest/SetupReactTestingLibrary.ts
+++ b/server/sonar-web/config/jest/SetupReactTestingLibrary.ts
@@ -59,4 +59,37 @@ expect.extend({
return result;
},
+ async toHaveAPopoverWithContent(received: any, content: string) {
+ const user = userEvent.setup({ pointerEventsCheck: PointerEventsCheckLevel.Never });
+
+ if (!(received instanceof Element)) {
+ return {
+ pass: false,
+ message: () => `Received object is not an HTMLElement, and cannot have a tooltip`,
+ };
+ }
+
+ await user.click(received);
+
+ const popover = await screen.findByRole('dialog');
+
+ const result = popover.textContent?.includes(content)
+ ? {
+ pass: true,
+ message: () => `Tooltip content "${popover.textContent}" contains expected "${content}"`,
+ }
+ : {
+ pass: false,
+ message: () =>
+ `Tooltip content "${popover.textContent}" does not contain expected "${content}"`,
+ };
+
+ await user.keyboard('{Escape}');
+
+ await waitFor(() => {
+ expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
+ });
+
+ return result;
+ },
});
diff --git a/server/sonar-web/design-system/src/components/ColorsLegend.tsx b/server/sonar-web/design-system/src/components/ColorsLegend.tsx
index 5974a136379..b1b111d0d47 100644
--- a/server/sonar-web/design-system/src/components/ColorsLegend.tsx
+++ b/server/sonar-web/design-system/src/components/ColorsLegend.tsx
@@ -64,12 +64,12 @@ export function ColorsLegend(props: ColorLegendProps) {
? {
backgroundColor:
color.backgroundColor ??
- themeColor(`bubble.legacy.${(idx + 1) as BubbleColorVal}`)({
+ themeColor(`bubble.${(idx + 1) as BubbleColorVal}`)({
theme,
}),
borderColor:
color.borderColor ??
- themeContrast(`bubble.legacy.${(idx + 1) as BubbleColorVal}`)({
+ themeContrast(`bubble.${(idx + 1) as BubbleColorVal}`)({
theme,
}),
}
diff --git a/server/sonar-web/design-system/src/components/FacetBox.tsx b/server/sonar-web/design-system/src/components/FacetBox.tsx
index 792eb273123..f92d58c30a0 100644
--- a/server/sonar-web/design-system/src/components/FacetBox.tsx
+++ b/server/sonar-web/design-system/src/components/FacetBox.tsx
@@ -89,37 +89,38 @@ export function FacetBox(props: FacetBoxProps) {
inner={inner}
>
<Header>
- <ChevronAndTitle
- aria-controls={`${id}-panel`}
- aria-disabled={!expandable}
- aria-expanded={open}
- aria-label={ariaLabel ?? name}
- expandable={expandable}
- id={`${id}-header`}
- onClick={() => {
- if (!disabled) {
- onClick?.(!open);
- }
- }}
- >
- {expandable && <OpenCloseIndicator aria-hidden open={open} />}
-
- {disabled ? (
- <Tooltip content={disabledHelper}>
- <HeaderTitle
- aria-disabled
- aria-label={`${name}, ${disabledHelper ?? ''}`}
- disabled={disabled}
- >
- {name}
- </HeaderTitle>
- </Tooltip>
- ) : (
- <HeaderTitle>{name}</HeaderTitle>
- )}
-
+ <TitleWithHelp>
+ <ChevronAndTitle
+ aria-controls={`${id}-panel`}
+ aria-disabled={!expandable}
+ aria-expanded={open}
+ aria-label={ariaLabel ?? name}
+ expandable={expandable}
+ id={`${id}-header`}
+ onClick={() => {
+ if (!disabled) {
+ onClick?.(!open);
+ }
+ }}
+ >
+ {expandable && <OpenCloseIndicator aria-hidden open={open} />}
+
+ {disabled ? (
+ <Tooltip content={disabledHelper}>
+ <HeaderTitle
+ aria-disabled
+ aria-label={`${name}, ${disabledHelper ?? ''}`}
+ disabled={disabled}
+ >
+ {name}
+ </HeaderTitle>
+ </Tooltip>
+ ) : (
+ <HeaderTitle>{name}</HeaderTitle>
+ )}
+ </ChevronAndTitle>
{help && <span className="sw-ml-1">{help}</span>}
- </ChevronAndTitle>
+ </TitleWithHelp>
{<Spinner loading={loading} />}
@@ -173,6 +174,11 @@ const BadgeAndIcons = styled.div`
${tw`sw-gap-2`};
`;
+const TitleWithHelp = styled.div`
+ ${tw`sw-flex`};
+ ${tw`sw-items-center`};
+`;
+
const ChevronAndTitle = styled(BareButton)<{
expandable?: boolean;
}>`
diff --git a/server/sonar-web/design-system/src/components/Pill.tsx b/server/sonar-web/design-system/src/components/Pill.tsx
index acd24669bda..c2eb3fb56c5 100644
--- a/server/sonar-web/design-system/src/components/Pill.tsx
+++ b/server/sonar-web/design-system/src/components/Pill.tsx
@@ -24,20 +24,31 @@ import tw from 'twin.macro';
import { themeColor, themeContrast } from '../helpers/theme';
import { ThemeColors } from '../types/theme';
-type PillVariant = 'danger' | 'warning' | 'info' | 'accent';
+export enum PillVariant {
+ Critical = 'critical',
+ Danger = 'danger',
+ Warning = 'warning',
+ Caution = 'caution',
+ Info = 'info',
+ Accent = 'accent',
+}
const variantThemeColors: Record<PillVariant, ThemeColors> = {
- danger: 'pillDanger',
- warning: 'pillWarning',
- info: 'pillInfo',
- accent: 'pillAccent',
+ [PillVariant.Critical]: 'pillCritical',
+ [PillVariant.Danger]: 'pillDanger',
+ [PillVariant.Warning]: 'pillWarning',
+ [PillVariant.Caution]: 'pillCaution',
+ [PillVariant.Info]: 'pillInfo',
+ [PillVariant.Accent]: 'pillAccent',
};
const variantThemeBorderColors: Record<PillVariant, ThemeColors> = {
- danger: 'pillDangerBorder',
- warning: 'pillWarningBorder',
- info: 'pillInfoBorder',
- accent: 'pillAccentBorder',
+ [PillVariant.Critical]: 'pillCriticalBorder',
+ [PillVariant.Danger]: 'pillDangerBorder',
+ [PillVariant.Warning]: 'pillWarningBorder',
+ [PillVariant.Caution]: 'pillCautionBorder',
+ [PillVariant.Info]: 'pillInfoBorder',
+ [PillVariant.Accent]: 'pillAccentBorder',
};
interface PillProps {
@@ -84,7 +95,7 @@ const StyledPill = styled.span<{
background-color: ${({ variant }) => themeColor(variantThemeColors[variant])};
color: ${({ variant }) => themeContrast(variantThemeColors[variant])};
- border-style: ${({ variant }) => (variant === 'accent' ? 'hidden' : 'solid')};
+ border-style: ${({ variant }) => (variant === PillVariant.Accent ? 'hidden' : 'solid')};
border-color: ${({ variant }) => themeColor(variantThemeBorderColors[variant])};
`;
@@ -95,7 +106,7 @@ const StyledPillButton = styled.button<{
background-color: ${({ variant }) => themeColor(variantThemeColors[variant])};
color: ${({ variant }) => themeContrast(variantThemeColors[variant])};
- border-style: ${({ variant }) => (variant === 'accent' ? 'hidden' : 'solid')};
+ border-style: ${({ variant }) => (variant === PillVariant.Accent ? 'hidden' : 'solid')};
border-color: ${({ variant }) => themeColor(variantThemeBorderColors[variant])};
cursor: pointer;
diff --git a/server/sonar-web/design-system/src/components/__tests__/Pill-test.tsx b/server/sonar-web/design-system/src/components/__tests__/Pill-test.tsx
index 5c385ce0cec..014f020809e 100644
--- a/server/sonar-web/design-system/src/components/__tests__/Pill-test.tsx
+++ b/server/sonar-web/design-system/src/components/__tests__/Pill-test.tsx
@@ -19,9 +19,9 @@
*/
import { screen } from '@testing-library/react';
import { render } from '../../helpers/testUtils';
-import { Pill } from '../Pill';
+import { Pill, PillVariant } from '../Pill';
it('should render correctly', () => {
- render(<Pill variant="accent">23</Pill>);
+ render(<Pill variant={PillVariant.Accent}>23</Pill>);
expect(screen.getByText('23')).toBeInTheDocument();
});
diff --git a/server/sonar-web/design-system/src/components/__tests__/__snapshots__/HotspotRating-test.tsx.snap b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/HotspotRating-test.tsx.snap
index 900f1f226d9..741beaababd 100644
--- a/server/sonar-web/design-system/src/components/__tests__/__snapshots__/HotspotRating-test.tsx.snap
+++ b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/HotspotRating-test.tsx.snap
@@ -74,7 +74,7 @@ exports[`should render HotspotRating with MEDIUM rating 1`] = `
<circle
cx="8"
cy="8"
- fill="rgb(254,205,202)"
+ fill="rgb(255,214,175)"
r="7"
/>
<path
diff --git a/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityBlockerIcon.tsx b/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityBlockerIcon.tsx
new file mode 100644
index 00000000000..bf8c4b08331
--- /dev/null
+++ b/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityBlockerIcon.tsx
@@ -0,0 +1,43 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { useTheme } from '@emotion/react';
+import { themeColor } from '../../helpers';
+import { CustomIcon, IconProps } from './Icon';
+
+export function SoftwareImpactSeverityBlockerIcon({
+ disabled,
+ ...iconProps
+}: IconProps & { disabled?: boolean }) {
+ const theme = useTheme();
+ const color = disabled
+ ? 'iconSoftwareImpactSeverityDisabled'
+ : 'iconSoftwareImpactSeverityBlocker';
+
+ return (
+ <CustomIcon viewBox="0 0 14 14" {...iconProps}>
+ <path
+ clipRule="evenodd"
+ d="M7 13.375C10.5208 13.375 13.375 10.5208 13.375 7C13.375 3.47918 10.5208 0.625 7 0.625C3.47918 0.625 0.625 3.47918 0.625 7C0.625 10.5208 3.47918 13.375 7 13.375ZM4 6C3.44772 6 3 6.44772 3 7C3 7.55228 3.44772 8 4 8H10C10.5523 8 11 7.55228 11 7C11 6.44772 10.5523 6 10 6H4Z"
+ fill={themeColor(color)({ theme })}
+ fillRule="evenodd"
+ />
+ </CustomIcon>
+ );
+}
diff --git a/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityHighIcon.tsx b/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityHighIcon.tsx
index 52b7aa4e977..dd5cd03ed2e 100644
--- a/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityHighIcon.tsx
+++ b/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityHighIcon.tsx
@@ -29,10 +29,10 @@ export function SoftwareImpactSeverityHighIcon({
const color = disabled ? 'iconSoftwareImpactSeverityDisabled' : 'iconSoftwareImpactSeverityHigh';
return (
- <CustomIcon {...iconProps}>
+ <CustomIcon viewBox="0 0 14 14" {...iconProps}>
<path
clipRule="evenodd"
- d="M7 14C10.866 14 14 10.866 14 7C14 3.13401 10.866 0 7 0C3.13401 0 0 3.13401 0 7C0 10.866 3.13401 14 7 14ZM4.14421 5.43198C4.05583 5.47727 4 5.56986 4 5.67113V9.73238C4 9.91906 4.18192 10.0483 4.35247 9.98273L6.9084 9.00033C6.96746 8.97763 7.03254 8.97763 7.0916 9.00033L9.64753 9.98273C9.81808 10.0483 10 9.91906 10 9.73238V5.67113C10 5.56986 9.94417 5.47727 9.85579 5.43198L7.11666 4.02823C7.04322 3.99059 6.95678 3.99059 6.88334 4.02823L4.14421 5.43198Z"
+ d="M7 13.375C10.5208 13.375 13.375 10.5208 13.375 7C13.375 3.47918 10.5208 0.625 7 0.625C3.47918 0.625 0.625 3.47918 0.625 7C0.625 10.5208 3.47918 13.375 7 13.375ZM4.3983 5.57213C4.31781 5.61338 4.26697 5.6977 4.26697 5.78993V9.48856C4.26697 9.65858 4.43265 9.77626 4.58796 9.71657L6.91569 8.82188C6.96948 8.80121 7.02875 8.80121 7.08253 8.82188L9.41026 9.71657C9.56557 9.77626 9.73125 9.65858 9.73125 9.48856V5.78993C9.73125 5.6977 9.68041 5.61338 9.59992 5.57213L7.10536 4.29371C7.03847 4.25944 6.95975 4.25944 6.89286 4.29371L4.3983 5.57213Z"
fill={themeColor(color)({ theme })}
fillRule="evenodd"
/>
diff --git a/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityInfoIcon.tsx b/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityInfoIcon.tsx
new file mode 100644
index 00000000000..7939c630b8d
--- /dev/null
+++ b/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityInfoIcon.tsx
@@ -0,0 +1,46 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import styled from '@emotion/styled';
+import { IconInfo } from '@sonarsource/echoes-react';
+import { IconProps } from './Icon';
+
+const defaultIconSize = 15;
+
+export function SoftwareImpactSeverityInfoIcon({
+ disabled,
+ ...iconProps
+}: IconProps & { disabled?: boolean }) {
+ const color = disabled ? 'echoes-color-icon-disabled' : 'echoes-color-icon-info';
+
+ return <StyledIconInfo color={color} {...iconProps} />;
+}
+
+// Info icon is the only one that is imported from echoes, so we need to adjust its size
+const StyledIconInfo = styled(IconInfo)`
+ ${(props: IconProps & { disabled?: boolean }) => {
+ let size = props.width ?? props.height;
+ size = size ? size + 1 : defaultIconSize;
+
+ return `
+ font-size: ${size}px;
+ margin-left: -0.5px;
+ `;
+ }};
+`;
diff --git a/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityLowIcon.tsx b/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityLowIcon.tsx
index 305cee4beda..ef943283fed 100644
--- a/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityLowIcon.tsx
+++ b/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityLowIcon.tsx
@@ -29,10 +29,10 @@ export function SoftwareImpactSeverityLowIcon({
const color = disabled ? 'iconSoftwareImpactSeverityDisabled' : 'iconSoftwareImpactSeverityLow';
return (
- <CustomIcon {...iconProps}>
+ <CustomIcon viewBox="0 0 14 14" {...iconProps}>
<path
clipRule="evenodd"
- d="M7 14C10.866 14 14 10.866 14 7C14 3.13401 10.866 0 7 0C3.13401 0 0 3.13401 0 7C0 10.866 3.13401 14 7 14ZM3.7019 6.46256L6.46967 9.23033C6.76256 9.52322 7.23744 9.52322 7.53033 9.23033L10.2981 6.46256C10.591 6.16967 10.591 5.6948 10.2981 5.4019C10.0052 5.10901 9.53033 5.10901 9.23744 5.4019L7 7.63934L4.76256 5.4019C4.46967 5.10901 3.9948 5.10901 3.7019 5.4019C3.40901 5.6948 3.40901 6.16967 3.7019 6.46256Z"
+ d="M7 13.375C10.5208 13.375 13.375 10.5208 13.375 7C13.375 3.47918 10.5208 0.625 7 0.625C3.47918 0.625 0.625 3.47918 0.625 7C0.625 10.5208 3.47918 13.375 7 13.375ZM3.94899 6.55761L6.46964 9.07825C6.76253 9.37115 7.2374 9.37115 7.5303 9.07825L10.0509 6.55761C10.3438 6.26472 10.3438 5.78984 10.0509 5.49695C9.75805 5.20406 9.28317 5.20406 8.99028 5.49695L6.99997 7.48727L5.00965 5.49695C4.71676 5.20406 4.24188 5.20406 3.94899 5.49695C3.6561 5.78984 3.6561 6.26472 3.94899 6.55761Z"
fill={themeColor(color)({ theme })}
fillRule="evenodd"
/>
diff --git a/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityMediumIcon.tsx b/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityMediumIcon.tsx
index 5d54e0f6e91..417ff73c76c 100644
--- a/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityMediumIcon.tsx
+++ b/server/sonar-web/design-system/src/components/icons/SoftwareImpactSeverityMediumIcon.tsx
@@ -31,10 +31,10 @@ export function SoftwareImpactSeverityMediumIcon({
: 'iconSoftwareImpactSeverityMedium';
return (
- <CustomIcon {...iconProps}>
+ <CustomIcon viewBox="0 0 14 14" {...iconProps}>
<path
clipRule="evenodd"
- d="M7 14C10.866 14 14 10.866 14 7C14 3.13401 10.866 0 7 0C3.13401 0 0 3.13401 0 7C0 10.866 3.13401 14 7 14ZM10.2981 7.96967L7.53033 5.2019C7.23744 4.90901 6.76256 4.90901 6.46967 5.2019L3.7019 7.96967C3.40901 8.26256 3.40901 8.73744 3.7019 9.03033C3.9948 9.32322 4.46967 9.32322 4.76256 9.03033L7 6.79289L9.23744 9.03033C9.53033 9.32322 10.0052 9.32322 10.2981 9.03033C10.591 8.73744 10.591 8.26256 10.2981 7.96967Z"
+ d="M7 13.375C10.5208 13.375 13.375 10.5208 13.375 7C13.375 3.47918 10.5208 0.625 7 0.625C3.47918 0.625 0.625 3.47918 0.625 7C0.625 10.5208 3.47918 13.375 7 13.375ZM10.051 7.83547L7.53033 5.31482C7.23744 5.02193 6.76256 5.02193 6.46967 5.31482L3.94903 7.83547C3.65613 8.12836 3.65613 8.60324 3.94903 8.89613C4.24192 9.18902 4.71679 9.18902 5.00969 8.89613L7 6.90581L8.99031 8.89613C9.28321 9.18902 9.75808 9.18902 10.051 8.89613C10.3439 8.60324 10.3439 8.12836 10.051 7.83547Z"
fill={themeColor(color)({ theme })}
fillRule="evenodd"
/>
diff --git a/server/sonar-web/design-system/src/components/icons/index.ts b/server/sonar-web/design-system/src/components/icons/index.ts
index 1cccc42ba0c..45d0a0c4ff9 100644
--- a/server/sonar-web/design-system/src/components/icons/index.ts
+++ b/server/sonar-web/design-system/src/components/icons/index.ts
@@ -78,7 +78,9 @@ export { SeverityInfoIcon } from './SeverityInfoIcon';
export { SeverityMajorIcon } from './SeverityMajorIcon';
export { SeverityMinorIcon } from './SeverityMinorIcon';
export { SnoozeCircleIcon } from './SnoozeCircleIcon';
+export { SoftwareImpactSeverityBlockerIcon } from './SoftwareImpactSeverityBlockerIcon';
export { SoftwareImpactSeverityHighIcon } from './SoftwareImpactSeverityHighIcon';
+export { SoftwareImpactSeverityInfoIcon } from './SoftwareImpactSeverityInfoIcon';
export { SoftwareImpactSeverityLowIcon } from './SoftwareImpactSeverityLowIcon';
export { SoftwareImpactSeverityMediumIcon } from './SoftwareImpactSeverityMediumIcon';
export { SortAscendIcon } from './SortAscendIcon';
diff --git a/server/sonar-web/design-system/src/components/index.ts b/server/sonar-web/design-system/src/components/index.ts
index 46771d97fd7..da0bc81f8ef 100644
--- a/server/sonar-web/design-system/src/components/index.ts
+++ b/server/sonar-web/design-system/src/components/index.ts
@@ -76,7 +76,7 @@ export * from './MultiSelector';
export * from './NavBarTabs';
export * from './NewCodeLegend';
export * from './OutsideClickHandler';
-export { Pill } from './Pill';
+export * from './Pill';
export * from './popups';
export { QualityGateIndicator } from './QualityGateIndicator';
export * from './SearchHighlighter';
diff --git a/server/sonar-web/design-system/src/sonar-aligned/components/MetricsRatingBadge.tsx b/server/sonar-web/design-system/src/sonar-aligned/components/MetricsRatingBadge.tsx
index 9276c9b286a..2ca4a739a7f 100644
--- a/server/sonar-web/design-system/src/sonar-aligned/components/MetricsRatingBadge.tsx
+++ b/server/sonar-web/design-system/src/sonar-aligned/components/MetricsRatingBadge.tsx
@@ -26,7 +26,6 @@ import { RatingLabel } from '../types/measures';
type sizeType = keyof typeof SIZE_MAPPING;
interface Props extends React.AriaAttributes {
className?: string;
- isLegacy?: boolean;
label?: string;
rating?: RatingLabel;
size?: sizeType;
@@ -41,10 +40,7 @@ const SIZE_MAPPING = {
};
export const MetricsRatingBadge = forwardRef<HTMLDivElement, Props>(
- (
- { className, size = 'sm', isLegacy = true, label, rating, ...ariaAttrs }: Readonly<Props>,
- ref,
- ) => {
+ ({ className, size = 'sm', label, rating, ...ariaAttrs }: Readonly<Props>, ref) => {
if (!rating) {
return (
<StyledNoRatingBadge
@@ -62,7 +58,6 @@ export const MetricsRatingBadge = forwardRef<HTMLDivElement, Props>(
<MetricsRatingBadgeStyled
aria-label={label}
className={className}
- isLegacy={isLegacy}
rating={rating}
ref={ref}
size={SIZE_MAPPING[size]}
@@ -97,7 +92,6 @@ const getFontSize = (size: string) => {
};
const MetricsRatingBadgeStyled = styled.div<{
- isLegacy: boolean;
rating: RatingLabel;
size: string;
}>`
@@ -105,8 +99,7 @@ const MetricsRatingBadgeStyled = styled.div<{
height: ${getProp('size')};
color: ${({ rating }) => themeContrast(`rating.${rating}`)};
font-size: ${({ size }) => getFontSize(size)};
- background-color: ${({ rating, isLegacy }) =>
- themeColor(`rating.${isLegacy ? 'legacy.' : ''}${rating}`)};
+ background-color: ${({ rating }) => themeColor(`rating.${rating}`)};
user-select: none;
display: inline-flex;
diff --git a/server/sonar-web/design-system/src/theme/light.ts b/server/sonar-web/design-system/src/theme/light.ts
index ef98fce9ac9..77301732b64 100644
--- a/server/sonar-web/design-system/src/theme/light.ts
+++ b/server/sonar-web/design-system/src/theme/light.ts
@@ -341,10 +341,14 @@ export const lightTheme = {
badgeCounterFailedBorder: COLORS.red[200],
// pills
+ pillCritical: COLORS.red[100],
+ pillCriticalBorder: COLORS.red[800],
pillDanger: COLORS.red[50],
- pillDangerBorder: COLORS.red[300],
- pillWarning: COLORS.yellow[50],
- pillWarningBorder: COLORS.yellow[300],
+ pillDangerBorder: COLORS.red[600],
+ pillWarning: COLORS.orange[50],
+ pillWarningBorder: COLORS.orange[300],
+ pillCaution: COLORS.yellow[50],
+ pillCautionBorder: COLORS.yellow[300],
pillInfo: COLORS.blue[50],
pillInfoBorder: COLORS.blue[300],
pillAccent: COLORS.indigo[50],
@@ -401,9 +405,11 @@ export const lightTheme = {
destructiveIconFocus: danger.default,
// icons
- iconSoftwareImpactSeverityHigh: COLORS.red[500],
- iconSoftwareImpactSeverityMedium: COLORS.yellow[700],
- iconSoftwareImpactSeverityLow: COLORS.blue[700],
+ iconSoftwareImpactSeverityBlocker: COLORS.red[800],
+ iconSoftwareImpactSeverityHigh: COLORS.red[600],
+ iconSoftwareImpactSeverityMedium: COLORS.orange[400],
+ iconSoftwareImpactSeverityLow: COLORS.yellow[500],
+ iconSoftwareImpactSeverityInfo: COLORS.blue[600],
iconSoftwareImpactSeverityDisabled: COLORS.blueGrey[300],
iconSeverityMajor: danger.light,
iconSeverityMinor: COLORS.yellowGreen[400],
@@ -467,17 +473,10 @@ export const lightTheme = {
sizeIndicator: COLORS.blue[500],
// rating colors
- 'rating.legacy.A': COLORS.green[200],
- 'rating.legacy.B': COLORS.yellowGreen[200],
- 'rating.legacy.C': COLORS.yellow[200],
- 'rating.legacy.D': COLORS.orange[200],
- 'rating.legacy.E': COLORS.red[200],
-
- // rating colors
'rating.A': COLORS.green[200],
'rating.B': COLORS.yellowGreen[200],
'rating.C': COLORS.yellow[200],
- 'rating.D': COLORS.red[200],
+ 'rating.D': COLORS.orange[200],
'rating.E': COLORS.red[200],
'portfolio.rating.A.text': COLORS.green[900],
@@ -489,9 +488,9 @@ export const lightTheme = {
'portfolio.rating.C.text': COLORS.yellow[900],
'portfolio.rating.C.background': COLORS.yellow[100],
'portfolio.rating.C.border': COLORS.yellow[500],
- 'portfolio.rating.D.text': COLORS.red[900],
- 'portfolio.rating.D.background': COLORS.red[100],
- 'portfolio.rating.D.border': COLORS.red[400],
+ 'portfolio.rating.D.text': COLORS.orange[900],
+ 'portfolio.rating.D.background': COLORS.orange[100],
+ 'portfolio.rating.D.border': COLORS.orange[300],
'portfolio.rating.E.text': COLORS.red[900],
'portfolio.rating.E.background': COLORS.red[100],
'portfolio.rating.E.border': COLORS.red[400],
@@ -499,25 +498,6 @@ export const lightTheme = {
'portfolio.rating.NONE.background': COLORS.blueGrey[50],
'portfolio.rating.NONE.border': COLORS.blueGrey[200],
- 'portfolio.rating.legacy.A.text': COLORS.green[900],
- 'portfolio.rating.legacy.A.background': COLORS.green[100],
- 'portfolio.rating.legacy.A.border': COLORS.green[400],
- 'portfolio.rating.legacy.B.text': COLORS.yellowGreen[900],
- 'portfolio.rating.legacy.B.background': COLORS.yellowGreen[100],
- 'portfolio.rating.legacy.B.border': COLORS.yellowGreen[400],
- 'portfolio.rating.legacy.C.text': COLORS.yellow[900],
- 'portfolio.rating.legacy.C.background': COLORS.yellow[100],
- 'portfolio.rating.legacy.C.border': COLORS.yellow[500],
- 'portfolio.rating.legacy.D.text': COLORS.orange[900],
- 'portfolio.rating.legacy.D.background': COLORS.orange[100],
- 'portfolio.rating.legacy.D.border': COLORS.orange[300],
- 'portfolio.rating.legacy.E.text': COLORS.red[900],
- 'portfolio.rating.legacy.E.background': COLORS.red[100],
- 'portfolio.rating.legacy.E.border': COLORS.red[400],
- 'portfolio.rating.legacy.NONE.text': COLORS.blueGrey[300],
- 'portfolio.rating.legacy.NONE.background': COLORS.blueGrey[50],
- 'portfolio.rating.legacy.NONE.border': COLORS.blueGrey[200],
-
// rating donut outside circle indicators
'ratingDonut.A': COLORS.green[400],
'ratingDonut.B': COLORS.yellowGreen[400],
@@ -676,29 +656,18 @@ export const lightTheme = {
// bubble charts
bubbleChartLine: COLORS.grey[50],
bubbleDefault: [...COLORS.blue[500], 0.3],
- 'bubble.legacy.1': [...COLORS.green[500], 0.3],
- 'bubble.legacy.2': [...COLORS.yellowGreen[500], 0.3],
- 'bubble.legacy.3': [...COLORS.yellow[500], 0.3],
- 'bubble.legacy.4': [...COLORS.orange[500], 0.3],
- 'bubble.legacy.5': [...COLORS.red[500], 0.3],
'bubble.1': [...COLORS.green[500], 0.3],
'bubble.2': [...COLORS.yellowGreen[500], 0.3],
'bubble.3': [...COLORS.yellow[500], 0.3],
- 'bubble.4': [...COLORS.red[500], 0.3],
+ 'bubble.4': [...COLORS.orange[500], 0.3],
'bubble.5': [...COLORS.red[500], 0.3],
// TreeMap Colors
- 'treeMap.legacy.A': COLORS.green[500],
- 'treeMap.legacy.B': COLORS.yellowGreen[500],
- 'treeMap.legacy.C': COLORS.yellow[500],
- 'treeMap.legacy.D': COLORS.orange[500],
- 'treeMap.legacy.E': COLORS.red[500],
-
'treeMap.A': COLORS.green[500],
'treeMap.B': COLORS.yellowGreen[500],
'treeMap.C': COLORS.yellow[500],
- 'treeMap.D': COLORS.red[500],
+ 'treeMap.D': COLORS.orange[500],
'treeMap.E': COLORS.red[500],
'treeMap.NA1': COLORS.blueGrey[300],
@@ -843,12 +812,11 @@ export const lightTheme = {
badgeCounterFailed: danger.dark,
// pills
- pillDanger: COLORS.red[800],
- pillDangerIcon: COLORS.red[700],
- pillWarning: COLORS.yellow[800],
- pillWarningIcon: COLORS.yellow[700],
+ pillCritical: COLORS.red[800],
+ pillDanger: COLORS.red[700],
+ pillWarning: COLORS.orange[800],
+ pillCaution: COLORS.yellow[800],
pillInfo: COLORS.blue[800],
- pillInfoIcon: COLORS.blue[700],
pillAccent: COLORS.indigo[500],
// project cards
@@ -945,12 +913,6 @@ export const lightTheme = {
// page
pageBlock: secondary.darker,
- // overview software impact breakdown
- overviewSoftwareImpactSeverityNeutral: COLORS.blueGrey[500],
- overviewSoftwareImpactSeverityHigh: COLORS.red[700],
- overviewSoftwareImpactSeverityMedium: COLORS.yellow[800],
- overviewSoftwareImpactSeverityLow: COLORS.blue[800],
-
// graph - chart
graphZoomHandleColor: COLORS.white,
@@ -967,16 +929,11 @@ export const lightTheme = {
// bubble charts
bubbleDefault: COLORS.blue[500],
- 'bubble.legacy.1': COLORS.green[500],
- 'bubble.legacy.2': COLORS.yellowGreen[500],
- 'bubble.legacy.3': COLORS.yellow[500],
- 'bubble.legacy.4': COLORS.orange[500],
- 'bubble.legacy.5': COLORS.red[500],
'bubble.1': COLORS.green[500],
'bubble.2': COLORS.yellowGreen[500],
'bubble.3': COLORS.yellow[500],
- 'bubble.4': COLORS.red[500],
+ 'bubble.4': COLORS.orange[500],
'bubble.5': COLORS.red[500],
// news bar
diff --git a/server/sonar-web/src/main/js/app/components/ChangeInCalculationPill.tsx b/server/sonar-web/src/main/js/app/components/ChangeInCalculationPill.tsx
index bdf31ea2a25..af82e478ded 100644
--- a/server/sonar-web/src/main/js/app/components/ChangeInCalculationPill.tsx
+++ b/server/sonar-web/src/main/js/app/components/ChangeInCalculationPill.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { Popover } from '@sonarsource/echoes-react';
-import { Pill } from 'design-system';
+import { Pill, PillVariant } from 'design-system';
import * as React from 'react';
import DocumentationLink from '../../components/common/DocumentationLink';
import { DocLink } from '../../helpers/doc-links';
@@ -49,7 +49,11 @@ export default function ChangeInCalculation({ qualifier }: Readonly<Props>) {
</DocumentationLink>
}
>
- <Pill variant="info" className="sw-ml-2" onClick={() => setIsPopoverOpen(!isPopoverOpen)}>
+ <Pill
+ variant={PillVariant.Accent}
+ className="sw-ml-2"
+ onClick={() => setIsPopoverOpen(!isPopoverOpen)}
+ >
{translate('projects.awaiting_scan')}
</Pill>
</Popover>
diff --git a/server/sonar-web/src/main/js/app/components/metrics/RatingComponent.tsx b/server/sonar-web/src/main/js/app/components/metrics/RatingComponent.tsx
index ce59c6e03ce..f63301ef1f3 100644
--- a/server/sonar-web/src/main/js/app/components/metrics/RatingComponent.tsx
+++ b/server/sonar-web/src/main/js/app/components/metrics/RatingComponent.tsx
@@ -61,6 +61,8 @@ function isNewRatingMetric(metricKey: MetricKey) {
const useGetMetricKeyForRating = (ratingMetric: RatingMetricKeys): MetricKey | null => {
const { data: isLegacy, isLoading } = useIsLegacyCCTMode();
+ const hasSoftwareQualityRating = !!SOFTWARE_QUALITY_RATING_METRICS_MAP[ratingMetric];
+
if (isNewRatingMetric(ratingMetric)) {
return ratingMetric;
}
@@ -68,7 +70,9 @@ const useGetMetricKeyForRating = (ratingMetric: RatingMetricKeys): MetricKey | n
if (isLoading) {
return null;
}
- return isLegacy ? ratingMetric : SOFTWARE_QUALITY_RATING_METRICS_MAP[ratingMetric];
+ return isLegacy || !hasSoftwareQualityRating
+ ? ratingMetric
+ : SOFTWARE_QUALITY_RATING_METRICS_MAP[ratingMetric];
};
export default function RatingComponent(props: Readonly<Props>) {
@@ -108,7 +112,6 @@ export default function RatingComponent(props: Readonly<Props>) {
const badge = (
<MetricsRatingBadge
label={getLabel ? getLabel(rating) : (value ?? '—')}
- isLegacy={measure?.metric ? !isNewRatingMetric(measure.metric as MetricKey) : false}
rating={rating}
size={size}
className={className}
diff --git a/server/sonar-web/src/main/js/apps/code/__tests__/__snapshots__/utils-test.tsx.snap b/server/sonar-web/src/main/js/apps/code/__tests__/__snapshots__/utils-test.tsx.snap
index bd05e186171..2ba88be1e1d 100644
--- a/server/sonar-web/src/main/js/apps/code/__tests__/__snapshots__/utils-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/code/__tests__/__snapshots__/utils-test.tsx.snap
@@ -19,7 +19,6 @@ exports[`getCodeMetrics should return the right metrics for apps 1`] = `
exports[`getCodeMetrics should return the right metrics for portfolios 1`] = `
[
"releasability_rating",
- "software_quality_releasability_rating",
"new_security_rating",
"new_software_quality_security_rating",
"new_reliability_rating",
@@ -27,10 +26,8 @@ exports[`getCodeMetrics should return the right metrics for portfolios 1`] = `
"new_maintainability_rating",
"new_software_quality_maintainability_rating",
"new_security_review_rating",
- "new_software_quality_security_review_rating",
"new_lines",
"releasability_rating",
- "software_quality_releasability_rating",
"security_rating",
"software_quality_security_rating",
"reliability_rating",
@@ -38,7 +35,6 @@ exports[`getCodeMetrics should return the right metrics for portfolios 1`] = `
"sqale_rating",
"software_quality_maintainability_rating",
"security_review_rating",
- "software_quality_security_review_rating",
"ncloc",
]
`;
@@ -46,7 +42,6 @@ exports[`getCodeMetrics should return the right metrics for portfolios 1`] = `
exports[`getCodeMetrics should return the right metrics for portfolios 2`] = `
[
"releasability_rating",
- "software_quality_releasability_rating",
"new_security_rating",
"new_software_quality_security_rating",
"new_reliability_rating",
@@ -54,10 +49,8 @@ exports[`getCodeMetrics should return the right metrics for portfolios 2`] = `
"new_maintainability_rating",
"new_software_quality_maintainability_rating",
"new_security_review_rating",
- "new_software_quality_security_review_rating",
"new_lines",
"releasability_rating",
- "software_quality_releasability_rating",
"security_rating",
"software_quality_security_rating",
"reliability_rating",
@@ -65,7 +58,6 @@ exports[`getCodeMetrics should return the right metrics for portfolios 2`] = `
"sqale_rating",
"software_quality_maintainability_rating",
"security_review_rating",
- "software_quality_security_review_rating",
"ncloc",
"alert_status",
]
@@ -74,7 +66,6 @@ exports[`getCodeMetrics should return the right metrics for portfolios 2`] = `
exports[`getCodeMetrics should return the right metrics for portfolios 3`] = `
[
"releasability_rating",
- "software_quality_releasability_rating",
"new_security_rating",
"new_software_quality_security_rating",
"new_reliability_rating",
@@ -82,7 +73,6 @@ exports[`getCodeMetrics should return the right metrics for portfolios 3`] = `
"new_maintainability_rating",
"new_software_quality_maintainability_rating",
"new_security_review_rating",
- "new_software_quality_security_review_rating",
"new_lines",
"alert_status",
]
@@ -91,7 +81,6 @@ exports[`getCodeMetrics should return the right metrics for portfolios 3`] = `
exports[`getCodeMetrics should return the right metrics for portfolios 4`] = `
[
"releasability_rating",
- "software_quality_releasability_rating",
"security_rating",
"software_quality_security_rating",
"reliability_rating",
@@ -99,7 +88,6 @@ exports[`getCodeMetrics should return the right metrics for portfolios 4`] = `
"sqale_rating",
"software_quality_maintainability_rating",
"security_review_rating",
- "software_quality_security_review_rating",
"ncloc",
"alert_status",
]
diff --git a/server/sonar-web/src/main/js/apps/code/components/CodeAppRenderer.tsx b/server/sonar-web/src/main/js/apps/code/components/CodeAppRenderer.tsx
index 021f688d401..173311aee9a 100644
--- a/server/sonar-web/src/main/js/apps/code/components/CodeAppRenderer.tsx
+++ b/server/sonar-web/src/main/js/apps/code/components/CodeAppRenderer.tsx
@@ -49,6 +49,7 @@ import {
areCCTMeasuresComputed,
areSoftwareQualityRatingsComputed,
} from '../../../helpers/measures';
+import { useIsLegacyCCTMode } from '../../../queries/settings';
import { BranchLike } from '../../../types/branch-like';
import { isApplication } from '../../../types/component';
import { Component, ComponentMeasure, Dict, Metric } from '../../../types/types';
@@ -108,6 +109,8 @@ export default function CodeAppRenderer(props: Readonly<Props>) {
const showComponentList = sourceViewer === undefined && components.length > 0 && !showSearch;
+ const { data: isLegacy, isLoading: isLoadingLegacy } = useIsLegacyCCTMode();
+
const metricKeys = intersection(
getCodeMetrics(component.qualifier, branchLike, { newCode: newCodeSelected }),
Object.keys(metrics),
@@ -121,10 +124,10 @@ export default function CodeAppRenderer(props: Readonly<Props>) {
);
const filteredMetrics = difference(metricKeys, [
- ...(allComponentsHaveSoftwareQualityMeasures
+ ...(allComponentsHaveSoftwareQualityMeasures && !isLegacy
? OLD_TAXONOMY_METRICS
: CCT_SOFTWARE_QUALITY_METRICS),
- ...(allComponentsHaveRatings
+ ...(allComponentsHaveRatings && !isLegacy
? [...OLD_TAXONOMY_RATINGS, ...LEAK_OLD_TAXONOMY_RATINGS]
: SOFTWARE_QUALITY_RATING_METRICS),
]).map((key) => metrics[key]);
@@ -156,7 +159,7 @@ export default function CodeAppRenderer(props: Readonly<Props>) {
</FlagMessage>
)}
- <Spinner isLoading={loading}>
+ <Spinner isLoading={loading || isLoadingLegacy}>
{!allComponentsHaveSoftwareQualityMeasures && (
<AnalysisMissingInfoMessage
qualifier={component.qualifier}
diff --git a/server/sonar-web/src/main/js/apps/code/utils.ts b/server/sonar-web/src/main/js/apps/code/utils.ts
index a7056a18b26..caddcc41f85 100644
--- a/server/sonar-web/src/main/js/apps/code/utils.ts
+++ b/server/sonar-web/src/main/js/apps/code/utils.ts
@@ -37,7 +37,6 @@ const APPLICATION_METRICS = [MetricKey.alert_status, ...METRICS];
const PORTFOLIO_METRICS = [
MetricKey.releasability_rating,
- MetricKey.software_quality_releasability_rating,
MetricKey.security_rating,
MetricKey.software_quality_security_rating,
MetricKey.reliability_rating,
@@ -45,13 +44,11 @@ const PORTFOLIO_METRICS = [
MetricKey.sqale_rating,
MetricKey.software_quality_maintainability_rating,
MetricKey.security_review_rating,
- MetricKey.software_quality_security_review_rating,
MetricKey.ncloc,
];
const NEW_PORTFOLIO_METRICS = [
MetricKey.releasability_rating,
- MetricKey.software_quality_releasability_rating,
MetricKey.new_security_rating,
MetricKey.new_software_quality_security_rating,
MetricKey.new_reliability_rating,
@@ -59,7 +56,6 @@ const NEW_PORTFOLIO_METRICS = [
MetricKey.new_maintainability_rating,
MetricKey.new_software_quality_maintainability_rating,
MetricKey.new_security_review_rating,
- MetricKey.new_software_quality_security_review_rating,
MetricKey.new_lines,
];
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/__tests__/CodingRules-it.ts b/server/sonar-web/src/main/js/apps/coding-rules/__tests__/CodingRules-it.ts
index 7e57a1be36d..fb96c419291 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/__tests__/CodingRules-it.ts
+++ b/server/sonar-web/src/main/js/apps/coding-rules/__tests__/CodingRules-it.ts
@@ -188,7 +188,7 @@ describe('Rules app list', () => {
// Filter by severity
await user.click(ui.severetiesFacet.get());
- await user.click(ui.facetItem(/severity.HIGH/).get());
+ await user.click(ui.facetItem(/severity_impact.HIGH/).get());
expect(ui.getAllRuleListItems()).toHaveLength(8);
});
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/__tests__/CustomRule-it.ts b/server/sonar-web/src/main/js/apps/coding-rules/__tests__/CustomRule-it.ts
index 208cc1a0b98..cc8644c433a 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/__tests__/CustomRule-it.ts
+++ b/server/sonar-web/src/main/js/apps/coding-rules/__tests__/CustomRule-it.ts
@@ -86,9 +86,11 @@ describe('custom rule', () => {
await user.click(ui.cleanCodeQualityCheckbox(SoftwareQuality.Reliability).get());
await user.click(ui.cleanCodeSeveritySelect(SoftwareQuality.Reliability).get());
- await user.click(byRole('option', { name: 'severity.MEDIUM severity.MEDIUM' }).get());
+ await user.click(
+ byRole('option', { name: 'severity_impact.MEDIUM severity_impact.MEDIUM' }).get(),
+ );
- expect(ui.createCustomRuleDialog.byText('severity.MEDIUM').get()).toBeInTheDocument();
+ expect(ui.createCustomRuleDialog.byText('severity_impact.MEDIUM').get()).toBeInTheDocument();
await user.click(ui.statusSelect.get());
await user.click(byRole('option', { name: 'rules.status.BETA' }).get());
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/AttributeCategoryFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/AttributeCategoryFacet.tsx
index c314a1150cf..76f99ceeb88 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/AttributeCategoryFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/AttributeCategoryFacet.tsx
@@ -18,9 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import Facet, { BasicProps } from '../../../components/facets/Facet';
import { CLEAN_CODE_CATEGORIES } from '../../../helpers/constants';
import { translate } from '../../../helpers/l10n';
-import Facet, { BasicProps } from './Facet';
export default function AttributeCategoryFacet(props: BasicProps) {
const renderName = React.useCallback(
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormFieldsCCT.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormFieldsCCT.tsx
index 94e0d1f4447..5482b9a4147 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormFieldsCCT.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormFieldsCCT.tsx
@@ -133,7 +133,7 @@ export function SoftwareQualitiesFields(
() =>
IMPACT_SEVERITIES.map((severity) => ({
value: severity,
- label: intl.formatMessage({ id: `severity.${severity}` }),
+ label: intl.formatMessage({ id: `severity_impact.${severity}` }),
Icon: <SoftwareImpactSeverityIcon severity={severity} />,
})),
[intl],
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/FacetsList.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/FacetsList.tsx
index e937feb4806..a1dbda02d91 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/FacetsList.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/FacetsList.tsx
@@ -21,6 +21,7 @@ import { BasicSeparator } from 'design-system';
import * as React from 'react';
import { Profile } from '../../../api/quality-profiles';
import { useAvailableFeatures } from '../../../app/components/available-features/withAvailableFeatures';
+import SeverityFacet from '../../../components/facets/SeverityFacet';
import { translate } from '../../../helpers/l10n';
import { Feature } from '../../../types/features';
import { Dict } from '../../../types/types';
@@ -33,7 +34,6 @@ import InheritanceFacet from './InheritanceFacet';
import PrioritizedRulesFacet from './PrioritizedRulesFacet';
import ProfileFacet from './ProfileFacet';
import RepositoryFacet from './RepositoryFacet';
-import SeverityFacet from './SeverityFacet';
import SoftwareQualityFacet from './SoftwareQualityFacet';
import StatusFacet from './StatusFacet';
import TagFacet from './TagFacet';
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/InheritanceFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/InheritanceFacet.tsx
index 49a5fb2eae4..92080f9afef 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/InheritanceFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/InheritanceFacet.tsx
@@ -18,9 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import Facet, { BasicProps } from '../../../components/facets/Facet';
import { translate } from '../../../helpers/l10n';
import { RuleInheritance } from '../../../types/types';
-import Facet, { BasicProps } from './Facet';
interface Props extends Omit<BasicProps, 'values'> {
disabled: boolean;
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/PrioritizedRulesFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/PrioritizedRulesFacet.tsx
index 66f1cc3b697..f739939fd89 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/PrioritizedRulesFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/PrioritizedRulesFacet.tsx
@@ -18,8 +18,8 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import Facet, { BasicProps } from '../../../components/facets/Facet';
import { translate } from '../../../helpers/l10n';
-import Facet, { BasicProps } from './Facet';
interface Props extends Omit<BasicProps, 'onChange' | 'values'> {
disabled: boolean;
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/RepositoryFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/RepositoryFacet.tsx
index f53ba7c4ae4..997f2f4bed1 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/RepositoryFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/RepositoryFacet.tsx
@@ -21,12 +21,12 @@ import { Note } from 'design-system';
import * as React from 'react';
import { getRuleRepositories } from '../../../api/rules';
import withLanguagesContext from '../../../app/components/languages/withLanguagesContext';
+import { BasicProps } from '../../../components/facets/Facet';
import { translate } from '../../../helpers/l10n';
import { highlightTerm } from '../../../helpers/search';
import { Languages } from '../../../types/languages';
import { Dict } from '../../../types/types';
import { ListStyleFacet } from '../../issues/sidebar/ListStyleFacet';
-import { BasicProps } from './Facet';
interface StateProps {
languages: Languages;
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/SoftwareQualityFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/SoftwareQualityFacet.tsx
index 1097682a5aa..26151da5286 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/SoftwareQualityFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/SoftwareQualityFacet.tsx
@@ -18,9 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import Facet, { BasicProps } from '../../../components/facets/Facet';
import { SOFTWARE_QUALITIES } from '../../../helpers/constants';
import { translate } from '../../../helpers/l10n';
-import Facet, { BasicProps } from './Facet';
export default function SoftwareQualityFacet(props: BasicProps) {
const renderName = React.useCallback(
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/StatusFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/StatusFacet.tsx
index 8fcd7092240..e7d03dc66d2 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/StatusFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/StatusFacet.tsx
@@ -18,9 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import Facet, { BasicProps } from '../../../components/facets/Facet';
import { RULE_STATUSES } from '../../../helpers/constants';
import { translate } from '../../../helpers/l10n';
-import Facet, { BasicProps } from './Facet';
export default class StatusFacet extends React.PureComponent<BasicProps> {
renderName = (status: string) => translate('rules.status', status.toLowerCase());
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/TagFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/TagFacet.tsx
index 78c3fd4a660..ae3b0b11a13 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/TagFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/TagFacet.tsx
@@ -20,10 +20,10 @@
import { uniq } from 'lodash';
import * as React from 'react';
import { getRuleTags } from '../../../api/rules';
+import { BasicProps } from '../../../components/facets/Facet';
import { translate } from '../../../helpers/l10n';
import { highlightTerm } from '../../../helpers/search';
import { ListStyleFacet } from '../../issues/sidebar/ListStyleFacet';
-import { BasicProps } from './Facet';
export default class TagFacet extends React.PureComponent<BasicProps> {
handleSearch = (query: string) => {
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/TemplateFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/TemplateFacet.tsx
index 87fdc3d87cf..3d49c68bcb9 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/TemplateFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/TemplateFacet.tsx
@@ -20,8 +20,8 @@
import { HelperHintIcon } from 'design-system';
import * as React from 'react';
import HelpTooltip from '~sonar-aligned/components/controls/HelpTooltip';
+import Facet, { BasicProps } from '../../../components/facets/Facet';
import { translate } from '../../../helpers/l10n';
-import Facet, { BasicProps } from './Facet';
interface Props extends Omit<BasicProps, 'onChange' | 'values'> {
onChange: (changes: { template: boolean | undefined }) => void;
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/TypeFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/TypeFacet.tsx
index c92a3c11697..09ba4b0635d 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/TypeFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/TypeFacet.tsx
@@ -18,10 +18,10 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import Facet, { BasicProps } from '../../../components/facets/Facet';
import IssueTypeIcon from '../../../components/icon-mappers/IssueTypeIcon';
import { RULE_TYPES } from '../../../helpers/constants';
import { translate } from '../../../helpers/l10n';
-import Facet, { BasicProps } from './Facet';
export default class TypeFacet extends React.PureComponent<BasicProps> {
renderName = (type: string) => (
diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/MeasureContent.tsx b/server/sonar-web/src/main/js/apps/component-measures/components/MeasureContent.tsx
index 95165e1448a..332801e1d32 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/components/MeasureContent.tsx
+++ b/server/sonar-web/src/main/js/apps/component-measures/components/MeasureContent.tsx
@@ -36,7 +36,6 @@ import { isDefined } from '../../../helpers/types';
import { getProjectUrl } from '../../../helpers/urls';
import { useCurrentBranchQuery } from '../../../queries/branch';
import { useComponentTreeQuery, useMeasuresComponentQuery } from '../../../queries/measures';
-import { useIsLegacyCCTMode } from '../../../queries/settings';
import { useLocation, useRouter } from '../../../sonar-aligned/components/hoc/withRouter';
import { BranchLike } from '../../../types/branch-like';
import { isApplication, isFile, isView } from '../../../types/component';
@@ -71,7 +70,6 @@ export default function MeasureContent(props: Readonly<Props>) {
const { data: branchLike } = useCurrentBranchQuery(rootComponent);
const router = useRouter();
const query = parseQuery(rawQuery);
- const { data: isLegacy } = useIsLegacyCCTMode();
const { selected, asc, view } = query;
const containerRef = React.useRef<HTMLDivElement>(null);
@@ -209,14 +207,7 @@ export default function MeasureContent(props: Readonly<Props>) {
);
}
- return (
- <TreeMapView
- isLegacyMode={Boolean(isLegacy)}
- components={components}
- handleSelect={onOpenComponent}
- metric={metric}
- />
- );
+ return <TreeMapView components={components} handleSelect={onOpenComponent} metric={metric} />;
};
return (
diff --git a/server/sonar-web/src/main/js/apps/component-measures/drilldown/BubbleChartView.tsx b/server/sonar-web/src/main/js/apps/component-measures/drilldown/BubbleChartView.tsx
index 86cdf3e2be9..67f507873ab 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/drilldown/BubbleChartView.tsx
+++ b/server/sonar-web/src/main/js/apps/component-measures/drilldown/BubbleChartView.tsx
@@ -32,7 +32,6 @@ import * as React from 'react';
import HelpTooltip from '~sonar-aligned/components/controls/HelpTooltip';
import { formatMeasure } from '~sonar-aligned/helpers/measures';
import { MetricKey } from '~sonar-aligned/types/metrics';
-import { SOFTWARE_QUALITY_RATING_METRICS } from '../../../helpers/constants';
import {
getLocalizedMetricDomain,
getLocalizedMetricName,
@@ -42,7 +41,6 @@ import {
import { getCCTMeasureValue, isDiffMetric } from '../../../helpers/measures';
import { isDefined } from '../../../helpers/types';
import { getComponentDrilldownUrl } from '../../../helpers/urls';
-import { useIsLegacyCCTMode } from '../../../queries/settings';
import { BranchLike } from '../../../types/branch-like';
import { isProject, isView } from '../../../types/component';
import {
@@ -88,7 +86,6 @@ export default function BubbleChartView(props: Readonly<Props>) {
bubblesByDomain,
} = props;
const theme = useTheme();
- const { data: isLegacy } = useIsLegacyCCTMode();
const bubbleMetrics = getBubbleMetrics(bubblesByDomain, domain, metrics);
const [ratingFilters, setRatingFilters] = React.useState<{ [rating: number]: boolean }>({});
@@ -116,8 +113,7 @@ export default function BubbleChartView(props: Readonly<Props>) {
return undefined;
}
- const bubbleColor =
- `bubble.${isLegacy ? 'legacy.' : ''}${(colorRating ?? 1) as BubbleColorVal}` as const;
+ const bubbleColor = `bubble.${(colorRating ?? 1) as BubbleColorVal}` as const;
return {
x,
@@ -220,12 +216,6 @@ export default function BubbleChartView(props: Readonly<Props>) {
</div>
{bubbleMetrics.colors && (
<ColorRatingsLegend
- isLegacy={
- isLegacy ||
- bubbleMetrics.colors.every(
- (m) => !SOFTWARE_QUALITY_RATING_METRICS.includes(m.key as MetricKey),
- )
- }
className="sw-mt-2"
filters={ratingFilters}
onRatingClick={handleRatingFilterClick}
diff --git a/server/sonar-web/src/main/js/apps/component-measures/drilldown/ColorRatingsLegend.tsx b/server/sonar-web/src/main/js/apps/component-measures/drilldown/ColorRatingsLegend.tsx
index 80acadf8b66..b765f2e4a25 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/drilldown/ColorRatingsLegend.tsx
+++ b/server/sonar-web/src/main/js/apps/component-measures/drilldown/ColorRatingsLegend.tsx
@@ -33,14 +33,13 @@ import { translateWithParameters } from '../../../helpers/l10n';
export interface ColorRatingsLegendProps {
className?: string;
filters: { [rating: number]: boolean };
- isLegacy?: boolean;
onRatingClick: (selection: number) => void;
}
export default function ColorRatingsLegend(props: ColorRatingsLegendProps) {
- const { className, filters, isLegacy } = props;
+ const { className, filters } = props;
const theme = useTheme();
- const RATINGS = isLegacy ? [1, 2, 3, 4, 5] : [1, 2, 3, 4];
+ const RATINGS = [1, 2, 3, 4, 5];
const ratingsColors = RATINGS.map((rating: BubbleColorVal) => {
const formattedMeasure = formatMeasure(rating, MetricType.Rating);
@@ -50,10 +49,10 @@ export default function ColorRatingsLegend(props: ColorRatingsLegendProps) {
label: formattedMeasure,
value: rating,
selected: !filters[rating],
- backgroundColor: themeColor(isLegacy ? `bubble.legacy.${rating}` : `bubble.${rating}`)({
+ backgroundColor: themeColor(`bubble.${rating}`)({
theme,
}),
- borderColor: themeContrast(isLegacy ? `bubble.legacy.${rating}` : `bubble.${rating}`)({
+ borderColor: themeContrast(`bubble.${rating}`)({
theme,
}),
};
diff --git a/server/sonar-web/src/main/js/apps/component-measures/drilldown/TreeMapView.tsx b/server/sonar-web/src/main/js/apps/component-measures/drilldown/TreeMapView.tsx
index 49cf36bb1f1..27b3dd2832e 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/drilldown/TreeMapView.tsx
+++ b/server/sonar-web/src/main/js/apps/component-measures/drilldown/TreeMapView.tsx
@@ -46,7 +46,6 @@ import EmptyResult from './EmptyResult';
interface TreeMapViewProps {
components: ComponentMeasureEnhanced[];
handleSelect: (component: ComponentMeasureIntern) => void;
- isLegacyMode: boolean;
metric: Metric;
}
@@ -57,8 +56,7 @@ interface State {
}
const PERCENT_SCALE_DOMAIN = [0, 25, 50, 75, 100];
-const RATING_SCALE_DOMAIN = [1, 2, 3, 4];
-const LEGACY_RATING_SCALE_DOMAIN = [1, 2, 3, 4, 5];
+const RATING_SCALE_DOMAIN = [1, 2, 3, 4, 5];
const HEIGHT = 500;
const NA_COLORS: [ThemeColors, ThemeColors] = ['treeMap.NA1', 'treeMap.NA2'];
@@ -69,13 +67,6 @@ const TREEMAP_COLORS: ThemeColors[] = [
'treeMap.D',
'treeMap.E',
];
-const TREEMAP_LEGACY_COLORS: ThemeColors[] = [
- 'treeMap.legacy.A',
- 'treeMap.legacy.B',
- 'treeMap.legacy.C',
- 'treeMap.legacy.D',
- 'treeMap.legacy.E',
-];
export class TreeMapView extends React.PureComponent<Props, State> {
state: State;
@@ -149,10 +140,8 @@ export class TreeMapView extends React.PureComponent<Props, State> {
};
getMappedThemeColors = (): string[] => {
- const { theme, isLegacyMode } = this.props;
- return (isLegacyMode ? TREEMAP_LEGACY_COLORS : TREEMAP_COLORS).map((c) =>
- themeColor(c)({ theme }),
- );
+ const { theme } = this.props;
+ return TREEMAP_COLORS.map((c) => themeColor(c)({ theme }));
};
getLevelColorScale = () =>
@@ -171,9 +160,8 @@ export class TreeMapView extends React.PureComponent<Props, State> {
};
getRatingColorScale = () => {
- const { isLegacyMode } = this.props;
return scaleLinear<string, string>()
- .domain(isLegacyMode ? LEGACY_RATING_SCALE_DOMAIN : RATING_SCALE_DOMAIN)
+ .domain(RATING_SCALE_DOMAIN)
.range(this.getMappedThemeColors());
};
diff --git a/server/sonar-web/src/main/js/apps/component-measures/utils.ts b/server/sonar-web/src/main/js/apps/component-measures/utils.ts
index 5424ba9d481..e47f720209e 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/utils.ts
+++ b/server/sonar-web/src/main/js/apps/component-measures/utils.ts
@@ -240,11 +240,7 @@ export function banQualityGateMeasure({ measures = [], qualifier }: ComponentMea
bannedMetrics.push(MetricKey.alert_status);
}
if (qualifier === ComponentQualifier.Application) {
- bannedMetrics.push(
- MetricKey.releasability_rating,
- MetricKey.releasability_effort,
- MetricKey.software_quality_releasability_rating,
- );
+ bannedMetrics.push(MetricKey.releasability_rating, MetricKey.releasability_effort);
}
return measures.filter((measure) => !bannedMetrics.includes(measure.metric));
}
diff --git a/server/sonar-web/src/main/js/apps/issues/__tests__/IssueHeader-it.tsx b/server/sonar-web/src/main/js/apps/issues/__tests__/IssueHeader-it.tsx
index b1edb27376b..f249c8f48e4 100644
--- a/server/sonar-web/src/main/js/apps/issues/__tests__/IssueHeader-it.tsx
+++ b/server/sonar-web/src/main/js/apps/issues/__tests__/IssueHeader-it.tsx
@@ -52,14 +52,14 @@ it('renders correctly', async () => {
`issue.clean_code_attribute_category.${issue.cleanCodeAttributeCategory}`,
).get();
expect(cctBadge).toBeInTheDocument();
- await expect(cctBadge).toHaveATooltipWithContent(
+ await expect(cctBadge).toHaveAPopoverWithContent(
`issue.clean_code_attribute.${issue.cleanCodeAttribute}`,
);
// Software Qualities
const qualityBadge = byText(`software_quality.${issue.impacts[0].softwareQuality}`).get();
expect(qualityBadge).toBeInTheDocument();
- await expect(qualityBadge).toHaveATooltipWithContent('software_quality');
+ await expect(qualityBadge).toHaveAPopoverWithContent('software_quality');
// Deprecated type
const type = byText(`issue.type.${issue.type}`).get();
diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/SeverityFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/SeverityFacet.tsx
deleted file mode 100644
index d4be7b73af1..00000000000
--- a/server/sonar-web/src/main/js/apps/issues/sidebar/SeverityFacet.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-import { HelperHintIcon } from 'design-system';
-import * as React from 'react';
-import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip';
-import SoftwareImpactSeverityIcon from '../../../components/icon-mappers/SoftwareImpactSeverityIcon';
-import { IMPACT_SEVERITIES } from '../../../helpers/constants';
-import { DocLink } from '../../../helpers/doc-links';
-import { translate } from '../../../helpers/l10n';
-import { SoftwareImpactSeverity } from '../../../types/clean-code-taxonomy';
-import { CommonProps, SimpleListStyleFacet } from './SimpleListStyleFacet';
-
-interface Props extends CommonProps {
- severities: SoftwareImpactSeverity[];
-}
-
-export function SeverityFacet(props: Props) {
- const { severities = [], ...rest } = props;
-
- return (
- <SimpleListStyleFacet
- property="impactSeverities"
- itemNamePrefix="severity"
- listItems={IMPACT_SEVERITIES}
- selectedItems={severities}
- renderIcon={(severity: string, disabled: boolean) => (
- <SoftwareImpactSeverityIcon severity={severity} disabled={disabled} />
- )}
- help={
- <DocHelpTooltip
- placement="right"
- content={
- <>
- <p>{translate('issues.facet.impactSeverities.help.line1')}</p>
- <p className="sw-mt-2">{translate('issues.facet.impactSeverities.help.line2')}</p>
- </>
- }
- links={[
- {
- href: DocLink.CleanCodeIntroduction,
- label: translate('learn_more'),
- },
- ]}
- >
- <HelperHintIcon />
- </DocHelpTooltip>
- }
- {...rest}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/Sidebar.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/Sidebar.tsx
index 749603a72d7..1f643e26f92 100644
--- a/server/sonar-web/src/main/js/apps/issues/sidebar/Sidebar.tsx
+++ b/server/sonar-web/src/main/js/apps/issues/sidebar/Sidebar.tsx
@@ -25,6 +25,7 @@ import { isPortfolioLike } from '~sonar-aligned/helpers/component';
import { ComponentQualifier } from '~sonar-aligned/types/component';
import { useAppState } from '../../../app/components/app-state/withAppStateContext';
import { useAvailableFeatures } from '../../../app/components/available-features/withAvailableFeatures';
+import SeverityFacet from '../../../components/facets/SeverityFacet';
import { translate } from '../../../helpers/l10n';
import { BranchLike } from '../../../types/branch-like';
import { isApplication, isProject, isView } from '../../../types/component';
@@ -52,7 +53,6 @@ import { PrioritizedRuleFacet } from './PrioritizedRuleFacet';
import { ProjectFacet } from './ProjectFacet';
import { RuleFacet } from './RuleFacet';
import { ScopeFacet } from './ScopeFacet';
-import { SeverityFacet } from './SeverityFacet';
import { SoftwareQualityFacet } from './SoftwareQualityFacet';
import { StandardFacet } from './StandardFacet';
import { TagFacet } from './TagFacet';
@@ -204,8 +204,8 @@ export function Sidebar(props: Readonly<Props>) {
onChange={props.onFilterChange}
onToggle={props.onFacetToggle}
open={!!openFacets.impactSeverities}
- severities={query.impactSeverities}
stats={facets.impactSeverities}
+ values={query.impactSeverities}
/>
<BasicSeparator className="sw-my-4" />
diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/Sidebar-it.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/Sidebar-it.tsx
index abd6403a955..e878ce08907 100644
--- a/server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/Sidebar-it.tsx
+++ b/server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/Sidebar-it.tsx
@@ -48,7 +48,9 @@ it('should render correct facets for Projects with PrioritizedRules feature', ()
expect(screen.getAllByRole('button').map((button) => button.textContent)).toStrictEqual([
'issues.facet.cleanCodeAttributeCategories',
'issues.facet.impactSoftwareQualities',
- 'issues.facet.impactSeverities',
+ 'coding_rules.facet.impactSeverities',
+ // help icon
+ '',
'issues.facet.types',
'issues.facet.scopes',
'issues.facet.issueStatuses',
@@ -72,7 +74,9 @@ it('should render correct facets for Application', () => {
expect(screen.getAllByRole('button').map((button) => button.textContent)).toStrictEqual([
'issues.facet.cleanCodeAttributeCategories',
'issues.facet.impactSoftwareQualities',
- 'issues.facet.impactSeverities',
+ 'coding_rules.facet.impactSeverities',
+ // help icon
+ '',
'issues.facet.types',
'issues.facet.scopes',
'issues.facet.issueStatuses',
@@ -94,7 +98,9 @@ it('should render correct facets for Portfolio', () => {
expect(screen.getAllByRole('button').map((button) => button.textContent)).toStrictEqual([
'issues.facet.cleanCodeAttributeCategories',
'issues.facet.impactSoftwareQualities',
- 'issues.facet.impactSeverities',
+ 'coding_rules.facet.impactSeverities',
+ // help icon
+ '',
'issues.facet.types',
'issues.facet.scopes',
'issues.facet.issueStatuses',
@@ -116,7 +122,9 @@ it('should render correct facets for SubPortfolio', () => {
expect(screen.getAllByRole('button').map((button) => button.textContent)).toStrictEqual([
'issues.facet.cleanCodeAttributeCategories',
'issues.facet.impactSoftwareQualities',
- 'issues.facet.impactSeverities',
+ 'coding_rules.facet.impactSeverities',
+ // help icon
+ '',
'issues.facet.types',
'issues.facet.scopes',
'issues.facet.issueStatuses',
diff --git a/server/sonar-web/src/main/js/apps/issues/test-utils.tsx b/server/sonar-web/src/main/js/apps/issues/test-utils.tsx
index 3918108f48b..aca69041755 100644
--- a/server/sonar-web/src/main/js/apps/issues/test-utils.tsx
+++ b/server/sonar-web/src/main/js/apps/issues/test-utils.tsx
@@ -107,7 +107,7 @@ export const ui = {
softwareQualityFacet: byRole('button', {
name: 'issues.facet.impactSoftwareQualities',
}),
- severityFacet: byRole('button', { name: 'issues.facet.impactSeverities' }),
+ severityFacet: byRole('button', { name: 'coding_rules.facet.impactSeverities' }),
prioritizedRuleFacet: byRole('button', { name: 'issues.facet.prioritized_rule.category' }),
clearCodeCategoryFacet: byTestId('clear-issues.facet.cleanCodeAttributeCategories'),
@@ -121,7 +121,7 @@ export const ui = {
clearResolutionFacet: byTestId('clear-issues.facet.resolutions'),
clearRuleFacet: byTestId('clear-issues.facet.rules'),
clearScopeFacet: byTestId('clear-issues.facet.scopes'),
- clearSeverityFacet: byTestId('clear-issues.facet.impactSeverities'),
+ clearSeverityFacet: byTestId('clear-coding_rules.facet.impactSeverities'),
clearIssueStatusFacet: byTestId('clear-issues.facet.issueStatuses'),
clearTagFacet: byTestId('clear-issues.facet.tags'),
clearPrioritizedRuleFacet: byTestId('clear-issues.facet.prioritized_rule.category'),
@@ -139,7 +139,9 @@ export const ui = {
confirmedStatusFilter: byRole('checkbox', { name: 'issue.issue_status.CONFIRMED' }),
fixedResolutionFilter: byRole('checkbox', { name: 'issue.resolution.FIXED' }),
mainScopeFilter: byRole('checkbox', { name: 'issue.scope.MAIN' }),
- mediumSeverityFilter: byRole('checkbox', { name: `severity.${SoftwareImpactSeverity.Medium}` }),
+ mediumSeverityFilter: byRole('checkbox', {
+ name: `severity_impact.${SoftwareImpactSeverity.Medium}`,
+ }),
openStatusFilter: byRole('checkbox', { name: 'issue.issue_status.OPEN' }),
vulnerabilityIssueTypeFilter: byRole('checkbox', { name: 'issue.type.VULNERABILITY' }),
prioritizedRuleFilter: byRole('checkbox', { name: 'issues.facet.prioritized_rule' }),
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/OverallCodeMeasuresPanel.tsx b/server/sonar-web/src/main/js/apps/overview/branches/OverallCodeMeasuresPanel.tsx
index dcf7161a700..12ba4763629 100644
--- a/server/sonar-web/src/main/js/apps/overview/branches/OverallCodeMeasuresPanel.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/branches/OverallCodeMeasuresPanel.tsx
@@ -197,6 +197,12 @@ export default function OverallCodeMeasuresPanel(props: Readonly<OverallCodeMeas
<RatingComponent
branchLike={branch}
componentKey={component.key}
+ getTooltip={(rating) =>
+ intl.formatMessage({ id: `metric.security_review_rating.tooltip.${rating}` })
+ }
+ getLabel={(rating) =>
+ intl.formatMessage({ id: 'metric.has_rating_X' }, { 0: rating })
+ }
ratingMetric={MetricKey.security_review_rating}
size="md"
/>
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureBreakdownCard.tsx b/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureBreakdownCard.tsx
deleted file mode 100644
index 463c20ea9f7..00000000000
--- a/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureBreakdownCard.tsx
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import styled from '@emotion/styled';
-import { Tooltip } from '@sonarsource/echoes-react';
-import classNames from 'classnames';
-import { DiscreetLinkBox, themeColor, themeContrast } from 'design-system';
-import * as React from 'react';
-import { useIntl } from 'react-intl';
-import { formatMeasure } from '~sonar-aligned/helpers/measures';
-import { getComponentIssuesUrl } from '~sonar-aligned/helpers/urls';
-import { MetricType } from '~sonar-aligned/types/metrics';
-import { DEFAULT_ISSUES_QUERY } from '../../../components/shared/utils';
-import { Branch } from '../../../types/branch-like';
-import { SoftwareImpactSeverity, SoftwareQuality } from '../../../types/clean-code-taxonomy';
-import { Component } from '../../../types/types';
-
-export interface SoftwareImpactMeasureBreakdownCardProps {
- active?: boolean;
- branch?: Branch;
- component: Component;
- severity: SoftwareImpactSeverity;
- softwareQuality: SoftwareQuality;
- value?: string;
-}
-
-export function SoftwareImpactMeasureBreakdownCard(
- props: Readonly<SoftwareImpactMeasureBreakdownCardProps>,
-) {
- const { softwareQuality, component, value, severity, active, branch } = props;
-
- const intl = useIntl();
-
- const url = getComponentIssuesUrl(component.key, {
- ...DEFAULT_ISSUES_QUERY,
- impactSoftwareQualities: softwareQuality,
- impactSeverities: severity,
- branch: branch?.name,
- });
-
- const testId = `overview__software-impact-${softwareQuality}-severity-${severity}`;
- const cardClasses =
- 'sw-w-1/3 sw-px-2 sw-py-1 sw-rounded-1 sw-text-xs sw-font-semibold sw-select-none sw-flex sw-gap-1 sw-justify-center sw-items-center';
-
- if (!value) {
- return (
- <StyledBreakdownCard
- data-testid={testId}
- className={classNames(cardClasses, severity, {
- active,
- })}
- >
- -
- </StyledBreakdownCard>
- );
- }
-
- return (
- <Tooltip
- content={intl.formatMessage({
- id: `overview.measures.software_impact.severity.${severity}.tooltip`,
- })}
- >
- <StyledBreakdownLinkCard
- data-testid={testId}
- className={classNames(cardClasses, severity, {
- active,
- })}
- aria-label={intl.formatMessage(
- {
- id: 'overview.measures.software_impact.severity.see_x_open_issues',
- },
- {
- count: formatMeasure(value, MetricType.ShortInteger),
- softwareQuality: intl.formatMessage({
- id: `software_quality.${softwareQuality}`,
- }),
- severity: intl.formatMessage({
- id: `overview.measures.software_impact.severity.${severity}.tooltip`,
- }),
- },
- )}
- disabled={component.needIssueSync}
- to={url}
- >
- <span>{formatMeasure(value, MetricType.ShortInteger)}</span>
- <span>
- {intl.formatMessage({
- id: `overview.measures.software_impact.severity.${severity}`,
- })}
- </span>
- </StyledBreakdownLinkCard>
- </Tooltip>
- );
-}
-
-const StyledBreakdownCard = styled.div`
- background-color: ${themeColor('overviewSoftwareImpactSeverityNeutral')};
-
- &.active.HIGH {
- background-color: ${themeColor('overviewSoftwareImpactSeverityHigh')};
- color: ${themeContrast('overviewSoftwareImpactSeverityHigh')};
- }
- &.active.MEDIUM {
- background-color: ${themeColor('overviewSoftwareImpactSeverityMedium')};
- color: ${themeContrast('overviewSoftwareImpactSeverityMedium')};
- }
- &.active.LOW {
- background-color: ${themeColor('overviewSoftwareImpactSeverityLow')};
- color: ${themeContrast('overviewSoftwareImpactSeverityLow')};
- }
-`;
-const StyledBreakdownLinkCard = StyledBreakdownCard.withComponent(DiscreetLinkBox);
-
-export default SoftwareImpactMeasureBreakdownCard;
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureCard.tsx b/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureCard.tsx
index 37c5e3248a8..96cd155eeca 100644
--- a/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureCard.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureCard.tsx
@@ -33,15 +33,10 @@ import {
import { isDefined } from '../../../helpers/types';
import { useIsLegacyCCTMode } from '../../../queries/settings';
import { Branch } from '../../../types/branch-like';
-import {
- SoftwareImpactMeasureData,
- SoftwareImpactSeverity,
- SoftwareQuality,
-} from '../../../types/clean-code-taxonomy';
+import { SoftwareImpactMeasureData, SoftwareQuality } from '../../../types/clean-code-taxonomy';
import { QualityGateStatusConditionEnhanced } from '../../../types/quality-gates';
import { Component, MeasureEnhanced } from '../../../types/types';
import { Status, softwareQualityToMeasure } from '../utils';
-import SoftwareImpactMeasureBreakdownCard from './SoftwareImpactMeasureBreakdownCard';
import SoftwareImpactMeasureRating from './SoftwareImpactMeasureRating';
export interface SoftwareImpactBreakdownCardProps {
@@ -79,13 +74,6 @@ export function SoftwareImpactMeasureCard(props: Readonly<SoftwareImpactBreakdow
branch: branch?.name,
});
- // We highlight the highest severity breakdown card with non-zero count
- const highlightedSeverity =
- measure &&
- [SoftwareImpactSeverity.High, SoftwareImpactSeverity.Medium, SoftwareImpactSeverity.Low].find(
- (severity) => measure[severity] > 0,
- );
-
const countTooltipOverlay = intl.formatMessage({
id: 'overview.measures.software_impact.count_tooltip',
});
@@ -149,25 +137,6 @@ export function SoftwareImpactMeasureCard(props: Readonly<SoftwareImpactBreakdow
/>
</div>
</div>
- {measure && (
- <div className="sw-flex sw-gap-2">
- {[
- SoftwareImpactSeverity.High,
- SoftwareImpactSeverity.Medium,
- SoftwareImpactSeverity.Low,
- ].map((severity) => (
- <SoftwareImpactMeasureBreakdownCard
- branch={branch}
- key={severity}
- component={component}
- softwareQuality={softwareQuality}
- value={measure?.[severity]?.toString()}
- severity={severity}
- active={highlightedSeverity === severity}
- />
- ))}
- </div>
- )}
</div>
</div>
);
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/BranchOverview-it.tsx b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/BranchOverview-it.tsx
index 4a99bdfa447..0bc93912b37 100644
--- a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/BranchOverview-it.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/BranchOverview-it.tsx
@@ -44,7 +44,7 @@ import { mockQualityGateProjectStatus } from '../../../../helpers/mocks/quality-
import { mockLoggedInUser, mockMeasure, mockPaging } from '../../../../helpers/testMocks';
import { renderComponent } from '../../../../helpers/testReactTestingUtils';
import { ComponentPropsType } from '../../../../helpers/testUtils';
-import { SoftwareImpactSeverity, SoftwareQuality } from '../../../../types/clean-code-taxonomy';
+import { SoftwareQuality } from '../../../../types/clean-code-taxonomy';
import { ProjectAnalysisEventCategory } from '../../../../types/project-activity';
import { SettingsKey } from '../../../../types/settings';
import { CaycStatus } from '../../../../types/types';
@@ -299,53 +299,21 @@ describe('project overview', () => {
await user.click(await ui.overallCodeButton.find());
- ui.expectSoftwareImpactMeasureCard(
- SoftwareQuality.Security,
- 'B',
- {
- total: 1,
- [SoftwareImpactSeverity.High]: 0,
- [SoftwareImpactSeverity.Medium]: 1,
- [SoftwareImpactSeverity.Low]: 0,
- },
- [false, true, false],
- );
+ ui.expectSoftwareImpactMeasureCard(SoftwareQuality.Security, 'B', 1);
await ui.expectSoftwareImpactMeasureCardRatingTooltip(
SoftwareQuality.Security,
'B',
'overview.measures.software_impact.improve_rating_tooltip.software_quality.SECURITY.software_quality.security.B.overview.measures.software_impact.severity.LOW.improve_tooltip',
);
- ui.expectSoftwareImpactMeasureCard(
- SoftwareQuality.Reliability,
- 'A',
- {
- total: 3,
- [SoftwareImpactSeverity.High]: 0,
- [SoftwareImpactSeverity.Medium]: 2,
- [SoftwareImpactSeverity.Low]: 1,
- },
- [false, true, false],
- undefined,
- true,
- );
+ ui.expectSoftwareImpactMeasureCard(SoftwareQuality.Reliability, 'A', 3, undefined, true);
await ui.expectSoftwareImpactMeasureCardRatingTooltip(
SoftwareQuality.Reliability,
'A',
'overview.measures.software_impact.improve_rating_tooltip.A.software_quality.RELIABILITY.software_quality.reliability.A.overview.measures.software_impact.severity.LOW.improve_tooltip',
);
- ui.expectSoftwareImpactMeasureCard(
- SoftwareQuality.Maintainability,
- 'D',
- {
- total: 2,
- [SoftwareImpactSeverity.High]: 0,
- [SoftwareImpactSeverity.Medium]: 0,
- [SoftwareImpactSeverity.Low]: 1,
- },
- [false, false, true],
- );
+ ui.expectSoftwareImpactMeasureCard(SoftwareQuality.Maintainability, 'D', 2);
await ui.expectSoftwareImpactMeasureCardRatingTooltip(
SoftwareQuality.Maintainability,
'D',
@@ -360,18 +328,7 @@ describe('project overview', () => {
await user.click(await ui.overallCodeButton.find());
- ui.expectSoftwareImpactMeasureCard(
- SoftwareQuality.Maintainability,
- 'D',
- {
- total: 2,
- [SoftwareImpactSeverity.High]: 0,
- [SoftwareImpactSeverity.Medium]: 0,
- [SoftwareImpactSeverity.Low]: 1,
- },
- [false, false, true],
- '',
- );
+ ui.expectSoftwareImpactMeasureCard(SoftwareQuality.Maintainability, 'D', 2, '');
});
it('should render old measures if software impact are missing', async () => {
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/test-utils.ts b/server/sonar-web/src/main/js/apps/overview/branches/test-utils.ts
index d9832064480..9367882d9a1 100644
--- a/server/sonar-web/src/main/js/apps/overview/branches/test-utils.ts
+++ b/server/sonar-web/src/main/js/apps/overview/branches/test-utils.ts
@@ -19,11 +19,7 @@
*/
import userEvent from '@testing-library/user-event';
import { byLabelText, byRole, byTestId, byText } from '~sonar-aligned/helpers/testSelector';
-import {
- SoftwareImpactMeasureData,
- SoftwareImpactSeverity,
- SoftwareQuality,
-} from '../../../types/clean-code-taxonomy';
+import { SoftwareImpactSeverity, SoftwareQuality } from '../../../types/clean-code-taxonomy';
export const getPageObjects = () => {
const user = userEvent.setup();
@@ -41,8 +37,7 @@ export const getPageObjects = () => {
expectSoftwareImpactMeasureCard: (
softwareQuality: SoftwareQuality,
rating?: string,
- data?: SoftwareImpactMeasureData,
- severitiesActiveState?: boolean[],
+ total?: number,
branch = 'master',
failed = false,
) => {
@@ -59,58 +54,17 @@ export const getPageObjects = () => {
byText(rating, { exact: true }).get(ui.softwareImpactMeasureCard(softwareQuality).get()),
).toBeInTheDocument();
}
- if (data) {
+ if (total !== undefined) {
const branchQuery = branch ? `&branch=${branch}` : '';
expect(
byRole('link', {
- name: `overview.measures.software_impact.see_list_of_x_open_issues.${data.total}.software_quality.${softwareQuality}`,
+ name: `overview.measures.software_impact.see_list_of_x_open_issues.${total}.software_quality.${softwareQuality}`,
}).get(),
).toHaveAttribute(
'href',
`/project/issues?issueStatuses=OPEN%2CCONFIRMED&impactSoftwareQualities=${softwareQuality}${branchQuery}&id=foo`,
);
- expect(
- byRole('link', {
- name: `overview.measures.software_impact.severity.see_x_open_issues.${
- data[SoftwareImpactSeverity.High]
- }.software_quality.${softwareQuality}.overview.measures.software_impact.severity.HIGH.tooltip`,
- }).get(),
- ).toHaveAttribute(
- 'href',
- `/project/issues?issueStatuses=OPEN%2CCONFIRMED&impactSoftwareQualities=${softwareQuality}&impactSeverities=${SoftwareImpactSeverity.High}${branchQuery}&id=foo`,
- );
- expect(
- byRole('link', {
- name: `overview.measures.software_impact.severity.see_x_open_issues.${
- data[SoftwareImpactSeverity.Medium]
- }.software_quality.${softwareQuality}.overview.measures.software_impact.severity.MEDIUM.tooltip`,
- }).get(),
- ).toBeInTheDocument();
- expect(
- byRole('link', {
- name: `overview.measures.software_impact.severity.see_x_open_issues.${
- data[SoftwareImpactSeverity.Low]
- }.software_quality.${softwareQuality}.overview.measures.software_impact.severity.LOW.tooltip`,
- }).get(),
- ).toBeInTheDocument();
- }
- if (severitiesActiveState) {
- ui.expectSoftwareImpactMeasureBreakdownCard(
- softwareQuality,
- SoftwareImpactSeverity.High,
- severitiesActiveState[0],
- );
- ui.expectSoftwareImpactMeasureBreakdownCard(
- softwareQuality,
- SoftwareImpactSeverity.Medium,
- severitiesActiveState[1],
- );
- ui.expectSoftwareImpactMeasureBreakdownCard(
- softwareQuality,
- SoftwareImpactSeverity.Low,
- severitiesActiveState[2],
- );
}
},
expectSoftwareImpactMeasureCardToHaveOldMeasures: (
diff --git a/server/sonar-web/src/main/js/apps/overview/utils.tsx b/server/sonar-web/src/main/js/apps/overview/utils.tsx
index fa7e2786ea5..0d94c172778 100644
--- a/server/sonar-web/src/main/js/apps/overview/utils.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/utils.tsx
@@ -68,9 +68,7 @@ export const BRANCH_OVERVIEW_METRICS: string[] = [
MetricKey.security_hotspots_reviewed,
MetricKey.new_security_hotspots_reviewed,
MetricKey.security_review_rating,
- MetricKey.software_quality_security_review_rating,
MetricKey.new_security_review_rating,
- MetricKey.new_software_quality_security_review_rating,
// code smells
MetricKey.code_smells,
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.tsx b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.tsx
index 80b1d177e92..f059e203627 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.tsx
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.tsx
@@ -253,8 +253,7 @@ export default class ProjectActivityGraphs extends React.PureComponent<Props, St
};
render() {
- const { analyses, leakPeriodDate, loading, measuresHistory, metrics, query, isLegacy } =
- this.props;
+ const { analyses, leakPeriodDate, loading, measuresHistory, metrics, query } = this.props;
const { graphEndDate, graphStartDate, series } = this.state;
return (
@@ -278,7 +277,6 @@ export default class ProjectActivityGraphs extends React.PureComponent<Props, St
graphs={this.state.graphs}
leakPeriodDate={leakPeriodDate}
loading={loading}
- isLegacy={isLegacy}
measuresHistory={measuresHistory}
removeCustomMetric={this.handleRemoveCustomMetric}
selectedDate={query.selectedDate}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityApp-it.tsx b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityApp-it.tsx
index 1e29192a079..e8132d76bef 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityApp-it.tsx
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityApp-it.tsx
@@ -609,7 +609,6 @@ describe('ratings', () => {
expect(await ui.graphs.findAll()).toHaveLength(1);
expect(ui.metricChangedInfoBtn.get()).toBeInTheDocument();
expect(ui.gapInfoMessage.get()).toBeInTheDocument();
- expect(byText('E').query()).not.toBeInTheDocument();
});
it('should not show old rating if new one was always there', async () => {
@@ -652,10 +651,9 @@ describe('ratings', () => {
expect(await ui.graphs.findAll()).toHaveLength(1);
expect(ui.metricChangedInfoBtn.query()).not.toBeInTheDocument();
expect(ui.gapInfoMessage.query()).not.toBeInTheDocument();
- expect(byText('E').query()).not.toBeInTheDocument();
});
- it('should show E if no new metrics', async () => {
+ it('should not show change info button if no new metrics', async () => {
timeMachineHandler.setMeasureHistory([
mockMeasureHistory({
metric: MetricKey.reliability_rating,
@@ -686,10 +684,9 @@ describe('ratings', () => {
expect(await ui.graphs.findAll()).toHaveLength(1);
expect(ui.metricChangedInfoBtn.query()).not.toBeInTheDocument();
expect(ui.gapInfoMessage.query()).not.toBeInTheDocument();
- expect(byText('E').get()).toBeInTheDocument();
});
- it('should not show gaps message and metric change button, but should show E in legacy mode', async () => {
+ it('should not show gaps message and metric change button in legacy mode', async () => {
settingsHandler.set(SettingsKey.LegacyMode, 'true');
timeMachineHandler.setMeasureHistory([
mockMeasureHistory({
@@ -746,7 +743,6 @@ describe('ratings', () => {
expect(await ui.graphs.findAll()).toHaveLength(1);
expect(ui.metricChangedInfoBtn.query()).not.toBeInTheDocument();
expect(ui.gapInfoMessage.query()).not.toBeInTheDocument();
- expect(byText('E').get()).toBeInTheDocument();
});
});
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx
index 63fe3f135e9..927df18e7aa 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx
@@ -88,20 +88,20 @@ it('should show legacy filters', async () => {
settingsHandler.set(SettingsKey.LegacyMode, 'true');
renderPageSidebar();
- expect(await screen.findAllByText('E')).toHaveLength(4);
- expect(screen.queryByText(/projects.facets.rating_option/)).not.toBeInTheDocument();
- expect(screen.queryByText('projects.facets.maintainability.description')).not.toBeInTheDocument();
- expect(screen.queryByText('projects.facets.security_review.description')).not.toBeInTheDocument();
+ expect(await screen.findAllByText(/projects.facets.rating_option/)).toHaveLength(20);
+ expect(screen.getByText('projects.facets.rating_option.security.legacy.1')).toBeInTheDocument();
+ expect(
+ screen.getByText('projects.facets.rating_option.reliability.legacy.1'),
+ ).toBeInTheDocument();
});
it('should show non legacy filters', async () => {
settingsHandler.set(SettingsKey.LegacyMode, 'false');
renderPageSidebar();
- expect(await screen.findAllByText(/projects.facets.rating_option/)).toHaveLength(16);
- expect(screen.queryAllByText('E')).toHaveLength(0);
- expect(screen.getByText('projects.facets.maintainability.description')).toBeInTheDocument();
- expect(screen.getByText('projects.facets.security_review.description')).toBeInTheDocument();
+ expect(await screen.findAllByText(/projects.facets.rating_option/)).toHaveLength(20);
+ expect(screen.getByText('projects.facets.rating_option.security.1')).toBeInTheDocument();
+ expect(screen.getByText('projects.facets.rating_option.reliability.1')).toBeInTheDocument();
});
function renderPageSidebar(overrides: Partial<PageSidebarProps> = {}, currentUser?: CurrentUser) {
diff --git a/server/sonar-web/src/main/js/apps/projects/components/project-card/__tests__/ProjectCard-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/project-card/__tests__/ProjectCard-test.tsx
index e062e396102..998ac41cc8c 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/project-card/__tests__/ProjectCard-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/components/project-card/__tests__/ProjectCard-test.tsx
@@ -38,7 +38,7 @@ const MEASURES = {
[MetricKey.reliability_rating]: '1.0',
[MetricKey.security_rating]: '1.0',
[MetricKey.sqale_rating]: '1.0',
- [MetricKey.security_review_rating]: '1.0',
+ [MetricKey.security_review_rating]: '3.0',
[MetricKey.new_bugs]: '12',
};
@@ -123,7 +123,7 @@ describe('upgrade scenario (awaiting scan)', () => {
}),
[MetricKey.security_review_rating]: mockMeasure({
metric: MetricKey.security_review_rating,
- value: '1',
+ value: '3',
}),
};
@@ -140,9 +140,9 @@ describe('upgrade scenario (awaiting scan)', () => {
metric: MetricKey.software_quality_security_rating,
value: '2',
}),
- [MetricKey.software_quality_security_review_rating]: mockMeasure({
- metric: MetricKey.software_quality_security_review_rating,
- value: '2',
+ [MetricKey.security_review_rating]: mockMeasure({
+ metric: MetricKey.security_review_rating,
+ value: '3',
}),
};
beforeEach(() => {
@@ -174,7 +174,6 @@ describe('upgrade scenario (awaiting scan)', () => {
[MetricKey.software_quality_maintainability_rating]: '2',
[MetricKey.software_quality_reliability_rating]: '2',
[MetricKey.software_quality_security_rating]: '2',
- [MetricKey.software_quality_security_review_rating]: '2',
[MetricKey.code_smells]: '4',
[MetricKey.bugs]: '5',
[MetricKey.vulnerabilities]: '6',
@@ -183,7 +182,8 @@ describe('upgrade scenario (awaiting scan)', () => {
expect(screen.getByText('1')).toBeInTheDocument();
expect(screen.getByText('2')).toBeInTheDocument();
expect(screen.getByText('3')).toBeInTheDocument();
- await waitFor(() => expect(screen.getAllByText('B')).toHaveLength(4));
+ await waitFor(() => expect(screen.getAllByText('B')).toHaveLength(3));
+ await waitFor(() => expect(screen.getAllByText('C')).toHaveLength(1));
expect(screen.queryByText('projects.awaiting_scan')).not.toBeInTheDocument();
expect(screen.queryByText('4')).not.toBeInTheDocument();
expect(screen.queryByText('5')).not.toBeInTheDocument();
@@ -208,7 +208,8 @@ describe('upgrade scenario (awaiting scan)', () => {
expect(screen.getByText('4')).toBeInTheDocument();
expect(screen.getByText('5')).toBeInTheDocument();
expect(screen.getByText('6')).toBeInTheDocument();
- expect(screen.getAllByText('A')).toHaveLength(4);
+ expect(screen.getAllByText('A')).toHaveLength(3);
+ expect(screen.getAllByText('C')).toHaveLength(1);
});
it('should display awaiting analysis badge, show new software qualities, but old ratings', async () => {
@@ -236,7 +237,8 @@ describe('upgrade scenario (awaiting scan)', () => {
expect(screen.queryByText('4')).not.toBeInTheDocument();
expect(screen.queryByText('5')).not.toBeInTheDocument();
expect(screen.queryByText('6')).not.toBeInTheDocument();
- await waitFor(() => expect(screen.getAllByText('A')).toHaveLength(4));
+ await waitFor(() => expect(screen.getAllByText('A')).toHaveLength(3));
+ expect(screen.getAllByText('C')).toHaveLength(1);
});
it('should display awaiting analysis badge and show the old measures for Application', async () => {
@@ -296,7 +298,8 @@ describe('upgrade scenario (awaiting scan)', () => {
expect(screen.getByText('4')).toBeInTheDocument();
expect(screen.getByText('5')).toBeInTheDocument();
expect(screen.getByText('6')).toBeInTheDocument();
- await waitFor(() => expect(screen.getAllByText('A')).toHaveLength(4));
+ await waitFor(() => expect(screen.getAllByText('A')).toHaveLength(3));
+ expect(screen.getAllByText('C')).toHaveLength(1);
expect(screen.queryByText('projects.awaiting_scan')).not.toBeInTheDocument();
});
@@ -323,7 +326,6 @@ describe('upgrade scenario (awaiting scan)', () => {
[MetricKey.software_quality_maintainability_rating]: '2',
[MetricKey.software_quality_reliability_rating]: '2',
[MetricKey.software_quality_security_rating]: '2',
- [MetricKey.software_quality_security_review_rating]: '2',
[MetricKey.code_smells]: '4',
[MetricKey.bugs]: '5',
[MetricKey.vulnerabilities]: '6',
@@ -335,7 +337,8 @@ describe('upgrade scenario (awaiting scan)', () => {
expect(screen.queryByText('1')).not.toBeInTheDocument();
expect(screen.queryByText('2')).not.toBeInTheDocument();
expect(screen.queryByText('3')).not.toBeInTheDocument();
- await waitFor(() => expect(screen.getAllByText('A')).toHaveLength(4));
+ await waitFor(() => expect(screen.getAllByText('A')).toHaveLength(3));
+ expect(screen.getAllByText('C')).toHaveLength(1);
expect(screen.queryByText('B')).not.toBeInTheDocument();
expect(screen.queryByText('projects.awaiting_scan')).not.toBeInTheDocument();
});
diff --git a/server/sonar-web/src/main/js/apps/projects/filters/RatingFacet.tsx b/server/sonar-web/src/main/js/apps/projects/filters/RatingFacet.tsx
index 5dbbfc52654..cd9aad48051 100644
--- a/server/sonar-web/src/main/js/apps/projects/filters/RatingFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/projects/filters/RatingFacet.tsx
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { Spinner } from '@sonarsource/echoes-react';
import { MetricsRatingBadge, RatingEnum } from 'design-system';
import * as React from 'react';
import { useIntl } from 'react-intl';
@@ -37,9 +38,8 @@ interface Props {
value?: any;
}
-export default function RatingFacet(props: Props) {
+export default function RatingFacet(props: Readonly<Props>) {
const { facet, maxFacetValue, name, property, value } = props;
- const { data: isLegacy } = useIsLegacyCCTMode();
const renderAccessibleLabel = React.useCallback(
(option: number) => {
@@ -65,14 +65,14 @@ export default function RatingFacet(props: Props) {
facet={facet}
header={translate('metric_domain', name)}
description={
- !isLegacy && hasDescription(property)
+ hasDescription(property)
? translate(`projects.facets.${property.replace('new_', '')}.description`)
: undefined
}
highlightUnder={1}
maxFacetValue={maxFacetValue}
onQueryChange={props.onQueryChange}
- options={isLegacy ? [1, 2, 3, 4, 5] : [1, 2, 3, 4]}
+ options={[1, 2, 3, 4, 5]}
property={property}
renderAccessibleLabel={renderAccessibleLabel}
renderOption={(option) => renderOption(option, property)}
@@ -93,25 +93,24 @@ function RatingOption({
option,
property,
}: Readonly<{ option: string | number; property: string }>) {
- const { data: isLegacy } = useIsLegacyCCTMode();
+ const { data: isLegacy, isLoading } = useIsLegacyCCTMode();
const intl = useIntl();
const ratingFormatted = formatMeasure(option, MetricType.Rating);
+ const propertyWithoutPrefix = property.replace('new_', '');
+ const isSecurityOrReliability = ['security', 'reliability'].includes(propertyWithoutPrefix);
return (
- <>
+ <Spinner isLoading={isLoading}>
<MetricsRatingBadge
label={ratingFormatted}
rating={ratingFormatted as RatingEnum}
- isLegacy={isLegacy}
size="xs"
/>
- {!isLegacy && (
- <span className="sw-ml-2">
- {intl.formatMessage({
- id: `projects.facets.rating_option.${property.replace('new_', '')}.${option}`,
- })}
- </span>
- )}
- </>
+ <span className="sw-ml-2">
+ {intl.formatMessage({
+ id: `projects.facets.rating_option.${propertyWithoutPrefix}${isLegacy && isSecurityOrReliability ? '.legacy' : ''}.${option}`,
+ })}
+ </span>
+ </Spinner>
);
}
diff --git a/server/sonar-web/src/main/js/apps/projects/utils.ts b/server/sonar-web/src/main/js/apps/projects/utils.ts
index 21ec392bfbe..709e2626f52 100644
--- a/server/sonar-web/src/main/js/apps/projects/utils.ts
+++ b/server/sonar-web/src/main/js/apps/projects/utils.ts
@@ -102,7 +102,6 @@ export const METRICS = [
MetricKey.software_quality_maintainability_rating,
MetricKey.security_hotspots_reviewed,
MetricKey.security_review_rating,
- MetricKey.software_quality_security_review_rating,
MetricKey.duplicated_lines_density,
MetricKey.coverage,
MetricKey.ncloc,
@@ -138,8 +137,8 @@ export const LEGACY_FACETS = [
export const FACETS = [
MetricKey.software_quality_reliability_rating,
MetricKey.software_quality_security_rating,
- MetricKey.software_quality_security_review_rating,
MetricKey.software_quality_maintainability_rating,
+ MetricKey.security_review_rating,
MetricKey.coverage,
MetricKey.duplicated_lines_density,
MetricKey.ncloc,
@@ -166,8 +165,8 @@ export const LEGACY_LEAK_FACETS = [
export const LEAK_FACETS = [
MetricKey.new_software_quality_reliability_rating,
MetricKey.new_software_quality_security_rating,
- MetricKey.new_software_quality_security_review_rating,
MetricKey.new_software_quality_maintainability_rating,
+ MetricKey.new_security_review_rating,
MetricKey.new_coverage,
MetricKey.new_duplicated_lines_density,
MetricKey.new_lines,
@@ -318,8 +317,6 @@ export const propertyToMetricMap: Dict<string | undefined> = {
new_reliability: 'new_software_quality_reliability_rating',
security: 'software_quality_security_rating',
new_security: 'new_software_quality_security_rating',
- security_review: 'software_quality_security_review_rating',
- new_security_review: 'new_software_quality_security_review_rating',
maintainability: 'software_quality_maintainability_rating',
new_maintainability: 'new_software_quality_maintainability_rating',
};
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionModal.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionModal.tsx
index 4f0bfadf919..f97e31fa685 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionModal.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionModal.tsx
@@ -50,8 +50,6 @@ const FORBIDDEN_METRICS: string[] = [
MetricKey.new_software_quality_reliability_rating,
MetricKey.software_quality_security_rating,
MetricKey.new_software_quality_security_rating,
- MetricKey.software_quality_security_review_rating,
- MetricKey.new_software_quality_security_review_rating,
MetricKey.effort_to_reach_software_quality_maintainability_rating_a,
MetricKey.software_quality_maintainability_remediation_effort,
MetricKey.new_software_quality_maintainability_remediation_effort,
diff --git a/server/sonar-web/src/main/js/components/activity-graph/GraphHistory.tsx b/server/sonar-web/src/main/js/components/activity-graph/GraphHistory.tsx
index 028c1ccd46e..1317281641b 100644
--- a/server/sonar-web/src/main/js/components/activity-graph/GraphHistory.tsx
+++ b/server/sonar-web/src/main/js/components/activity-graph/GraphHistory.tsx
@@ -41,7 +41,6 @@ interface Props {
graphEndDate?: Date;
graphStartDate?: Date;
isCustom?: boolean;
- isLegacy?: boolean;
leakPeriodDate?: Date;
measuresHistory: MeasureHistory[];
metricsType: string;
@@ -69,7 +68,6 @@ export default function GraphHistory(props: Readonly<Props>) {
series,
showAreas,
graphDescription,
- isLegacy,
} = props;
const [tooltipIdx, setTooltipIdx] = React.useState<number | undefined>(undefined);
const [tooltipXPos, setTooltipXPos] = React.useState<number | undefined>(undefined);
@@ -124,7 +122,6 @@ export default function GraphHistory(props: Readonly<Props>) {
splitPointDate={measuresHistory.find((m) => m.splitPointDate)?.splitPointDate}
metricType={metricsType}
selectedDate={selectedDate}
- isLegacy={isLegacy}
series={series}
showAreas={showAreas}
startDate={graphStartDate}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/GraphsHistory.tsx b/server/sonar-web/src/main/js/components/activity-graph/GraphsHistory.tsx
index 9be16362121..5bf2137e1d8 100644
--- a/server/sonar-web/src/main/js/components/activity-graph/GraphsHistory.tsx
+++ b/server/sonar-web/src/main/js/components/activity-graph/GraphsHistory.tsx
@@ -33,7 +33,6 @@ interface Props {
graphEndDate?: Date;
graphStartDate?: Date;
graphs: Serie[][];
- isLegacy?: boolean;
leakPeriodDate?: Date;
loading: boolean;
measuresHistory: MeasureHistory[];
@@ -67,8 +66,7 @@ export default class GraphsHistory extends React.PureComponent<Props, State> {
};
render() {
- const { analyses, graph, loading, series, ariaLabel, canShowDataAsTable, isLegacy } =
- this.props;
+ const { analyses, graph, loading, series, ariaLabel, canShowDataAsTable } = this.props;
const isCustom = isCustomGraph(graph);
if (loading) {
@@ -107,7 +105,6 @@ export default class GraphsHistory extends React.PureComponent<Props, State> {
graphStartDate={this.props.graphStartDate}
isCustom={isCustom}
key={idx}
- isLegacy={isLegacy}
leakPeriodDate={this.props.leakPeriodDate}
measuresHistory={this.props.measuresHistory}
metricsType={getSeriesMetricType(graphSeries)}
diff --git a/server/sonar-web/src/main/js/components/charts/AdvancedTimeline.tsx b/server/sonar-web/src/main/js/components/charts/AdvancedTimeline.tsx
index 632410a2370..2f86e9e75ed 100644
--- a/server/sonar-web/src/main/js/components/charts/AdvancedTimeline.tsx
+++ b/server/sonar-web/src/main/js/components/charts/AdvancedTimeline.tsx
@@ -51,7 +51,6 @@ export interface PropsWithoutTheme {
height: number;
hideGrid?: boolean;
hideXAxis?: boolean;
- isLegacy?: boolean;
leakPeriodDate?: Date;
// used to avoid same y ticks labels
maxYTicksCount?: number;
@@ -145,10 +144,7 @@ export class AdvancedTimelineClass extends React.PureComponent<Props, State> {
}
getRatingScale = (availableHeight: number) => {
- const { isLegacy } = this.props;
- return scalePoint<number>()
- .domain(isLegacy ? [5, 4, 3, 2, 1] : [4, 3, 2, 1])
- .range([availableHeight, 0]);
+ return scalePoint<number>().domain([5, 4, 3, 2, 1]).range([availableHeight, 0]);
};
getLevelScale = (availableHeight: number) => {
diff --git a/server/sonar-web/src/main/js/components/charts/__tests__/AdvancedTimeline-test.tsx b/server/sonar-web/src/main/js/components/charts/__tests__/AdvancedTimeline-test.tsx
index fbf0cad0c04..ed7dfb4d301 100644
--- a/server/sonar-web/src/main/js/components/charts/__tests__/AdvancedTimeline-test.tsx
+++ b/server/sonar-web/src/main/js/components/charts/__tests__/AdvancedTimeline-test.tsx
@@ -61,18 +61,9 @@ it('should render correctly', () => {
checkSnapShot({ zoomSpeed: 2 }, 'zoomSpeed');
checkSnapShot({ leakPeriodDate: new Date('2019-10-02T00:00:00.000Z') }, 'leakPeriodDate');
checkSnapShot({ basisCurve: true }, 'basisCurve');
- checkSnapShot({ isLegacy: false }, 'not legacy');
checkSnapShot(
- { isLegacy: false, splitPointDate: new Date('2019-10-02T00:00:00.000Z') },
- 'not legacy + split point, but not Rating',
- );
- checkSnapShot(
- {
- isLegacy: false,
- splitPointDate: new Date('2019-10-02T00:00:00.000Z'),
- metricType: MetricType.Rating,
- },
- 'not legacy + split point',
+ { splitPointDate: new Date('2019-10-02T00:00:00.000Z') },
+ 'split point, but not Rating',
);
});
@@ -113,7 +104,6 @@ function renderComponent(props?: Partial<PropsWithoutTheme>) {
]}
width={100}
zoomSpeed={1}
- isLegacy
{...props}
/>
</TooltipProvider>,
diff --git a/server/sonar-web/src/main/js/components/charts/__tests__/__snapshots__/AdvancedTimeline-test.tsx.snap b/server/sonar-web/src/main/js/components/charts/__tests__/__snapshots__/AdvancedTimeline-test.tsx.snap
index 93c34d14707..b44f642ade9 100644
--- a/server/sonar-web/src/main/js/components/charts/__tests__/__snapshots__/AdvancedTimeline-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/charts/__tests__/__snapshots__/AdvancedTimeline-test.tsx.snap
@@ -1913,171 +1913,7 @@ exports[`should render correctly: no height 1`] = `null`;
exports[`should render correctly: no width 1`] = `null`;
-exports[`should render correctly: not legacy + split point 1`] = `
-<svg
- class="line-chart"
- height="100"
- width="100"
->
- <g
- transform="translate(50, 26)"
- >
- <g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="24"
- y2="24"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="16"
- y2="16"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="8"
- y2="8"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="0"
- y2="0"
- />
- </g>
- </g>
- <g
- transform="translate(0, 20)"
- >
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 15, 24)"
- x="15"
- y="24"
- >
- October
- </text>
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 20, 24)"
- x="20"
- y="24"
- >
- 06 AM
- </text>
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 25, 24)"
- x="25"
- y="24"
- >
- 12 PM
- </text>
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 30, 24)"
- x="30"
- y="24"
- >
- 06 PM
- </text>
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 35, 24)"
- x="35"
- y="24"
- >
- Wed 02
- </text>
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 40, 24)"
- x="40"
- y="24"
- >
- 06 AM
- </text>
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 45, 24)"
- x="45"
- y="24"
- >
- 12 PM
- </text>
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 50, 24)"
- x="50"
- y="24"
- >
- 06 PM
- </text>
- </g>
- <g>
- <path
- class="line-chart-path line-chart-path-0"
- d="M0,0L20,8"
- stroke="rgb(85,170,223)"
- stroke-dasharray="0"
- />
- <path
- class="line-chart-path line-chart-path-1"
- d="M40,16Z"
- stroke="rgb(58,127,173)"
- stroke-dasharray="3"
- />
- </g>
- <g>
- <circle
- cx="40"
- cy="16"
- fill="rgb(58,127,173)"
- r="2"
- stroke="white"
- stroke-width="1"
- />
- </g>
- <rect
- class="chart-mouse-events-overlay"
- height="24"
- width="40"
- />
- <line
- class="line-tooltip"
- stroke-dasharray="2"
- x1="20"
- x2="20"
- y1="24"
- y2="-10"
- />
- </g>
-</svg>
-`;
-
-exports[`should render correctly: not legacy + split point, but not Rating 1`] = `
+exports[`should render correctly: rating metric 1`] = `
<svg
class="line-chart"
height="100"
@@ -2101,107 +1937,8 @@ exports[`should render correctly: not legacy + split point, but not Rating 1`] =
class="line-chart-grid"
x1="0"
x2="40"
- y1="22.4"
- y2="22.4"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="20.8"
- y2="20.8"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="19.200000000000003"
- y2="19.200000000000003"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="17.6"
- y2="17.6"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="16"
- y2="16"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="14.400000000000002"
- y2="14.400000000000002"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="12.800000000000002"
- y2="12.800000000000002"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="11.2"
- y2="11.2"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="9.600000000000001"
- y2="9.600000000000001"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="8"
- y2="8"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="6.399999999999999"
- y2="6.399999999999999"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="4.800000000000002"
- y2="4.800000000000002"
+ y1="18"
+ y2="18"
/>
</g>
<g>
@@ -2209,8 +1946,8 @@ exports[`should render correctly: not legacy + split point, but not Rating 1`] =
class="line-chart-grid"
x1="0"
x2="40"
- y1="3.1999999999999993"
- y2="3.1999999999999993"
+ y1="12"
+ y2="12"
/>
</g>
<g>
@@ -2218,8 +1955,8 @@ exports[`should render correctly: not legacy + split point, but not Rating 1`] =
class="line-chart-grid"
x1="0"
x2="40"
- y1="1.6000000000000023"
- y2="1.6000000000000023"
+ y1="6"
+ y2="6"
/>
</g>
<g>
@@ -2311,13 +2048,13 @@ exports[`should render correctly: not legacy + split point, but not Rating 1`] =
<g>
<path
class="line-chart-path line-chart-path-0"
- d="M0,16L20,8"
+ d="M0,0L20,6"
stroke="rgb(85,170,223)"
stroke-dasharray="0"
/>
<path
class="line-chart-path line-chart-path-1"
- d="M40,0Z"
+ d="M40,12Z"
stroke="rgb(58,127,173)"
stroke-dasharray="3"
/>
@@ -2325,7 +2062,7 @@ exports[`should render correctly: not legacy + split point, but not Rating 1`] =
<g>
<circle
cx="40"
- cy="0"
+ cy="12"
fill="rgb(58,127,173)"
r="2"
stroke="white"
@@ -2337,19 +2074,11 @@ exports[`should render correctly: not legacy + split point, but not Rating 1`] =
height="24"
width="40"
/>
- <line
- class="line-tooltip"
- stroke-dasharray="2"
- x1="20"
- x2="20"
- y1="24"
- y2="-10"
- />
</g>
</svg>
`;
-exports[`should render correctly: not legacy 1`] = `
+exports[`should render correctly: selected date 1`] = `
<svg
class="line-chart"
height="100"
@@ -2604,167 +2333,27 @@ exports[`should render correctly: not legacy 1`] = `
stroke-width="1"
/>
</g>
- <rect
- class="chart-mouse-events-overlay"
- height="24"
- width="40"
- />
- </g>
-</svg>
-`;
-
-exports[`should render correctly: rating metric 1`] = `
-<svg
- class="line-chart"
- height="100"
- width="100"
->
- <g
- transform="translate(50, 26)"
- >
<g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="24"
- y2="24"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="18"
- y2="18"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="12"
- y2="12"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="6"
- y2="6"
- />
- </g>
- <g>
- <line
- class="line-chart-grid"
- x1="0"
- x2="40"
- y1="0"
- y2="0"
- />
- </g>
- </g>
- <g
- transform="translate(0, 20)"
- >
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 15, 24)"
- x="15"
- y="24"
- >
- October
- </text>
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 20, 24)"
- x="20"
- y="24"
- >
- 06 AM
- </text>
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 25, 24)"
- x="25"
- y="24"
- >
- 12 PM
- </text>
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 30, 24)"
- x="30"
- y="24"
- >
- 06 PM
- </text>
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 35, 24)"
- x="35"
- y="24"
- >
- Wed 02
- </text>
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 40, 24)"
- x="40"
- y="24"
- >
- 06 AM
- </text>
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 45, 24)"
- x="45"
- y="24"
- >
- 12 PM
- </text>
- <text
- class="line-chart-tick sw-body-sm"
- text-anchor="end"
- transform="rotate(-35, 50, 24)"
- x="50"
- y="24"
- >
- 06 PM
- </text>
- </g>
- <g>
- <path
- class="line-chart-path line-chart-path-0"
- d="M0,0L20,6"
- stroke="rgb(85,170,223)"
- stroke-dasharray="0"
+ <line
+ class="line-tooltip"
+ x1="0"
+ x2="0"
+ y1="24"
+ y2="0"
/>
- <path
- class="line-chart-path line-chart-path-1"
- d="M40,12Z"
- stroke="rgb(58,127,173)"
- stroke-dasharray="3"
+ <circle
+ cx="0"
+ cy="16"
+ fill="rgb(85,170,223)"
+ r="4"
+ stroke="white"
+ stroke-width="1"
/>
- </g>
- <g>
<circle
- cx="40"
- cy="12"
+ cx="0"
+ cy="0"
fill="rgb(58,127,173)"
- r="2"
+ r="4"
stroke="white"
stroke-width="1"
/>
@@ -2778,7 +2367,7 @@ exports[`should render correctly: rating metric 1`] = `
</svg>
`;
-exports[`should render correctly: selected date 1`] = `
+exports[`should render correctly: split point, but not Rating 1`] = `
<svg
class="line-chart"
height="100"
@@ -3033,36 +2622,19 @@ exports[`should render correctly: selected date 1`] = `
stroke-width="1"
/>
</g>
- <g>
- <line
- class="line-tooltip"
- x1="0"
- x2="0"
- y1="24"
- y2="0"
- />
- <circle
- cx="0"
- cy="16"
- fill="rgb(85,170,223)"
- r="4"
- stroke="white"
- stroke-width="1"
- />
- <circle
- cx="0"
- cy="0"
- fill="rgb(58,127,173)"
- r="4"
- stroke="white"
- stroke-width="1"
- />
- </g>
<rect
class="chart-mouse-events-overlay"
height="24"
width="40"
/>
+ <line
+ class="line-tooltip"
+ stroke-dasharray="2"
+ x1="20"
+ x2="20"
+ y1="24"
+ y2="-10"
+ />
</g>
</svg>
`;
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/Facet.tsx b/server/sonar-web/src/main/js/components/facets/Facet.tsx
index 2f594df563f..0273f0f4739 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/Facet.tsx
+++ b/server/sonar-web/src/main/js/components/facets/Facet.tsx
@@ -23,14 +23,15 @@ import { orderBy, sortBy, without } from 'lodash';
import * as React from 'react';
import { formatMeasure } from '~sonar-aligned/helpers/measures';
import { MetricType } from '~sonar-aligned/types/metrics';
-import Tooltip from '../../../components/controls/Tooltip';
-import { translate } from '../../../helpers/l10n';
-import { Dict } from '../../../types/types';
-import { FacetItemsList } from '../../issues/sidebar/FacetItemsList';
-import { MultipleSelectionHint } from '../../issues/sidebar/MultipleSelectionHint';
-import { FacetKey } from '../query';
+import { FacetKey } from '../../apps/coding-rules/query';
+import { FacetItemsList } from '../../apps/issues/sidebar/FacetItemsList';
+import { MultipleSelectionHint } from '../../apps/issues/sidebar/MultipleSelectionHint';
+import { translate } from '../../helpers/l10n';
+import { Dict } from '../../types/types';
+import Tooltip from '../controls/Tooltip';
export interface BasicProps {
+ fetching?: boolean;
help?: React.ReactNode;
onChange: (changes: Dict<string | string[] | undefined>) => void;
onToggle: (facet: FacetKey) => void;
@@ -103,6 +104,7 @@ export default class Facet extends React.PureComponent<Props> {
stats,
help,
values,
+ fetching,
} = this.props;
const items =
this.props.options ||
@@ -119,10 +121,11 @@ export default class Facet extends React.PureComponent<Props> {
return (
<FacetBox
- className={classNames('it__search-navigator-facet-box', {
+ className={classNames('it__search-navigator-facet-box it__search-navigator-facet-header', {
'it__search-navigator-facet-box-forbidden': disabled,
})}
data-property={property}
+ loading={fetching}
clearIconLabel={translate('clear')}
count={values.length}
id={headerId}
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/SeverityFacet.tsx b/server/sonar-web/src/main/js/components/facets/SeverityFacet.tsx
index 6acfbcc3871..3f7cae9eca6 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/SeverityFacet.tsx
+++ b/server/sonar-web/src/main/js/components/facets/SeverityFacet.tsx
@@ -18,28 +18,31 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { HelperHintIcon } from 'design-system';
+import { Popover } from '@sonarsource/echoes-react';
+import { BareButton, HelperHintIcon } from 'design-system';
import * as React from 'react';
-import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip';
-import SoftwareImpactSeverityIcon from '../../../components/icon-mappers/SoftwareImpactSeverityIcon';
-import { IMPACT_SEVERITIES } from '../../../helpers/constants';
-import { DocLink } from '../../../helpers/doc-links';
-import { translate } from '../../../helpers/l10n';
+import { useIntl } from 'react-intl';
+import { IMPACT_SEVERITIES } from '../../helpers/constants';
+import { DocLink } from '../../helpers/doc-links';
+import { translate } from '../../helpers/l10n';
+import DocumentationLink from '../common/DocumentationLink';
+import SoftwareImpactSeverityIcon from '../icon-mappers/SoftwareImpactSeverityIcon';
import Facet, { BasicProps } from './Facet';
-export default function SeverityFacet(props: BasicProps) {
+export default function SeverityFacet(props: Readonly<BasicProps>) {
+ const intl = useIntl();
const renderName = React.useCallback(
(severity: string, disabled: boolean) => (
<div className="sw-flex sw-items-center">
<SoftwareImpactSeverityIcon severity={severity} disabled={disabled} />
- <span className="sw-ml-1">{translate('severity', severity)}</span>
+ <span className="sw-ml-1">{translate('severity_impact', severity)}</span>
</div>
),
[],
);
const renderTextName = React.useCallback(
- (severity: string) => translate('severity', severity),
+ (severity: string) => translate('severity_impact', severity),
[],
);
@@ -51,23 +54,24 @@ export default function SeverityFacet(props: BasicProps) {
renderName={renderName}
renderTextName={renderTextName}
help={
- <DocHelpTooltip
- placement="right"
- content={
+ <Popover
+ title={intl.formatMessage({ id: 'severity_impact.levels' })}
+ description={
<>
- <p>{translate('issues.facet.impactSeverities.help.line1')}</p>
- <p className="sw-mt-2">{translate('issues.facet.impactSeverities.help.line2')}</p>
+ <p>{intl.formatMessage({ id: 'severity_impact.help.line1' })}</p>
+ <p className="sw-mt-2">{intl.formatMessage({ id: 'severity_impact.help.line2' })}</p>
</>
}
- links={[
- {
- href: DocLink.CleanCodeIntroduction,
- label: translate('learn_more'),
- },
- ]}
+ footer={
+ <DocumentationLink to={DocLink.CleanCodeIntroduction}>
+ {intl.formatMessage({ id: 'learn_more' })}
+ </DocumentationLink>
+ }
>
- <HelperHintIcon />
- </DocHelpTooltip>
+ <BareButton aria-label={intl.formatMessage({ id: 'more_information' })}>
+ <HelperHintIcon />
+ </BareButton>
+ </Popover>
}
/>
);
diff --git a/server/sonar-web/src/main/js/components/icon-mappers/SoftwareImpactSeverityIcon.tsx b/server/sonar-web/src/main/js/components/icon-mappers/SoftwareImpactSeverityIcon.tsx
index 61251a5db8c..9d1cebd666b 100644
--- a/server/sonar-web/src/main/js/components/icon-mappers/SoftwareImpactSeverityIcon.tsx
+++ b/server/sonar-web/src/main/js/components/icon-mappers/SoftwareImpactSeverityIcon.tsx
@@ -19,7 +19,9 @@
*/
import {
IconProps,
+ SoftwareImpactSeverityBlockerIcon,
SoftwareImpactSeverityHighIcon,
+ SoftwareImpactSeverityInfoIcon,
SoftwareImpactSeverityLowIcon,
SoftwareImpactSeverityMediumIcon,
} from 'design-system';
@@ -33,10 +35,14 @@ interface Props extends IconProps {
severity: string | null | undefined;
}
+const defaultIconSize = 14;
+
const severityIcons: Dict<(props: IconProps) => React.ReactElement> = {
+ [SoftwareImpactSeverity.Blocker]: SoftwareImpactSeverityBlockerIcon,
[SoftwareImpactSeverity.High]: SoftwareImpactSeverityHighIcon,
[SoftwareImpactSeverity.Medium]: SoftwareImpactSeverityMediumIcon,
[SoftwareImpactSeverity.Low]: SoftwareImpactSeverityLowIcon,
+ [SoftwareImpactSeverity.Info]: SoftwareImpactSeverityInfoIcon,
};
export default function SoftwareImpactSeverityIcon({ severity, ...iconProps }: Readonly<Props>) {
@@ -45,5 +51,12 @@ export default function SoftwareImpactSeverityIcon({ severity, ...iconProps }: R
}
const DesiredIcon = severityIcons[severity];
- return <DesiredIcon {...iconProps} aria-label={translate('severity', severity)} />;
+ return (
+ <DesiredIcon
+ {...iconProps}
+ width={iconProps?.width ?? defaultIconSize}
+ height={iconProps?.height ?? defaultIconSize}
+ aria-label={translate('severity_impact', severity)}
+ />
+ );
}
diff --git a/server/sonar-web/src/main/js/components/measure/utils.ts b/server/sonar-web/src/main/js/components/measure/utils.ts
index 60e1437baf7..f37449d3e98 100644
--- a/server/sonar-web/src/main/js/components/measure/utils.ts
+++ b/server/sonar-web/src/main/js/components/measure/utils.ts
@@ -28,7 +28,6 @@ export const KNOWN_RATINGS = [
MetricKey.software_quality_maintainability_rating,
MetricKey.software_quality_reliability_rating,
MetricKey.software_quality_security_rating,
- MetricKey.software_quality_security_review_rating,
'maintainability_rating', // Needed to provide the label for "new_maintainability_rating"
];
diff --git a/server/sonar-web/src/main/js/components/shared/CleanCodeAttributePill.tsx b/server/sonar-web/src/main/js/components/shared/CleanCodeAttributePill.tsx
index 20ec0c2b7df..9e386598774 100644
--- a/server/sonar-web/src/main/js/components/shared/CleanCodeAttributePill.tsx
+++ b/server/sonar-web/src/main/js/components/shared/CleanCodeAttributePill.tsx
@@ -18,12 +18,13 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { Pill } from 'design-system';
+import { Popover } from '@sonarsource/echoes-react';
+import { Pill, PillVariant } from 'design-system';
import React from 'react';
-import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip';
import { DocLink } from '../../helpers/doc-links';
import { translate } from '../../helpers/l10n';
import { CleanCodeAttribute, CleanCodeAttributeCategory } from '../../types/clean-code-taxonomy';
+import DocumentationLink from '../common/DocumentationLink';
export interface Props {
className?: string;
@@ -36,35 +37,26 @@ export function CleanCodeAttributePill(props: Readonly<Props>) {
const { className, cleanCodeAttributeCategory, cleanCodeAttribute, type = 'issue' } = props;
return (
- <DocHelpTooltip
- content={
- <>
- <p className="sw-mb-4">
- {translate(
- type,
- cleanCodeAttribute ? 'clean_code_attribute' : 'clean_code_attribute_category',
- cleanCodeAttribute ?? cleanCodeAttributeCategory,
- 'title',
- )}
- </p>
- <p>
- {translate(
- 'issue',
- cleanCodeAttribute ? 'clean_code_attribute' : 'clean_code_attribute_category',
- cleanCodeAttribute ?? cleanCodeAttributeCategory,
- 'advice',
- )}
- </p>
- </>
+ <Popover
+ title={translate(
+ type,
+ cleanCodeAttribute ? 'clean_code_attribute' : 'clean_code_attribute_category',
+ cleanCodeAttribute ?? cleanCodeAttributeCategory,
+ 'title',
+ )}
+ description={translate(
+ 'issue',
+ cleanCodeAttribute ? 'clean_code_attribute' : 'clean_code_attribute_category',
+ cleanCodeAttribute ?? cleanCodeAttributeCategory,
+ 'advice',
+ )}
+ footer={
+ <DocumentationLink to={DocLink.CleanCodeIntroduction}>
+ {translate('learn_more')}
+ </DocumentationLink>
}
- links={[
- {
- href: DocLink.CleanCodeIntroduction,
- label: translate('learn_more'),
- },
- ]}
>
- <Pill variant="accent" data-guiding-id="issue-1" className={className}>
+ <Pill variant={PillVariant.Accent} data-guiding-id="issue-1" className={className}>
<span className="sw-font-semibold">
{translate(type, 'clean_code_attribute_category', cleanCodeAttributeCategory)}
</span>
@@ -72,6 +64,6 @@ export function CleanCodeAttributePill(props: Readonly<Props>) {
<span> | {translate(type, 'clean_code_attribute', cleanCodeAttribute)}</span>
)}
</Pill>
- </DocHelpTooltip>
+ </Popover>
);
}
diff --git a/server/sonar-web/src/main/js/components/shared/SoftwareImpactPill.tsx b/server/sonar-web/src/main/js/components/shared/SoftwareImpactPill.tsx
index f0ae5848ac2..88b531e6232 100644
--- a/server/sonar-web/src/main/js/components/shared/SoftwareImpactPill.tsx
+++ b/server/sonar-web/src/main/js/components/shared/SoftwareImpactPill.tsx
@@ -18,14 +18,16 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { Popover } from '@sonarsource/echoes-react';
import classNames from 'classnames';
-import { Pill } from 'design-system';
+import { Pill, PillVariant } from 'design-system';
+import { noop } from 'lodash';
import React from 'react';
import { FormattedMessage } from 'react-intl';
-import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip';
import { DocLink } from '../../helpers/doc-links';
import { translate } from '../../helpers/l10n';
import { SoftwareImpactSeverity } from '../../types/clean-code-taxonomy';
+import DocumentationLink from '../common/DocumentationLink';
import SoftwareImpactSeverityIcon from '../icon-mappers/SoftwareImpactSeverityIcon';
export interface Props {
@@ -39,34 +41,50 @@ export default function SoftwareImpactPill(props: Props) {
const { className, severity, quality, type = 'issue' } = props;
const variant = {
- [SoftwareImpactSeverity.High]: 'danger',
- [SoftwareImpactSeverity.Medium]: 'warning',
- [SoftwareImpactSeverity.Low]: 'info',
- }[severity] as 'danger' | 'warning' | 'info';
+ [SoftwareImpactSeverity.Blocker]: PillVariant.Critical,
+ [SoftwareImpactSeverity.High]: PillVariant.Danger,
+ [SoftwareImpactSeverity.Medium]: PillVariant.Warning,
+ [SoftwareImpactSeverity.Low]: PillVariant.Caution,
+ [SoftwareImpactSeverity.Info]: PillVariant.Info,
+ }[severity];
return (
- <DocHelpTooltip
- content={
- <FormattedMessage
- id={`${type}.impact.severity.tooltip`}
- defaultMessage={translate(`${type}.impact.severity.tooltip`)}
- values={{
- severity: translate('severity', severity).toLowerCase(),
- quality: quality.toLowerCase(),
- }}
- />
+ <Popover
+ title={translate('severity_impact.title')}
+ description={
+ <>
+ <FormattedMessage
+ id={`${type}.impact.severity.tooltip`}
+ values={{
+ severity: translate('severity_impact', severity).toLowerCase(),
+ quality: quality.toLowerCase(),
+ }}
+ />
+ <p className="sw-mt-2">
+ <span className="sw-mr-1">{translate('severity_impact.help.line1')}</span>
+ {translate('severity_impact.help.line2')}
+ </p>
+ </>
+ }
+ footer={
+ <DocumentationLink to={DocLink.CleanCodeIntroduction}>
+ {translate('learn_more')}
+ </DocumentationLink>
}
- links={[
- {
- href: DocLink.CleanCodeIntroduction,
- label: translate('learn_more'),
- },
- ]}
>
- <Pill className={classNames('sw-flex sw-gap-1 sw-items-center', className)} variant={variant}>
+ <Pill
+ className={classNames('sw-flex sw-gap-1 sw-items-center', className)}
+ onClick={noop}
+ variant={variant}
+ >
{quality}
- <SoftwareImpactSeverityIcon severity={severity} data-guiding-id="issue-3" />
+ <SoftwareImpactSeverityIcon
+ width={14}
+ height={14}
+ severity={severity}
+ data-guiding-id="issue-3"
+ />
</Pill>
- </DocHelpTooltip>
+ </Popover>
);
}
diff --git a/server/sonar-web/src/main/js/components/shared/SoftwareImpactPillList.tsx b/server/sonar-web/src/main/js/components/shared/SoftwareImpactPillList.tsx
index 3bc09b6b130..476e9cd98bf 100644
--- a/server/sonar-web/src/main/js/components/shared/SoftwareImpactPillList.tsx
+++ b/server/sonar-web/src/main/js/components/shared/SoftwareImpactPillList.tsx
@@ -34,9 +34,11 @@ interface SoftwareImpactPillListProps extends React.HTMLAttributes<HTMLUListElem
}
const severityMap = {
- [SoftwareImpactSeverity.High]: 2,
- [SoftwareImpactSeverity.Medium]: 1,
- [SoftwareImpactSeverity.Low]: 0,
+ [SoftwareImpactSeverity.Blocker]: 4,
+ [SoftwareImpactSeverity.High]: 3,
+ [SoftwareImpactSeverity.Medium]: 2,
+ [SoftwareImpactSeverity.Low]: 1,
+ [SoftwareImpactSeverity.Info]: 0,
};
export default function SoftwareImpactPillList({
diff --git a/server/sonar-web/src/main/js/helpers/activity-graph.ts b/server/sonar-web/src/main/js/helpers/activity-graph.ts
index 6d7ebd1b895..62c3e9d46c4 100644
--- a/server/sonar-web/src/main/js/helpers/activity-graph.ts
+++ b/server/sonar-web/src/main/js/helpers/activity-graph.ts
@@ -68,10 +68,7 @@ export const mergeRatingMeasureHistory = (
const historyMapper = (historyItem: { date: string; value?: string }) => ({
date: parseDateFn(historyItem.date),
- value:
- softwareQualityMeasuresMap.size > 0 && historyItem.value === '5.0'
- ? '4.0'
- : historyItem.value,
+ value: historyItem.value,
});
return historyDataFiltered.map((measure) => {
diff --git a/server/sonar-web/src/main/js/helpers/constants.ts b/server/sonar-web/src/main/js/helpers/constants.ts
index ce344a72320..2e70556dfaa 100644
--- a/server/sonar-web/src/main/js/helpers/constants.ts
+++ b/server/sonar-web/src/main/js/helpers/constants.ts
@@ -112,11 +112,9 @@ export const LEAK_OLD_TAXONOMY_METRICS = [
];
export const OLD_TAXONOMY_RATINGS = [
- MetricKey.releasability_rating,
MetricKey.sqale_rating,
MetricKey.security_rating,
MetricKey.reliability_rating,
- MetricKey.security_review_rating,
MetricKey.sqale_index,
MetricKey.reliability_remediation_effort,
MetricKey.security_remediation_effort,
@@ -128,7 +126,6 @@ export const LEAK_OLD_TAXONOMY_RATINGS = [
MetricKey.new_maintainability_rating,
MetricKey.new_security_rating,
MetricKey.new_reliability_rating,
- MetricKey.new_security_review_rating,
MetricKey.new_technical_debt,
MetricKey.new_security_remediation_effort,
MetricKey.new_reliability_remediation_effort,
@@ -191,9 +188,6 @@ export const DEPRECATED_ACTIVITY_METRICS = [
];
export const SOFTWARE_QUALITY_RATING_METRICS_MAP: Record<string, MetricKey> = {
- [MetricKey.releasability_rating]: MetricKey.software_quality_releasability_rating,
- [MetricKey.releasability_rating_distribution]:
- MetricKey.software_quality_releasability_rating_distribution,
[MetricKey.sqale_rating]: MetricKey.software_quality_maintainability_rating,
[MetricKey.maintainability_rating_distribution]:
MetricKey.software_quality_maintainability_rating_distribution,
@@ -202,9 +196,6 @@ export const SOFTWARE_QUALITY_RATING_METRICS_MAP: Record<string, MetricKey> = {
[MetricKey.reliability_rating]: MetricKey.software_quality_reliability_rating,
[MetricKey.reliability_rating_distribution]:
MetricKey.software_quality_reliability_rating_distribution,
- [MetricKey.security_review_rating]: MetricKey.software_quality_security_review_rating,
- [MetricKey.security_review_rating_distribution]:
- MetricKey.software_quality_security_review_rating_distribution,
[MetricKey.reliability_remediation_effort]:
MetricKey.software_quality_reliability_remediation_effort,
[MetricKey.security_remediation_effort]: MetricKey.software_quality_security_remediation_effort,
@@ -214,20 +205,14 @@ export const SOFTWARE_QUALITY_RATING_METRICS_MAP: Record<string, MetricKey> = {
MetricKey.effort_to_reach_software_quality_maintainability_rating_a,
[MetricKey.last_change_on_maintainability_rating]:
MetricKey.last_change_on_software_quality_maintainability_rating,
- [MetricKey.last_change_on_releasability_rating]:
- MetricKey.last_change_on_software_quality_releasability_rating,
[MetricKey.last_change_on_reliability_rating]:
MetricKey.last_change_on_software_quality_reliability_rating,
[MetricKey.last_change_on_security_rating]:
MetricKey.last_change_on_software_quality_security_rating,
- [MetricKey.last_change_on_security_review_rating]:
- MetricKey.last_change_on_software_quality_security_review_rating,
[MetricKey.maintainability_rating_effort]:
MetricKey.software_quality_maintainability_rating_effort,
[MetricKey.reliability_rating_effort]: MetricKey.software_quality_reliability_rating_effort,
[MetricKey.security_rating_effort]: MetricKey.software_quality_security_rating_effort,
- [MetricKey.security_review_rating_effort]:
- MetricKey.software_quality_security_review_rating_effort,
[MetricKey.new_maintainability_rating]: MetricKey.new_software_quality_maintainability_rating,
[MetricKey.new_maintainability_rating_distribution]:
MetricKey.new_software_quality_maintainability_rating_distribution,
@@ -237,9 +222,6 @@ export const SOFTWARE_QUALITY_RATING_METRICS_MAP: Record<string, MetricKey> = {
[MetricKey.new_reliability_rating]: MetricKey.new_software_quality_reliability_rating,
[MetricKey.new_reliability_rating_distribution]:
MetricKey.new_software_quality_reliability_rating_distribution,
- [MetricKey.new_security_review_rating]: MetricKey.new_software_quality_security_review_rating,
- [MetricKey.new_security_review_rating_distribution]:
- MetricKey.new_software_quality_security_review_rating_distribution,
[MetricKey.new_technical_debt]: MetricKey.new_software_quality_maintainability_remediation_effort,
[MetricKey.new_reliability_remediation_effort]:
MetricKey.new_software_quality_reliability_remediation_effort,
@@ -249,11 +231,9 @@ export const SOFTWARE_QUALITY_RATING_METRICS_MAP: Record<string, MetricKey> = {
};
export const SOFTWARE_QUALITY_RATING_METRICS = [
- MetricKey.software_quality_releasability_rating,
MetricKey.software_quality_maintainability_rating,
MetricKey.software_quality_security_rating,
MetricKey.software_quality_reliability_rating,
- MetricKey.software_quality_security_review_rating,
MetricKey.software_quality_maintainability_remediation_effort,
MetricKey.software_quality_reliability_remediation_effort,
MetricKey.software_quality_security_remediation_effort,
@@ -262,7 +242,6 @@ export const SOFTWARE_QUALITY_RATING_METRICS = [
MetricKey.new_software_quality_maintainability_rating,
MetricKey.new_software_quality_security_rating,
MetricKey.new_software_quality_reliability_rating,
- MetricKey.new_software_quality_security_review_rating,
MetricKey.new_software_quality_maintainability_remediation_effort,
MetricKey.new_software_quality_reliability_remediation_effort,
MetricKey.new_software_quality_security_remediation_effort,
diff --git a/server/sonar-web/src/main/js/sonar-aligned/types/metrics.ts b/server/sonar-web/src/main/js/sonar-aligned/types/metrics.ts
index d88e3fcf552..7ce4c1604ed 100644
--- a/server/sonar-web/src/main/js/sonar-aligned/types/metrics.ts
+++ b/server/sonar-web/src/main/js/sonar-aligned/types/metrics.ts
@@ -69,10 +69,8 @@ export enum MetricKey {
last_change_on_security_rating = 'last_change_on_security_rating',
last_change_on_security_review_rating = 'last_change_on_security_review_rating',
last_change_on_software_quality_maintainability_rating = 'last_change_on_software_quality_maintainability_rating',
- last_change_on_software_quality_releasability_rating = 'last_change_on_software_quality_releasability_rating',
last_change_on_software_quality_reliability_rating = 'last_change_on_software_quality_reliability_rating',
last_change_on_software_quality_security_rating = 'last_change_on_software_quality_security_rating',
- last_change_on_software_quality_security_review_rating = 'last_change_on_software_quality_security_review_rating',
last_commit_date = 'last_commit_date',
leak_projects = 'leak_projects',
line_coverage = 'line_coverage',
@@ -129,9 +127,7 @@ export enum MetricKey {
new_security_remediation_effort = 'new_security_remediation_effort',
new_software_quality_security_remediation_effort = 'new_software_quality_security_remediation_effort',
new_security_review_rating = 'new_security_review_rating',
- new_software_quality_security_review_rating = 'new_software_quality_security_review_rating',
new_security_review_rating_distribution = 'new_security_review_rating_distribution',
- new_software_quality_security_review_rating_distribution = 'new_software_quality_security_review_rating_distribution',
new_sqale_debt_ratio = 'new_sqale_debt_ratio',
new_software_quality_maintainability_debt_ratio = 'new_software_quality_maintainability_debt_ratio',
new_technical_debt = 'new_technical_debt',
@@ -152,9 +148,7 @@ export enum MetricKey {
quality_profiles = 'quality_profiles',
releasability_effort = 'releasability_effort',
releasability_rating = 'releasability_rating',
- software_quality_releasability_rating = 'software_quality_releasability_rating',
releasability_rating_distribution = 'releasability_rating_distribution',
- software_quality_releasability_rating_distribution = 'software_quality_releasability_rating_distribution',
reliability_issues = 'reliability_issues',
reliability_rating = 'reliability_rating',
software_quality_reliability_rating = 'software_quality_reliability_rating',
@@ -177,11 +171,8 @@ export enum MetricKey {
security_remediation_effort = 'security_remediation_effort',
software_quality_security_remediation_effort = 'software_quality_security_remediation_effort',
security_review_rating = 'security_review_rating',
- software_quality_security_review_rating = 'software_quality_security_review_rating',
security_review_rating_distribution = 'security_review_rating_distribution',
- software_quality_security_review_rating_distribution = 'software_quality_security_review_rating_distribution',
security_review_rating_effort = 'security_review_rating_effort',
- software_quality_security_review_rating_effort = 'software_quality_security_review_rating_effort',
skipped_tests = 'skipped_tests',
sonarjava_feedback = 'sonarjava_feedback',
sqale_debt_ratio = 'sqale_debt_ratio',
diff --git a/server/sonar-web/src/main/js/types/clean-code-taxonomy.ts b/server/sonar-web/src/main/js/types/clean-code-taxonomy.ts
index 13bea9be601..d5a80809f20 100644
--- a/server/sonar-web/src/main/js/types/clean-code-taxonomy.ts
+++ b/server/sonar-web/src/main/js/types/clean-code-taxonomy.ts
@@ -18,9 +18,11 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
export enum SoftwareImpactSeverity {
+ Blocker = 'BLOCKER',
High = 'HIGH',
Medium = 'MEDIUM',
Low = 'LOW',
+ Info = 'INFO',
}
export enum CleanCodeAttributeCategory {
@@ -60,7 +62,9 @@ export interface SoftwareImpact {
export interface SoftwareImpactMeasureData {
total: number;
+ [SoftwareImpactSeverity.Blocker]: number;
[SoftwareImpactSeverity.High]: number;
[SoftwareImpactSeverity.Medium]: number;
[SoftwareImpactSeverity.Low]: number;
+ [SoftwareImpactSeverity.Info]: number;
}
diff --git a/server/sonar-web/src/main/js/types/jest.d.ts b/server/sonar-web/src/main/js/types/jest.d.ts
index 7f43b94e89a..8db287d8628 100644
--- a/server/sonar-web/src/main/js/types/jest.d.ts
+++ b/server/sonar-web/src/main/js/types/jest.d.ts
@@ -19,6 +19,7 @@
*/
declare namespace jest {
interface Matchers<R> {
+ toHaveAPopoverWithContent(content: string): Promise<CustomMatcherResult>;
toHaveATooltipWithContent(content: string): Promise<CustomMatcherResult>;
toHaveNoA11yViolations(): Promise<CustomMatcherResult>;
}
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java
index 9d6344f96e2..eb678ce714d 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java
@@ -21,7 +21,6 @@ package org.sonar.server.measure.index;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -107,11 +106,9 @@ import static org.sonar.api.measures.CoreMetrics.SQALE_RATING_KEY;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY;
-import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING_KEY;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING_KEY;
-import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY;
import static org.sonar.server.es.EsUtils.escapeSpecialRegexChars;
import static org.sonar.server.es.EsUtils.termsToMap;
import static org.sonar.server.es.IndexType.FIELD_INDEX_TYPE;
@@ -175,14 +172,12 @@ public class ProjectMeasuresIndex {
NEW_SECURITY_REVIEW_RATING(new RatingMeasureFacet(NEW_SECURITY_REVIEW_RATING_KEY)),
//Software quality ratings
- SOFTWARE_QUALITY_MAINTAINABILITY_RATING(new RatingMeasureFacet(SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, 4)),
- NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING(new RatingMeasureFacet(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, 4)),
- SOFTWARE_QUALITY_RELIABILITY_RATING(new RatingMeasureFacet(SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, 4)),
- NEW_SOFTWARE_QUALITY_RELIABILITY_RATING(new RatingMeasureFacet(NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, 4)),
- SOFTWARE_QUALITY_SECURITY_RATING(new RatingMeasureFacet(SOFTWARE_QUALITY_SECURITY_RATING_KEY, 4)),
- NEW_SOFTWARE_QUALITY_SECURITY_RATING(new RatingMeasureFacet(NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, 4)),
- SOFTWARE_QUALITY_SECURITY_REVIEW_RATING(new RatingMeasureFacet(SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY, 4)),
- NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING(new RatingMeasureFacet(NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY, 4)),
+ SOFTWARE_QUALITY_MAINTAINABILITY_RATING(new RatingMeasureFacet(SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY)),
+ NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING(new RatingMeasureFacet(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY)),
+ SOFTWARE_QUALITY_RELIABILITY_RATING(new RatingMeasureFacet(SOFTWARE_QUALITY_RELIABILITY_RATING_KEY)),
+ NEW_SOFTWARE_QUALITY_RELIABILITY_RATING(new RatingMeasureFacet(NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY)),
+ SOFTWARE_QUALITY_SECURITY_RATING(new RatingMeasureFacet(SOFTWARE_QUALITY_SECURITY_RATING_KEY)),
+ NEW_SOFTWARE_QUALITY_SECURITY_RATING(new RatingMeasureFacet(NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY)),
SECURITY_HOTSPOTS_REVIEWED(new RangeMeasureFacet(SECURITY_HOTSPOTS_REVIEWED_KEY, SECURITY_REVIEW_RATING_THRESHOLDS)),
NEW_SECURITY_HOTSPOTS_REVIEWED(new RangeMeasureFacet(NEW_SECURITY_HOTSPOTS_REVIEWED_KEY, SECURITY_REVIEW_RATING_THRESHOLDS)),
@@ -588,20 +583,14 @@ public class ProjectMeasuresIndex {
private static class RatingMeasureFacet extends MeasureFacet {
private RatingMeasureFacet(String metricKey) {
- super(metricKey, new MetricRatingFacetBuilder(metricKey, 5));
- }
-
- private RatingMeasureFacet(String metricKey, int maxRating) {
- super(metricKey, new MetricRatingFacetBuilder(metricKey, maxRating));
+ super(metricKey, new MetricRatingFacetBuilder(metricKey));
}
private static class MetricRatingFacetBuilder implements FacetBuilder {
private final String metricKey;
- private final int maxRating;
- private MetricRatingFacetBuilder(String metricKey, int maxRating) {
+ private MetricRatingFacetBuilder(String metricKey) {
this.metricKey = metricKey;
- this.maxRating = maxRating;
}
@Override
@@ -609,20 +598,19 @@ public class ProjectMeasuresIndex {
return topAggregationHelper.buildTopAggregation(
facet.getName(), facet.getTopAggregationDef(),
NO_EXTRA_FILTER,
- t -> t.subAggregation(createMeasureRatingFacet(metricKey, maxRating)));
+ t -> t.subAggregation(createMeasureRatingFacet(metricKey)));
}
- private static AbstractAggregationBuilder<?> createMeasureRatingFacet(String metricKey, int maxRating) {
- List<KeyedFilter> filter = new ArrayList<>();
- for (int i = 1; i <= maxRating; i++) {
- filter.add(new KeyedFilter(String.valueOf(i), termQuery(FIELD_MEASURES_MEASURE_VALUE, Double.valueOf(i))));
- }
-
+ private static AbstractAggregationBuilder<?> createMeasureRatingFacet(String metricKey) {
return AggregationBuilders.nested("nested_" + metricKey, FIELD_MEASURES)
.subAggregation(
AggregationBuilders.filter("filter_" + metricKey, termsQuery(FIELD_MEASURES_MEASURE_KEY, metricKey))
- .subAggregation(filters(metricKey, filter.toArray(new KeyedFilter[0])
- )));
+ .subAggregation(filters(metricKey,
+ new KeyedFilter("1", termQuery(FIELD_MEASURES_MEASURE_VALUE, 1D)),
+ new KeyedFilter("2", termQuery(FIELD_MEASURES_MEASURE_VALUE, 2D)),
+ new KeyedFilter("3", termQuery(FIELD_MEASURES_MEASURE_VALUE, 3D)),
+ new KeyedFilter("4", termQuery(FIELD_MEASURES_MEASURE_VALUE, 4D)),
+ new KeyedFilter("5", termQuery(FIELD_MEASURES_MEASURE_VALUE, 5D)))));
}
}
}
diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java
index 40a8403f089..ffeffc9647e 100644
--- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java
+++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java
@@ -52,6 +52,7 @@ import static org.sonar.api.issue.Issue.STATUS_REOPENED;
import static org.sonar.api.issue.Issue.STATUS_RESOLVED;
import static org.sonar.api.issue.impact.SoftwareQuality.MAINTAINABILITY;
import static org.sonar.api.issue.impact.SoftwareQuality.RELIABILITY;
+import static org.sonar.api.issue.impact.SoftwareQuality.SECURITY;
import static org.sonar.api.rule.Severity.BLOCKER;
import static org.sonar.api.rule.Severity.CRITICAL;
import static org.sonar.api.rule.Severity.INFO;
@@ -115,7 +116,8 @@ class IssueIndexFacetsTest extends IssueIndexTestCommon {
newDoc("I4", project.uuid(), file2),
newDoc("I5", project.uuid(), file3));
- assertThatFacetHasOnly(IssueQuery.builder(), "files", entry("src/NAME_ABCD", 1L), entry("src/NAME_BCDE", 2L), entry("src/NAME_CDEF", 1L));
+ assertThatFacetHasOnly(IssueQuery.builder(), "files", entry("src/NAME_ABCD", 1L), entry("src/NAME_BCDE", 2L), entry("src/NAME_CDEF",
+ 1L));
}
@Test
@@ -147,13 +149,15 @@ class IssueIndexFacetsTest extends IssueIndexTestCommon {
void facet_on_directories_return_100_entries_plus_selected_values() {
ComponentDto project = newPrivateProjectDto();
indexIssues(
- rangeClosed(1, 110).mapToObj(i -> newDoc(newFileDto(project, newDirectory(project, "dir" + i)), project.uuid()).setDirectoryPath("a" + i)).toArray(IssueDoc[]::new));
+ rangeClosed(1, 110).mapToObj(i -> newDoc(newFileDto(project, newDirectory(project, "dir" + i)), project.uuid()).setDirectoryPath("a"
+ + i)).toArray(IssueDoc[]::new));
IssueDoc issue1 = newDoc(newFileDto(project, newDirectory(project, "path1")), project.uuid()).setDirectoryPath("directory1");
IssueDoc issue2 = newDoc(newFileDto(project, newDirectory(project, "path2")), project.uuid()).setDirectoryPath("directory2");
indexIssues(issue1, issue2);
assertThatFacetHasSize(IssueQuery.builder().build(), "directories", 100);
- assertThatFacetHasSize(IssueQuery.builder().directories(asList(issue1.directoryPath(), issue2.directoryPath())).build(), "directories", 102);
+ assertThatFacetHasSize(IssueQuery.builder().directories(asList(issue1.directoryPath(), issue2.directoryPath())).build(), "directories"
+ , 102);
}
@Test
@@ -275,7 +279,8 @@ class IssueIndexFacetsTest extends IssueIndexTestCommon {
ComponentDto file = newFileDto(project);
indexIssues(
- newDoc("I1", project.uuid(), file).setType(RuleType.VULNERABILITY).setSansTop25(asList("porous-defenses", "risky-resource", "insecure-interaction")),
+ newDoc("I1", project.uuid(), file).setType(RuleType.VULNERABILITY).setSansTop25(asList("porous-defenses", "risky-resource",
+ "insecure-interaction")),
newDoc("I2", project.uuid(), file).setType(RuleType.VULNERABILITY).setSansTop25(singletonList("porous-defenses")),
newDoc("I3", project.uuid(), file));
@@ -458,7 +463,8 @@ class IssueIndexFacetsTest extends IssueIndexTestCommon {
indexIssues(issue1, issue2);
assertThatFacetHasSize(IssueQuery.builder().build(), "assignees", 100);
- assertThatFacetHasSize(IssueQuery.builder().assigneeUuids(asList(issue1.assigneeUuid(), issue2.assigneeUuid())).build(), "assignees", 102);
+ assertThatFacetHasSize(IssueQuery.builder().assigneeUuids(asList(issue1.assigneeUuid(), issue2.assigneeUuid())).build(), "assignees",
+ 102);
}
@Test
@@ -588,8 +594,8 @@ class IssueIndexFacetsTest extends IssueIndexTestCommon {
SearchOptions options = fixtureForCreatedAtFacet();
SearchResponse result = underTest.search(IssueQuery.builder()
- .createdAfter(parseDateTime("2014-09-01T00:00:00+0100"))
- .createdBefore(parseDateTime("2014-09-21T00:00:00+0100")).build(),
+ .createdAfter(parseDateTime("2014-09-01T00:00:00+0100"))
+ .createdBefore(parseDateTime("2014-09-21T00:00:00+0100")).build(),
options);
Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt");
assertThat(createdAt).containsOnly(
@@ -604,8 +610,8 @@ class IssueIndexFacetsTest extends IssueIndexTestCommon {
SearchOptions options = fixtureForCreatedAtFacet();
SearchResponse result = underTest.search(IssueQuery.builder()
- .createdAfter(parseDateTime("2014-09-01T00:00:00+0100"))
- .createdBefore(parseDateTime("2015-01-19T00:00:00+0100")).build(),
+ .createdAfter(parseDateTime("2014-09-01T00:00:00+0100"))
+ .createdBefore(parseDateTime("2015-01-19T00:00:00+0100")).build(),
options);
Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt");
assertThat(createdAt).containsOnly(
@@ -622,8 +628,8 @@ class IssueIndexFacetsTest extends IssueIndexTestCommon {
SearchOptions options = fixtureForCreatedAtFacet();
SearchResponse result = underTest.search(IssueQuery.builder()
- .createdAfter(parseDateTime("2011-01-01T00:00:00+0100"))
- .createdBefore(parseDateTime("2016-01-01T00:00:00+0100")).build(),
+ .createdAfter(parseDateTime("2011-01-01T00:00:00+0100"))
+ .createdBefore(parseDateTime("2016-01-01T00:00:00+0100")).build(),
options);
Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt");
assertThat(createdAt).containsOnly(
@@ -640,8 +646,8 @@ class IssueIndexFacetsTest extends IssueIndexTestCommon {
SearchOptions options = fixtureForCreatedAtFacet();
SearchResponse result = underTest.search(IssueQuery.builder()
- .createdAfter(parseDateTime("2014-09-01T00:00:00-0100"))
- .createdBefore(parseDateTime("2014-09-02T00:00:00-0100")).build(),
+ .createdAfter(parseDateTime("2014-09-01T00:00:00-0100"))
+ .createdBefore(parseDateTime("2014-09-02T00:00:00-0100")).build(),
options);
Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt");
assertThat(createdAt).containsOnly(
@@ -673,7 +679,7 @@ class IssueIndexFacetsTest extends IssueIndexTestCommon {
SearchOptions searchOptions = fixtureForCreatedAtFacet();
SearchResponse result = underTest.search(IssueQuery.builder()
- .createdBefore(parseDateTime("2016-01-01T00:00:00+0100")).build(),
+ .createdBefore(parseDateTime("2016-01-01T00:00:00+0100")).build(),
searchOptions);
Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt");
assertThat(createdAt).containsOnly(
@@ -739,8 +745,8 @@ class IssueIndexFacetsTest extends IssueIndexTestCommon {
indexIssues(
newDoc("I1", project.uuid(), file).setImpacts(Map.of(
- MAINTAINABILITY, org.sonar.api.issue.impact.Severity.HIGH,
- RELIABILITY, org.sonar.api.issue.impact.Severity.MEDIUM))
+ MAINTAINABILITY, org.sonar.api.issue.impact.Severity.HIGH,
+ RELIABILITY, org.sonar.api.issue.impact.Severity.MEDIUM))
.setTags(singletonList("my-tag")),
newDoc("I2", project.uuid(), file).setImpacts(Map.of(
MAINTAINABILITY, org.sonar.api.issue.impact.Severity.LOW)),
@@ -765,14 +771,15 @@ class IssueIndexFacetsTest extends IssueIndexTestCommon {
entry("RELIABILITY", 1L),
entry("SECURITY", 0L));
- assertThatFacetHasOnly(IssueQuery.builder().impactSeverities(Set.of(org.sonar.api.issue.impact.Severity.HIGH.name())), "impactSoftwareQualities",
+ assertThatFacetHasOnly(IssueQuery.builder().impactSeverities(Set.of(org.sonar.api.issue.impact.Severity.HIGH.name())),
+ "impactSoftwareQualities",
entry("MAINTAINABILITY", 1L),
entry("RELIABILITY", 1L),
entry("SECURITY", 0L));
assertThatFacetHasOnly(IssueQuery.builder()
- .tags(singletonList("my-tag"))
- .impactSeverities(Set.of(org.sonar.api.issue.impact.Severity.HIGH.name())), "impactSoftwareQualities",
+ .tags(singletonList("my-tag"))
+ .impactSeverities(Set.of(org.sonar.api.issue.impact.Severity.HIGH.name())), "impactSoftwareQualities",
entry("MAINTAINABILITY", 1L),
entry("RELIABILITY", 0L),
entry("SECURITY", 0L));
@@ -786,23 +793,26 @@ class IssueIndexFacetsTest extends IssueIndexTestCommon {
indexIssues(
newDoc("I1", project.uuid(), file).setImpacts(Map.of(
MAINTAINABILITY, org.sonar.api.issue.impact.Severity.LOW,
- RELIABILITY, org.sonar.api.issue.impact.Severity.LOW)));
+ RELIABILITY, org.sonar.api.issue.impact.Severity.LOW,
+ SECURITY, org.sonar.api.issue.impact.Severity.BLOCKER)));
assertThatFacetHasOnly(IssueQuery.builder()
- .impactSoftwareQualities(Set.of(MAINTAINABILITY.name()))
- .impactSeverities(Set.of(org.sonar.api.issue.impact.Severity.LOW.name())),
+ .impactSoftwareQualities(Set.of(MAINTAINABILITY.name()))
+ .impactSeverities(Set.of(org.sonar.api.issue.impact.Severity.LOW.name())),
"impactSoftwareQualities",
entry("MAINTAINABILITY", 1L),
entry("RELIABILITY", 1L),
entry("SECURITY", 0L));
assertThatFacetHasOnly(IssueQuery.builder()
- .impactSoftwareQualities(Set.of(MAINTAINABILITY.name()))
- .impactSeverities(Set.of(org.sonar.api.issue.impact.Severity.LOW.name())),
+ .impactSoftwareQualities(Set.of(MAINTAINABILITY.name()))
+ .impactSeverities(Set.of(org.sonar.api.issue.impact.Severity.LOW.name())),
"impactSeverities",
entry("HIGH", 0L),
entry("MEDIUM", 0L),
- entry("LOW", 1L));
+ entry("LOW", 1L),
+ entry("INFO", 0L),
+ entry("BLOCKER", 0L));
}
@Test
@@ -817,14 +827,18 @@ class IssueIndexFacetsTest extends IssueIndexTestCommon {
newDoc("I2", project.uuid(), file).setImpacts(Map.of(
MAINTAINABILITY, org.sonar.api.issue.impact.Severity.LOW)),
newDoc("I3", project.uuid(), file).setImpacts(Map.of(
- RELIABILITY, org.sonar.api.issue.impact.Severity.HIGH)),
+ RELIABILITY, org.sonar.api.issue.impact.Severity.HIGH,
+ SECURITY, org.sonar.api.issue.impact.Severity.BLOCKER)),
newDoc("I4", project.uuid(), file).setImpacts(Map.of(
- MAINTAINABILITY, org.sonar.api.issue.impact.Severity.LOW)));
+ MAINTAINABILITY, org.sonar.api.issue.impact.Severity.LOW,
+ RELIABILITY, org.sonar.api.issue.impact.Severity.INFO)));
assertThatFacetHasOnly(IssueQuery.builder(), "impactSeverities",
entry("HIGH", 2L),
entry("MEDIUM", 1L),
- entry("LOW", 2L));
+ entry("LOW", 2L),
+ entry("BLOCKER", 1L),
+ entry("INFO", 1L));
}
@Test
@@ -846,7 +860,9 @@ class IssueIndexFacetsTest extends IssueIndexTestCommon {
assertThatFacetHasOnly(IssueQuery.builder().impactSoftwareQualities(Set.of(MAINTAINABILITY.name())), "impactSeverities",
entry("HIGH", 1L),
entry("MEDIUM", 0L),
- entry("LOW", 2L));
+ entry("LOW", 2L),
+ entry("BLOCKER", 0L),
+ entry("INFO", 0L));
}
@Test
diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java
index 8b21640cbb5..8c2c0ad6af8 100644
--- a/server/sonar-webserver-es/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java
+++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java
@@ -85,8 +85,6 @@ class ProjectMeasuresIndexTest {
private static final String NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY = "new_software_quality_reliability_rating";
private static final String SOFTWARE_QUALITY_SECURITY_RATING_KEY = "software_quality_security_rating";
private static final String NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY = "new_software_quality_security_rating";
- private static final String SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY = "software_quality_security_review_rating";
- private static final String NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY = "new_software_quality_security_review_rating";
private static final String SECURITY_HOTSPOTS_REVIEWED = "security_hotspots_reviewed";
private static final String NEW_SECURITY_HOTSPOTS_REVIEWED = "new_security_hotspots_reviewed";
@@ -127,8 +125,7 @@ class ProjectMeasuresIndexTest {
return new String[]{
SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY,
SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY,
- SOFTWARE_QUALITY_SECURITY_RATING_KEY, NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY,
- SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY, NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY
+ SOFTWARE_QUALITY_SECURITY_RATING_KEY, NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY
};
}
@@ -1088,7 +1085,10 @@ class ProjectMeasuresIndexTest {
newDoc(metricKey, 3d),
// 2 docs with rating D
newDoc(metricKey, 4d),
- newDoc(metricKey, 4d));
+ newDoc(metricKey, 4d),
+ // 1 doc with rating E
+ newDoc(metricKey, 5d));
+
Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(metricKey)).getFacets();
@@ -1096,7 +1096,8 @@ class ProjectMeasuresIndexTest {
entry("1", 3L),
entry("2", 2L),
entry("3", 4L),
- entry("4", 2L));
+ entry("4", 2L),
+ entry("5", 1L));
}
@ParameterizedTest
@@ -1160,7 +1161,9 @@ class ProjectMeasuresIndexTest {
newDoc(metricKey, 3d, NCLOC, 40000d, COVERAGE, 0d),
newDoc(metricKey, 3d, NCLOC, 50000d, COVERAGE, 0d),
// docs with rating D
- newDoc(metricKey, 4d, NCLOC, 120000d, COVERAGE, 0d));
+ newDoc(metricKey, 4d, NCLOC, 120000d, COVERAGE, 0d),
+ // docs with rating E
+ newDoc(metricKey, 5d, NCLOC, 120000d, COVERAGE, 0d));
Facets facets = underTest.search(new ProjectMeasuresQuery()
.addMetricCriterion(MetricCriterion.create(metricKey, Operator.LT, 3d))
@@ -1172,7 +1175,8 @@ class ProjectMeasuresIndexTest {
entry("1", 3L),
entry("2", 2L),
entry("3", 4L),
- entry("4", 1L));
+ entry("4", 1L),
+ entry("5", 1L));
// But facet on ncloc does well take into into filters
assertThat(facets.get(NCLOC)).containsExactly(
entry("*-1000.0", 3L),
@@ -1233,7 +1237,9 @@ class ProjectMeasuresIndexTest {
// docs with rating C
newDoc(metricKey, 3d),
// docs with rating D
- newDoc(metricKey, 4d));
+ newDoc(metricKey, 4d),
+ // docs with rating E
+ newDoc(metricKey, 5d));
userSession.logIn(USER1);
Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(metricKey)).getFacets();
@@ -1242,7 +1248,8 @@ class ProjectMeasuresIndexTest {
entry("1", 3L),
entry("2", 2L),
entry("3", 0L),
- entry("4", 0L));
+ entry("4", 0L),
+ entry("5", 0L));
}
@Test
diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/enums/ImpactSeverityRestEnum.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/enums/ImpactSeverityRestEnum.java
index f6c7f9307e5..1ef9f7e82a0 100644
--- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/enums/ImpactSeverityRestEnum.java
+++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/enums/ImpactSeverityRestEnum.java
@@ -23,9 +23,11 @@ import java.util.Arrays;
import org.sonar.api.issue.impact.Severity;
public enum ImpactSeverityRestEnum {
+ INFO(Severity.INFO),
LOW(Severity.LOW),
MEDIUM(Severity.MEDIUM),
- HIGH(Severity.HIGH);
+ HIGH(Severity.HIGH),
+ BLOCKER(Severity.BLOCKER);
private final Severity severity;
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SearchProjectsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SearchProjectsActionIT.java
index 3269fa61cce..f7744ed7dc4 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SearchProjectsActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SearchProjectsActionIT.java
@@ -99,11 +99,9 @@ import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY;
-import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING_KEY;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING_KEY;
-import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_002;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_003;
@@ -138,7 +136,7 @@ public class SearchProjectsActionIT {
@DataProvider
public static Object[][] software_quality_rating_metric_keys() {
return new Object[][]{{SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY}, {SOFTWARE_QUALITY_RELIABILITY_RATING_KEY},
- {SOFTWARE_QUALITY_SECURITY_RATING_KEY}, {SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY}};
+ {SOFTWARE_QUALITY_SECURITY_RATING_KEY}};
}
@DataProvider
@@ -157,7 +155,7 @@ public class SearchProjectsActionIT {
@DataProvider
public static Object[][] new_software_quality_rating_metric_keys() {
return new Object[][]{{NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY}, {NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY},
- {NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY}, {NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY}};
+ {NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY}};
}
@DataProvider
@@ -248,11 +246,9 @@ public class SearchProjectsActionIT {
"new_software_quality_maintainability_rating",
"new_software_quality_reliability_rating",
"new_software_quality_security_rating",
- "new_software_quality_security_review_rating",
"software_quality_maintainability_rating",
"software_quality_reliability_rating",
- "software_quality_security_rating",
- "software_quality_security_review_rating");
+ "software_quality_security_rating");
Param asc = def.param("asc");
assertThat(asc.defaultValue()).isEqualTo("true");
@@ -272,11 +268,9 @@ public class SearchProjectsActionIT {
"new_software_quality_maintainability_rating",
"new_software_quality_reliability_rating",
"new_software_quality_security_rating",
- "new_software_quality_security_review_rating",
"software_quality_maintainability_rating",
"software_quality_reliability_rating",
- "software_quality_security_rating",
- "software_quality_security_review_rating");
+ "software_quality_security_rating");
}
@Test
@@ -1005,6 +999,8 @@ public class SearchProjectsActionIT {
insertProject(new Measure(ratingMetric, c -> c.setValue(1d)));
insertProject(new Measure(ratingMetric, c -> c.setValue(1d)));
insertProject(new Measure(ratingMetric, c -> c.setValue(3d)));
+ insertProject(new Measure(ratingMetric, c -> c.setValue(5d)));
+ insertProject(new Measure(ratingMetric, c -> c.setValue(5d)));
index();
SearchProjectsWsResponse result = call(request.setFacets(singletonList(ratingMetricKey)));
@@ -1018,7 +1014,8 @@ public class SearchProjectsActionIT {
tuple("1", 2L),
tuple("2", 0L),
tuple("3", 1L),
- tuple("4", 0L));
+ tuple("4", 0L),
+ tuple("5", 2L));
}
@Test
@@ -1068,7 +1065,8 @@ public class SearchProjectsActionIT {
tuple("1", 2L),
tuple("2", 0L),
tuple("3", 1L),
- tuple("4", 0L));
+ tuple("4", 0L),
+ tuple("5", 0L));
}
@Test
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ListActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ListActionIT.java
index 8a581d45c87..0b207e6a128 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ListActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ListActionIT.java
@@ -40,6 +40,7 @@ import org.sonar.db.DbTester;
import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ProjectData;
+import org.sonar.db.issue.ImpactDto;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.metric.MetricDto;
import org.sonar.db.protobuf.DbIssues;
@@ -74,6 +75,7 @@ import static org.sonar.api.issue.Issue.STATUS_CLOSED;
import static org.sonar.api.issue.Issue.STATUS_CONFIRMED;
import static org.sonar.api.issue.Issue.STATUS_OPEN;
import static org.sonar.api.issue.Issue.STATUS_RESOLVED;
+import static org.sonar.api.issue.impact.SoftwareQuality.MAINTAINABILITY;
import static org.sonar.api.measures.CoreMetrics.ANALYSIS_FROM_SONARQUBE_9_4_KEY;
import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.api.utils.DateUtils.parseDate;
@@ -86,6 +88,7 @@ import static org.sonar.db.rule.RuleTesting.XOO_X1;
import static org.sonar.db.rule.RuleTesting.XOO_X2;
import static org.sonar.db.rule.RuleTesting.newRule;
import static org.sonar.server.tester.UserSessionRule.standalone;
+import static org.sonarqube.ws.Common.Impact.newBuilder;
@RunWith(DataProviderRunner.class)
public class ListActionIT {
@@ -196,7 +199,8 @@ public class ListActionIT {
.setMessageFormattings(DbIssues.MessageFormattings.newBuilder().addMessageFormatting(MESSAGE_FORMATTING).build())
.setStatus(STATUS_OPEN)
.setResolution(null)
- .setSeverity("MAJOR")
+ .setSeverity("BLOCKER")
+ .replaceAllImpacts(List.of(new ImpactDto().setSoftwareQuality(MAINTAINABILITY).setSeverity(org.sonar.api.issue.impact.Severity.BLOCKER)))
.setAuthorLogin("John")
.setAssigneeUuid(simon.getUuid())
.setTags(asList("bug", "owasp"))
@@ -217,12 +221,13 @@ public class ListActionIT {
.extracting(
Issue::getKey, Issue::getRule, Issue::getSeverity, Issue::getComponent, Issue::getResolution, Issue::getStatus, Issue::getMessage, Issue::getMessageFormattingsList,
Issue::getEffort, Issue::getAssignee, Issue::getAuthor, Issue::getLine, Issue::getHash, Issue::getTagsList, Issue::getCreationDate, Issue::getUpdateDate,
- Issue::getQuickFixAvailable, Issue::getCodeVariantsList)
+ Issue::getQuickFixAvailable, Issue::getCodeVariantsList, Issue::getImpactsList)
.containsExactlyInAnyOrder(
- tuple(issue.getKey(), rule.getKey().toString(), Severity.MAJOR, file.getKey(), "", STATUS_OPEN, "the message",
+ tuple(issue.getKey(), rule.getKey().toString(), Severity.BLOCKER, file.getKey(), "", STATUS_OPEN, "the message",
MessageFormattingUtils.dbMessageFormattingListToWs(List.of(MESSAGE_FORMATTING)), "10min",
simon.getLogin(), "John", 42, "a227e508d6646b55a086ee11d63b21e9", asList("bug", "owasp"), formatDateTime(issue.getIssueCreationDate()),
- formatDateTime(issue.getIssueUpdateDate()), false, List.of("variant1", "variant2")));
+ formatDateTime(issue.getIssueUpdateDate()), false, List.of("variant1", "variant2"),
+ List.of(newBuilder().setSoftwareQuality(Common.SoftwareQuality.MAINTAINABILITY).setSeverity(Common.ImpactSeverity.ImpactSeverity_BLOCKER).build())));
assertThat(response.getComponentsList())
.extracting(
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/PullTaintActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/PullTaintActionIT.java
index 993d5b9abbf..963d8e8771f 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/PullTaintActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/PullTaintActionIT.java
@@ -28,12 +28,15 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.impact.Severity;
+import org.sonar.api.issue.impact.SoftwareQuality;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ProjectData;
import org.sonar.db.component.ResourceTypesRule;
+import org.sonar.db.issue.ImpactDto;
import org.sonar.db.issue.IssueDbTester;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.project.ProjectDto;
@@ -45,6 +48,7 @@ import org.sonar.db.user.UserDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.issue.ImpactFormatter;
import org.sonar.server.issue.TaintChecker;
import org.sonar.server.issue.ws.pull.PullTaintActionProtobufObjectGenerator;
import org.sonar.server.tester.UserSessionRule;
@@ -233,6 +237,8 @@ public class PullTaintActionIT {
.setManualSeverity(true)
.setMessage("message")
.setMessageFormattings(DbIssues.MessageFormattings.newBuilder().addMessageFormatting(MESSAGE_FORMATTING).build())
+ .replaceAllImpacts(List.of(new ImpactDto().setSoftwareQuality(SoftwareQuality.MAINTAINABILITY).setSeverity(Severity.BLOCKER),
+ new ImpactDto().setSoftwareQuality(SoftwareQuality.RELIABILITY).setSeverity(Severity.HIGH)))
.setIssueCreationTime(NOW)
.setStatus(Issue.STATUS_OPEN)
.setLocations(mainLocation.build())
@@ -265,7 +271,7 @@ public class PullTaintActionIT {
.containsExactlyInAnyOrderElementsOf(issueDto.getEffectiveImpacts()
.entrySet()
.stream()
- .map(entry -> tuple(Common.SoftwareQuality.valueOf(entry.getKey().name()), Common.ImpactSeverity.valueOf(entry.getValue().name())))
+ .map(entry -> tuple(Common.SoftwareQuality.valueOf(entry.getKey().name()), ImpactFormatter.mapImpactSeverity(entry.getValue())))
.collect(toList()));
Issues.Location location = taintLite.getMainLocation();
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java
index 516107ac4c8..4f45dd7f188 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java
@@ -164,18 +164,22 @@ public class SearchActionIT {
private final DbClient dbClient = db.getDbClient();
private final DbSession session = db.getSession();
- private final IssueIndex issueIndex = new IssueIndex(es.client(), System2.INSTANCE, userSession, new WebAuthorizationTypeSupport(userSession));
+ private final IssueIndex issueIndex = new IssueIndex(es.client(), System2.INSTANCE, userSession,
+ new WebAuthorizationTypeSupport(userSession));
private final IssueIndexer issueIndexer = new IssueIndexer(es.client(), dbClient, new IssueIteratorFactory(dbClient), null);
private final IssueQueryFactory issueQueryFactory = new IssueQueryFactory(dbClient, Clock.systemUTC(), userSession);
private final IssueFieldsSetter issueFieldsSetter = new IssueFieldsSetter();
private final IssueWorkflow issueWorkflow = new IssueWorkflow(new FunctionExecutor(issueFieldsSetter), issueFieldsSetter);
- private final SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSession, dbClient, new TransitionService(userSession, issueWorkflow));
+ private final SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSession, dbClient,
+ new TransitionService(userSession, issueWorkflow));
private final Languages languages = new Languages();
private final UserResponseFormatter userFormatter = new UserResponseFormatter(new AvatarResolverImpl());
- private final SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), languages, new TextRangeResponseFormatter(), userFormatter);
+ private final SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), languages,
+ new TextRangeResponseFormatter(), userFormatter);
private final IssueIndexSyncProgressChecker issueIndexSyncProgressChecker = new IssueIndexSyncProgressChecker(dbClient);
private final WsActionTester ws = new WsActionTester(
- new SearchAction(userSession, issueIndex, issueQueryFactory, issueIndexSyncProgressChecker, searchResponseLoader, searchResponseFormat, System2.INSTANCE, dbClient));
+ new SearchAction(userSession, issueIndex, issueQueryFactory, issueIndexSyncProgressChecker, searchResponseLoader,
+ searchResponseFormat, System2.INSTANCE, dbClient));
private final PermissionIndexer permissionIndexer = new PermissionIndexer(dbClient, es.client(), issueIndexer);
@Before
@@ -218,13 +222,16 @@ public class SearchActionIT {
assertThat(response.getIssuesList())
.extracting(
- Issue::getKey, Issue::getRule, Issue::getSeverity, Issue::getComponent, Issue::getResolution, Issue::getStatus, Issue::getMessage, Issue::getMessageFormattingsList,
- Issue::getEffort, Issue::getAssignee, Issue::getAuthor, Issue::getLine, Issue::getHash, Issue::getTagsList, Issue::getCreationDate, Issue::getUpdateDate,
+ Issue::getKey, Issue::getRule, Issue::getSeverity, Issue::getComponent, Issue::getResolution, Issue::getStatus, Issue::getMessage
+ , Issue::getMessageFormattingsList,
+ Issue::getEffort, Issue::getAssignee, Issue::getAuthor, Issue::getLine, Issue::getHash, Issue::getTagsList,
+ Issue::getCreationDate, Issue::getUpdateDate,
Issue::getQuickFixAvailable, Issue::getCodeVariantsList)
.containsExactlyInAnyOrder(
tuple(issue.getKey(), rule.getKey().toString(), Severity.MAJOR, file.getKey(), RESOLUTION_FIXED, STATUS_RESOLVED, "the message",
MessageFormattingUtils.dbMessageFormattingListToWs(List.of(MESSAGE_FORMATTING)), "10min",
- simon.getLogin(), "John", 42, "a227e508d6646b55a086ee11d63b21e9", asList("bug", "owasp"), formatDateTime(issue.getIssueCreationDate()),
+ simon.getLogin(), "John", 42, "a227e508d6646b55a086ee11d63b21e9", asList("bug", "owasp"),
+ formatDateTime(issue.getIssueCreationDate()),
formatDateTime(issue.getIssueUpdateDate()), false, List.of("variant1", "variant2")));
}
@@ -250,7 +257,7 @@ public class SearchActionIT {
.get(0)
.getActions()
.getActionsList())
- .isEqualTo(asList(ACTION_SET_TAGS, COMMENT_KEY, ACTION_ASSIGN));
+ .isEqualTo(asList(ACTION_SET_TAGS, COMMENT_KEY, ACTION_ASSIGN));
response = ws.newRequest()
.setParam(PARAM_ADDITIONAL_FIELDS, "actions")
@@ -263,7 +270,7 @@ public class SearchActionIT {
.get(0)
.getActions()
.getActionsList())
- .isEqualTo(asList(ACTION_SET_TAGS, COMMENT_KEY));
+ .isEqualTo(asList(ACTION_SET_TAGS, COMMENT_KEY));
}
@Test
@@ -380,7 +387,8 @@ public class SearchActionIT {
SearchWsResponse result = ws.newRequest().executeProtobuf(SearchWsResponse.class);
assertThat(result.getIssuesCount()).isOne();
- assertThat(result.getIssues(0).getFlows(0).getLocationsList()).extracting(Common.Location::getComponent, Common.Location::getMsg, Common.Location::getMsgFormattingsList)
+ assertThat(result.getIssues(0).getFlows(0).getLocationsList()).extracting(Common.Location::getComponent, Common.Location::getMsg,
+ Common.Location::getMsgFormattingsList)
.containsExactlyInAnyOrder(
tuple(file.getKey(), "FLOW MESSAGE", List.of()),
tuple(anotherFile.getKey(), "ANOTHER FLOW MESSAGE", List.of(Common.MessageFormatting.newBuilder()
@@ -503,7 +511,8 @@ public class SearchActionIT {
c -> c.setKey("PROJECT_KEY").setName("NAME_PROJECT_ID").setLongName("LONG_NAME_PROJECT_ID").setLanguage("java"));
grantPermissionToAnyone(project.getProjectDto(), ISSUE_ADMIN);
indexPermissions();
- ComponentDto file = db.components().insertComponent(newFileDto(project.getMainBranchComponent(), null, "FILE_ID").setKey("FILE_KEY").setLanguage("js"));
+ ComponentDto file =
+ db.components().insertComponent(newFileDto(project.getMainBranchComponent(), null, "FILE_ID").setKey("FILE_KEY").setLanguage("js"));
IssueDto issue = newIssue(newIssueRule(), project.getMainBranchComponent(), file)
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
@@ -613,7 +622,8 @@ public class SearchActionIT {
c -> c.setKey("PROJECT_KEY").setName("NAME_PROJECT_ID").setLongName("LONG_NAME_PROJECT_ID").setLanguage("java")).getMainBranchComponent();
ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY").setLanguage("java"));
db.issues().insertIssue(rule, project, file, i -> i.setStatus(STATUS_OPEN));
- IssueDto expectedIssue = db.issues().insertIssue(rule, project, file, i -> i.setStatus(STATUS_RESOLVED).setResolution(RESOLUTION_WONT_FIX));
+ IssueDto expectedIssue = db.issues().insertIssue(rule, project, file,
+ i -> i.setStatus(STATUS_RESOLVED).setResolution(RESOLUTION_WONT_FIX));
db.issues().insertIssue(rule, project, file, i -> i.setStatus(STATUS_RESOLVED).setResolution(RESOLUTION_FALSE_POSITIVE));
db.issues().insertIssue(rule, project, file, i -> i.setStatus(STATUS_RESOLVED).setResolution(RESOLUTION_FIXED));
db.issues().insertIssue(rule, project, file, i -> i.setStatus(STATUS_CLOSED).setResolution(RESOLUTION_WONT_FIX));
@@ -728,14 +738,15 @@ public class SearchActionIT {
.addImpact(new ImpactDto().setSoftwareQuality(SoftwareQuality.RELIABILITY).setSeverity(org.sonar.api.issue.impact.Severity.HIGH)));
IssueDto issue3 = db.issues().insertIssue(rule, project, file, i -> i
.addImpact(new ImpactDto().setSoftwareQuality(SoftwareQuality.SECURITY).setSeverity(org.sonar.api.issue.impact.Severity.MEDIUM))
- .addImpact(new ImpactDto().setSoftwareQuality(SoftwareQuality.RELIABILITY).setSeverity(org.sonar.api.issue.impact.Severity.LOW)));
+ .addImpact(new ImpactDto().setSoftwareQuality(SoftwareQuality.RELIABILITY).setSeverity(org.sonar.api.issue.impact.Severity.INFO)));
indexPermissionsAndIssues();
- Map<Common.SoftwareQuality, Common.ImpactSeverity> expectedImpacts = Map.of(Common.SoftwareQuality.SECURITY, Common.ImpactSeverity.MEDIUM,
- Common.SoftwareQuality.RELIABILITY, Common.ImpactSeverity.LOW,
+ Map<Common.SoftwareQuality, Common.ImpactSeverity> expectedImpacts = Map.of(Common.SoftwareQuality.SECURITY,
+ Common.ImpactSeverity.MEDIUM,
+ Common.SoftwareQuality.RELIABILITY, Common.ImpactSeverity.ImpactSeverity_INFO,
Common.SoftwareQuality.MAINTAINABILITY, Common.ImpactSeverity.HIGH);
SearchWsResponse response = ws.newRequest()
- .setParam(PARAM_IMPACT_SEVERITIES, org.sonar.api.issue.impact.Severity.LOW.name())
+ .setParam(PARAM_IMPACT_SEVERITIES, org.sonar.api.issue.impact.Severity.INFO.name())
.setParam(FACETS, PARAM_IMPACT_SOFTWARE_QUALITIES)
.executeProtobuf(SearchWsResponse.class);
@@ -777,6 +788,9 @@ public class SearchActionIT {
new ImpactDto(SoftwareQuality.MAINTAINABILITY, org.sonar.api.issue.impact.Severity.LOW),
new ImpactDto(SoftwareQuality.SECURITY, org.sonar.api.issue.impact.Severity.MEDIUM),
new ImpactDto(SoftwareQuality.RELIABILITY, org.sonar.api.issue.impact.Severity.LOW))));
+ IssueDto issue4 = db.issues().insertIssue(rule, project, file, i -> i.replaceAllImpacts(List.of(
+ new ImpactDto(SoftwareQuality.MAINTAINABILITY, org.sonar.api.issue.impact.Severity.INFO),
+ new ImpactDto(SoftwareQuality.SECURITY, org.sonar.api.issue.impact.Severity.BLOCKER))));
indexPermissionsAndIssues();
SearchWsResponse response = ws.newRequest()
@@ -785,7 +799,7 @@ public class SearchActionIT {
assertThat(response.getIssuesList())
.extracting(Issue::getKey)
- .containsExactlyInAnyOrder(issue1.getKey(), issue2.getKey(), issue3.getKey());
+ .containsExactlyInAnyOrder(issue1.getKey(), issue2.getKey(), issue3.getKey(), issue4.getKey());
Optional<Common.Facet> first = response.getFacets().getFacetsList()
.stream().filter(facet -> facet.getProperty().equals(PARAM_IMPACT_SEVERITIES))
@@ -793,9 +807,11 @@ public class SearchActionIT {
assertThat(first.get().getValuesList())
.extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
.containsExactlyInAnyOrder(
+ tuple("BLOCKER", 1L),
tuple("HIGH", 2L),
tuple("MEDIUM", 1L),
- tuple("LOW", 1L));
+ tuple("LOW", 1L),
+ tuple("INFO", 1L));
}
@Test
@@ -809,7 +825,13 @@ public class SearchActionIT {
new ImpactDto(SoftwareQuality.RELIABILITY, org.sonar.api.issue.impact.Severity.HIGH))));
db.issues().insertIssue(rule, project, file, i -> i.replaceAllImpacts(List.of(
new ImpactDto(SoftwareQuality.RELIABILITY, org.sonar.api.issue.impact.Severity.HIGH))));
+ IssueDto issue2 = db.issues().insertIssue(rule, project, file, i -> i.replaceAllImpacts(List.of(
+ new ImpactDto(SoftwareQuality.SECURITY, org.sonar.api.issue.impact.Severity.BLOCKER))));
IssueDto issue3 = db.issues().insertIssue(rule, project, file, i -> i.replaceAllImpacts(List.of(
+ new ImpactDto(SoftwareQuality.SECURITY, org.sonar.api.issue.impact.Severity.BLOCKER))));
+ IssueDto issue4 = db.issues().insertIssue(rule, project, file, i -> i.replaceAllImpacts(List.of(
+ new ImpactDto(SoftwareQuality.SECURITY, org.sonar.api.issue.impact.Severity.INFO))));
+ IssueDto issue5 = db.issues().insertIssue(rule, project, file, i -> i.replaceAllImpacts(List.of(
new ImpactDto(SoftwareQuality.MAINTAINABILITY, org.sonar.api.issue.impact.Severity.LOW),
new ImpactDto(SoftwareQuality.SECURITY, org.sonar.api.issue.impact.Severity.MEDIUM),
new ImpactDto(SoftwareQuality.RELIABILITY, org.sonar.api.issue.impact.Severity.LOW))));
@@ -822,7 +844,7 @@ public class SearchActionIT {
assertThat(response.getIssuesList())
.extracting(Issue::getKey)
- .containsExactlyInAnyOrder(issue1.getKey(), issue3.getKey());
+ .containsExactlyInAnyOrder(issue1.getKey(), issue2.getKey(), issue3.getKey(), issue4.getKey(), issue5.getKey());
Optional<Common.Facet> first = response.getFacets().getFacetsList()
.stream().filter(facet -> facet.getProperty().equals(PARAM_IMPACT_SEVERITIES))
@@ -832,7 +854,9 @@ public class SearchActionIT {
.containsExactlyInAnyOrder(
tuple("HIGH", 1L),
tuple("MEDIUM", 1L),
- tuple("LOW", 0L));
+ tuple("LOW", 0L),
+ tuple("INFO", 1L),
+ tuple("BLOCKER", 2L));
}
@Test
@@ -878,7 +902,8 @@ public class SearchActionIT {
@Test
public void issue_on_removed_file() {
RuleDto rule = newIssueRule();
- ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY").setKey("PROJECT_KEY")).getMainBranchComponent();
+ ComponentDto project =
+ db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY").setKey("PROJECT_KEY")).getMainBranchComponent();
indexPermissions();
ComponentDto removedFile = db.components().insertComponent(newFileDto(project).setUuid("REMOVED_FILE_ID")
.setKey("REMOVED_FILE_KEY")
@@ -903,7 +928,8 @@ public class SearchActionIT {
@Test
public void apply_paging_with_one_component() {
RuleDto rule = newIssueRule();
- ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY").setKey("PROJECT_KEY")).getMainBranchComponent();
+ ComponentDto project =
+ db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY").setKey("PROJECT_KEY")).getMainBranchComponent();
indexPermissions();
ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY"));
for (int i = 0; i < SearchOptions.MAX_PAGE_SIZE + 1; i++) {
@@ -921,7 +947,8 @@ public class SearchActionIT {
public void filter_by_assigned_to_me() {
UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
- ComponentDto project = db.components().insertPublicProject(c -> c.setUuid("PROJECT_ID").setKey("PROJECT_KEY").setBranchUuid("PROJECT_ID")).getMainBranchComponent();
+ ComponentDto project = db.components().insertPublicProject(c -> c.setUuid("PROJECT_ID").setKey("PROJECT_KEY").setBranchUuid(
+ "PROJECT_ID")).getMainBranchComponent();
indexPermissions();
ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY"));
RuleDto rule = newIssueRule();
@@ -969,7 +996,7 @@ public class SearchActionIT {
UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
ComponentDto project = db.components().insertPublicProject("PROJECT_ID",
c -> c.setKey("PROJECT_KEY").setName("NAME_PROJECT_ID").setLongName("LONG_NAME_PROJECT_ID")).getMainBranchComponent();
- SnapshotDto snapshotDto = db.components().insertSnapshot(project, s -> s.setLast(true).setPeriodDate(parseDateTime("2014-09-05T00:00:00+0100").getTime()));
+ db.components().insertSnapshot(project, s -> s.setLast(true).setPeriodDate(parseDateTime("2014-09-05T00:00:00+0100").getTime()));
indexPermissions();
ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY"));
@@ -1213,7 +1240,7 @@ public class SearchActionIT {
assertThat(ws.newRequest()
.setMultiParam("author", singletonList("unknown"))
.executeProtobuf(SearchWsResponse.class).getIssuesList())
- .isEmpty();
+ .isEmpty();
}
@Test
@@ -1362,7 +1389,8 @@ public class SearchActionIT {
assertThat(parse.getAsJsonObject().get("issues").getAsJsonArray())
.extracting(o -> o.getAsJsonObject().get("key").getAsString())
- .containsExactly("82fd47d4-b650-4037-80bc-7b112bd4eac3", "82fd47d4-b650-4037-80bc-7b112bd4eac1", "82fd47d4-b650-4037-80bc-7b112bd4eac2");
+ .containsExactly("82fd47d4-b650-4037-80bc-7b112bd4eac3", "82fd47d4-b650-4037-80bc-7b112bd4eac1", "82fd47d4-b650-4037-80bc" +
+ "-7b112bd4eac2");
}
@Test
@@ -1372,12 +1400,15 @@ public class SearchActionIT {
Consumer<RuleDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
.setSecurityStandards(Sets.newHashSet("cwe:20", "owaspTop10:a1", "pciDss-3.2:6.5.3", "owaspAsvs-4.0:12.3.1"))
.setSystemTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
- Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25" +
+ "-insecure", "sql"));
RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
indexPermissionsAndIssues();
@@ -1402,13 +1433,15 @@ public class SearchActionIT {
public void only_vulnerabilities_are_returned_by_owaspAsvs40_with_level() {
ComponentDto project = db.components().insertPublicProject().getMainBranchComponent();
ComponentDto file = db.components().insertComponent(newFileDto(project));
- Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25" +
+ "-insecure", "sql"));
RuleDto issueRule1 = db.rules().insertIssueRule(r -> r.setSecurityStandards(Set.of("owaspAsvs-4.0:1.7.2", "owaspAsvs-4.0:12.3.1")));
RuleDto issueRule2 = db.rules().insertIssueRule(r -> r.setSecurityStandards(Set.of("owaspAsvs-4.0:2.2.5")));
RuleDto issueRule3 = db.rules().insertIssueRule(r -> r.setSecurityStandards(Set.of("owaspAsvs-4.0:2.2.5", "owaspAsvs-4.0:12.1.3")));
- IssueDto issueDto1 = db.issues().insertIssue(issueRule1, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto2 = db.issues().insertIssue(issueRule2, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto3 = db.issues().insertIssue(issueRule3, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule1, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto3 = db.issues().insertIssue(issueRule3, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
indexPermissionsAndIssues();
SearchWsResponse result = ws.newRequest()
@@ -1453,12 +1486,15 @@ public class SearchActionIT {
Consumer<RuleDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
.setSecurityStandards(Sets.newHashSet("cwe:20", "owaspTop10:a1", "pciDss-3.2:6.5.3", "pciDss-3.2:10.1"))
.setSystemTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
- Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25" +
+ "-insecure", "sql"));
RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
indexPermissionsAndIssues();
@@ -1488,12 +1524,15 @@ public class SearchActionIT {
Consumer<RuleDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
.setSecurityStandards(Sets.newHashSet("cwe:20", "owaspTop10:a1", "pciDss-3.2:6.5.3", "pciDss-3.2:10.1"))
.setSystemTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
- Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25" +
+ "-insecure", "sql"));
RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
// Rule 2
ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
@@ -1503,8 +1542,10 @@ public class SearchActionIT {
hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto4 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto4 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
// Rule 3
ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
@@ -1514,8 +1555,10 @@ public class SearchActionIT {
hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto5 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto6 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto5 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto6 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
indexPermissionsAndIssues();
@@ -1525,7 +1568,8 @@ public class SearchActionIT {
assertThat(result.getIssuesList())
.extracting(Issue::getKey)
- .containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey(), issueDto3.getKey(), issueDto4.getKey(), issueDto5.getKey(), issueDto6.getKey());
+ .containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey(), issueDto3.getKey(), issueDto4.getKey(), issueDto5.getKey(),
+ issueDto6.getKey());
result = ws.newRequest()
.setParam("pciDss-3.2", "1")
@@ -1541,7 +1585,8 @@ public class SearchActionIT {
assertThat(result.getIssuesList())
.extracting(Issue::getKey)
- .containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey(), issueDto3.getKey(), issueDto4.getKey(), issueDto5.getKey(), issueDto6.getKey());
+ .containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey(), issueDto3.getKey(), issueDto4.getKey(), issueDto5.getKey(),
+ issueDto6.getKey());
result = ws.newRequest()
.setParam("pciDss-3.2", "4")
@@ -1571,12 +1616,15 @@ public class SearchActionIT {
Consumer<RuleDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
.setSecurityStandards(Sets.newHashSet("cwe:20", "owaspTop10:a1", "pciDss-4.0:6.5.3", "pciDss-4.0:10.1"))
.setSystemTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
- Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25" +
+ "-insecure", "sql"));
RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
indexPermissionsAndIssues();
@@ -1606,12 +1654,15 @@ public class SearchActionIT {
Consumer<RuleDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
.setSecurityStandards(Sets.newHashSet("cwe:20", "owaspTop10:a1", "pciDss-4.0:6.5.3", "pciDss-4.0:10.1"))
.setSystemTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
- Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25" +
+ "-insecure", "sql"));
RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
// Rule 2
ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
@@ -1621,8 +1672,10 @@ public class SearchActionIT {
hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto4 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto4 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
// Rule 3
ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
@@ -1632,8 +1685,8 @@ public class SearchActionIT {
hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto5 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto6 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
indexPermissionsAndIssues();
@@ -1681,12 +1734,15 @@ public class SearchActionIT {
Consumer<RuleDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
.setSecurityStandards(Sets.newHashSet("cwe:20", "cwe:564", "cwe:89", "cwe:943", "owaspTop10:a1"))
.setSystemTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
- Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25" +
+ "-insecure", "sql"));
RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
indexPermissionsAndIssues();
@@ -1706,12 +1762,15 @@ public class SearchActionIT {
Consumer<RuleDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
.setSecurityStandards(Sets.newHashSet("cwe:20", "cwe:564", "cwe:89", "cwe:943", "owaspTop10:a1", "owaspTop10-2021:a2"))
.setSystemTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
- Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25" +
+ "-insecure", "sql"));
RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
indexPermissionsAndIssues();
@@ -1731,12 +1790,15 @@ public class SearchActionIT {
Consumer<RuleDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
.setSecurityStandards(Sets.newHashSet("cwe:20", "cwe:564", "cwe:89", "cwe:943", "owaspTop10:a1", "owaspTop10-2021:a2"))
.setSystemTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
- Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25" +
+ "-insecure", "sql"));
RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
indexPermissionsAndIssues();
@@ -1754,14 +1816,18 @@ public class SearchActionIT {
ComponentDto project = db.components().insertPublicProject().getMainBranchComponent();
ComponentDto file = db.components().insertComponent(newFileDto(project));
Consumer<RuleDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
- .setSecurityStandards(Sets.newHashSet("cwe:20", "cwe:564", "stig-ASD_V5R3:V-222402", "stig-ASD_V5R3:V-222403", "stig-ASD_V5R3:V-222404", "ostig-ASD_V5R3:V-222405"))
+ .setSecurityStandards(Sets.newHashSet("cwe:20", "cwe:564", "stig-ASD_V5R3:V-222402", "stig-ASD_V5R3:V-222403", "stig-ASD_V5R3:V" +
+ "-222404", "ostig-ASD_V5R3:V-222405"))
.setSystemTags(Sets.newHashSet("bad-practice", "cwe", "stig", "sans-top25-insecure", "sql"));
- Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "stig", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "stig", "sans-top25-insecure",
+ "sql"));
RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
indexPermissionsAndIssues();
@@ -1790,8 +1856,10 @@ public class SearchActionIT {
RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
indexPermissionsAndIssues();
@@ -1830,8 +1898,10 @@ public class SearchActionIT {
RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
indexPermissionsAndIssues();
@@ -1855,8 +1925,10 @@ public class SearchActionIT {
RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
indexPermissionsAndIssues();
@@ -1900,7 +1972,8 @@ public class SearchActionIT {
indexPermissionsAndIssues();
SearchWsResponse result = ws.newRequest()
- .setParam("issues", Stream.of(bugIssue, vulnerabilityIssue, codeSmellIssue, hotspot).map(IssueDto::getKey).collect(Collectors.joining(",")))
+ .setParam("issues",
+ Stream.of(bugIssue, vulnerabilityIssue, codeSmellIssue, hotspot).map(IssueDto::getKey).collect(Collectors.joining(",")))
.executeProtobuf(SearchWsResponse.class);
assertThat(result.getIssuesList())
@@ -1915,12 +1988,15 @@ public class SearchActionIT {
Consumer<RuleDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
.setSecurityStandards(Sets.newHashSet("cwe:20", "cwe:564", "cwe:89", "cwe:943", "owaspTop10:a1"))
.setSystemTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
- Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25" +
+ "-insecure", "sql"));
RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
- IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer,
+ issueDto -> issueDto.setType(RuleType.VULNERABILITY));
indexPermissions();
indexIssues();
@@ -2014,8 +2090,10 @@ public class SearchActionIT {
ComponentDto file = db.components().insertComponent(newFileDto(project));
RuleDto issueRule = db.rules().insertIssueRule();
IssueDto bugIssue = db.issues().insertIssue(issueRule, project, file, i -> i.setType(RuleType.BUG).setSeverity(Severity.MAJOR.name()));
- IssueDto vulnerabilityIssue = db.issues().insertIssue(issueRule, project, file, i -> i.setType(RuleType.VULNERABILITY).setSeverity(Severity.MAJOR.name()));
- IssueDto codeSmellIssue = db.issues().insertIssue(issueRule, project, file, i -> i.setType(CODE_SMELL).setSeverity(Severity.MAJOR.name()));
+ IssueDto vulnerabilityIssue = db.issues().insertIssue(issueRule, project, file,
+ i -> i.setType(RuleType.VULNERABILITY).setSeverity(Severity.MAJOR.name()));
+ IssueDto codeSmellIssue = db.issues().insertIssue(issueRule, project, file,
+ i -> i.setType(CODE_SMELL).setSeverity(Severity.MAJOR.name()));
RuleDto hotspotRule = db.rules().insertHotspotRule();
db.issues().insertHotspot(hotspotRule, project, file, i -> i.setSeverity(Severity.MAJOR.name()));
indexPermissions();
@@ -2152,8 +2230,10 @@ public class SearchActionIT {
assertThat(def.params()).extracting("key").containsExactlyInAnyOrder(
"additionalFields", "asc", "assigned", "assignees", "author", "components", "branch", "pullRequest", "createdAfter", "createdAt",
"createdBefore", "createdInLast", "directories", "facets", "files", "issues", "scopes", "languages", "onComponentOnly",
- "p", "projects", "ps", "resolutions", "resolved", "rules", "s", "severities", "statuses", "tags", "types", "pciDss-3.2", "pciDss-4.0", "owaspAsvs-4.0",
- "owaspAsvsLevel", "owaspTop10", "owaspTop10-2021", "stig-ASD_V5R3", "casa", "sansTop25", "cwe", "sonarsourceSecurity", "timeZone", "inNewCodePeriod", "codeVariants",
+ "p", "projects", "ps", "resolutions", "resolved", "rules", "s", "severities", "statuses", "tags", "types", "pciDss-3.2", "pciDss-4" +
+ ".0", "owaspAsvs-4.0",
+ "owaspAsvsLevel", "owaspTop10", "owaspTop10-2021", "stig-ASD_V5R3", "casa", "sansTop25", "cwe", "sonarsourceSecurity", "timeZone",
+ "inNewCodePeriod", "codeVariants",
"cleanCodeAttributeCategories", "impactSeverities", "impactSoftwareQualities", "issueStatuses", "fixedInPullRequest",
"prioritizedRule");
@@ -2163,8 +2243,10 @@ public class SearchActionIT {
assertThat(branch.since()).isEqualTo("6.6");
WebService.Param projectUuids = def.param("projects");
- assertThat(projectUuids.description()).isEqualTo("To retrieve issues associated to a specific list of projects (comma-separated list of project keys). " +
- "This parameter is mostly used by the Issues page, please prefer usage of the componentKeys parameter. If this parameter is set, projectUuids must not be set.");
+ assertThat(projectUuids.description()).isEqualTo("To retrieve issues associated to a specific list of projects (comma-separated list " +
+ "of project keys). " +
+ "This parameter is mostly used by the Issues page, please prefer usage of the componentKeys parameter. If this parameter is set, " +
+ "projectUuids must not be set.");
}
@Test
@@ -2391,9 +2473,9 @@ public class SearchActionIT {
private RuleDto newIssueRule(String ruleKey, Consumer<RuleDto> consumer) {
RuleDto rule = newRule(RuleKey.of("xoo", ruleKey),
createDefaultRuleDescriptionSection(uuidFactory.create(), "Rule desc"))
- .setLanguage("xoo")
- .setName("Rule name")
- .setStatus(RuleStatus.READY);
+ .setLanguage("xoo")
+ .setName("Rule name")
+ .setStatus(RuleStatus.READY);
consumer.accept(rule);
db.rules().insert(rule);
return rule;
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/CreateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/CreateActionIT.java
index 0575fd65d47..ebb4b714130 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/CreateActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/CreateActionIT.java
@@ -31,12 +31,12 @@ import org.sonar.core.util.SequenceUuidFactory;
import org.sonar.core.util.UuidFactory;
import org.sonar.db.DbTester;
import org.sonar.db.rule.RuleDto;
+import org.sonar.server.common.rule.RuleCreator;
import org.sonar.server.common.rule.service.RuleService;
import org.sonar.server.common.text.MacroInterpreter;
import org.sonar.server.es.EsTester;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
-import org.sonar.server.common.rule.RuleCreator;
import org.sonar.server.rule.RuleDescriptionFormatter;
import org.sonar.server.rule.index.RuleIndexer;
import org.sonar.server.tester.UserSessionRule;
@@ -166,7 +166,7 @@ public class CreateActionIT {
.setParam("markdownDescription", "Description")
.setParam("status", "BETA")
.setParam("cleanCodeAttribute", "MODULAR")
- .setParam("impacts", "RELIABILITY=HIGH;SECURITY=LOW")
+ .setParam("impacts", "RELIABILITY=BLOCKER;SECURITY=INFO")
.execute().getInput();
String expectedResult = """
@@ -176,7 +176,7 @@ public class CreateActionIT {
"repo": "java",
"name": "My custom rule",
"htmlDesc": "Description",
- "severity": "MINOR",
+ "severity": "INFO",
"status": "BETA",
"type": "VULNERABILITY",
"internalKey": "configKey_S001",
@@ -188,11 +188,11 @@ public class CreateActionIT {
"impacts": [
{
"softwareQuality": "RELIABILITY",
- "severity": "HIGH"
+ "severity": "BLOCKER"
},
{
"softwareQuality": "SECURITY",
- "severity": "LOW"
+ "severity": "INFO"
}
]
}
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/SearchActionIT.java
index cb8219e5d2e..768a7225065 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/SearchActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/SearchActionIT.java
@@ -499,7 +499,8 @@ public class SearchActionIT {
db.rules().insert(
r -> r.replaceAllDefaultImpacts(List.of(new ImpactDto().setSoftwareQuality(SoftwareQuality.MAINTAINABILITY).setSeverity(Severity.HIGH))));
db.rules().insert(
- r -> r.replaceAllDefaultImpacts(List.of(new ImpactDto().setSoftwareQuality(SoftwareQuality.RELIABILITY).setSeverity(Severity.MEDIUM))));
+ r -> r.replaceAllDefaultImpacts(List.of(new ImpactDto().setSoftwareQuality(SoftwareQuality.RELIABILITY).setSeverity(Severity.MEDIUM),
+ new ImpactDto().setSoftwareQuality(SoftwareQuality.MAINTAINABILITY).setSeverity(Severity.INFO))));
indexRules();
SearchResponse result = ws.newRequest()
@@ -507,7 +508,7 @@ public class SearchActionIT {
.setParam("impactSoftwareQualities", SoftwareQuality.MAINTAINABILITY.name())
.executeProtobuf(SearchResponse.class);
assertThat(result.getFacets().getFacets(0).getValuesList()).extracting(v -> entry(v.getVal(), v.getCount()))
- .contains(entry(Severity.HIGH.name(), 1L), entry(Severity.MEDIUM.name(), 0L), entry(Severity.LOW.name(), 0L));
+ .contains(entry(Severity.HIGH.name(), 1L), entry(Severity.MEDIUM.name(), 0L), entry(Severity.LOW.name(), 0L), entry(Severity.INFO.name(), 1L));
}
@Test
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ImpactFormatter.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ImpactFormatter.java
new file mode 100644
index 00000000000..3d018120b07
--- /dev/null
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ImpactFormatter.java
@@ -0,0 +1,38 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.issue;
+
+import org.sonar.api.issue.impact.Severity;
+import org.sonarqube.ws.Common;
+
+public class ImpactFormatter {
+ private ImpactFormatter() {
+ }
+
+ public static Common.ImpactSeverity mapImpactSeverity(Severity severity) {
+ return switch (severity) {
+ case BLOCKER -> Common.ImpactSeverity.ImpactSeverity_BLOCKER;
+ case HIGH -> Common.ImpactSeverity.HIGH;
+ case MEDIUM -> Common.ImpactSeverity.MEDIUM;
+ case LOW -> Common.ImpactSeverity.LOW;
+ case INFO -> Common.ImpactSeverity.ImpactSeverity_INFO;
+ };
+ }
+}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseFormat.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseFormat.java
index e309eed6fae..49e9e0a6cb0 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseFormat.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseFormat.java
@@ -49,6 +49,7 @@ import org.sonar.db.rule.RuleDto;
import org.sonar.db.user.UserDto;
import org.sonar.markdown.Markdown;
import org.sonar.server.es.Facets;
+import org.sonar.server.issue.ImpactFormatter;
import org.sonar.server.issue.TextRangeResponseFormatter;
import org.sonar.server.issue.index.IssueScope;
import org.sonar.server.issue.workflow.Transition;
@@ -184,7 +185,7 @@ public class SearchResponseFormat {
.stream()
.map(entry -> Common.Impact.newBuilder()
.setSoftwareQuality(Common.SoftwareQuality.valueOf(entry.getKey().name()))
- .setSeverity(Common.ImpactSeverity.valueOf(entry.getValue().name()))
+ .setSeverity(ImpactFormatter.mapImpactSeverity(entry.getValue()))
.build())
.toList());
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/pull/PullTaintActionProtobufObjectGenerator.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/pull/PullTaintActionProtobufObjectGenerator.java
index 18850ad9883..a31082b6693 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/pull/PullTaintActionProtobufObjectGenerator.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/pull/PullTaintActionProtobufObjectGenerator.java
@@ -34,6 +34,7 @@ import org.sonar.db.component.ComponentDto;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.protobuf.DbIssues;
import org.sonar.db.rule.RuleDto;
+import org.sonar.server.issue.ImpactFormatter;
import org.sonar.server.user.UserSession;
import org.sonar.server.ws.MessageFormattingUtils;
import org.sonarqube.ws.Common;
@@ -108,7 +109,7 @@ public class PullTaintActionProtobufObjectGenerator implements ProtobufObjectGen
taintBuilder.addAllImpacts(issueDto.getEffectiveImpacts().entrySet()
.stream().map(entry -> Common.Impact.newBuilder()
.setSoftwareQuality(Common.SoftwareQuality.valueOf(entry.getKey().name()))
- .setSeverity(Common.ImpactSeverity.valueOf(entry.getValue().name()))
+ .setSeverity(ImpactFormatter.mapImpactSeverity(entry.getValue()))
.build())
.toList());
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java
index 3f5871bd5fd..b857f21915d 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java
@@ -50,7 +50,6 @@ import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALIT
import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT;
-import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT;
@@ -58,11 +57,9 @@ import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RE
import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING;
import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT;
-import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING;
import static org.sonar.server.measure.Rating.RATING_BY_SEVERITY;
import static org.sonar.server.measure.Rating.RATING_BY_SOFTWARE_QUALITY_SEVERITY;
import static org.sonar.server.metric.IssueCountMetrics.PRIORITIZED_RULE_ISSUES;
-import static org.sonar.server.security.SecurityReviewRating.computeAToDRating;
import static org.sonar.server.security.SecurityReviewRating.computePercent;
import static org.sonar.server.security.SecurityReviewRating.computeRating;
@@ -311,13 +308,13 @@ public class MeasureUpdateFormulaFactoryImpl implements MeasureUpdateFormulaFact
asList(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, CoreMetrics.NEW_DEVELOPMENT_COST)),
new MeasureUpdateFormula(SOFTWARE_QUALITY_MAINTAINABILITY_RATING, false, true,
- (context, issues) -> context.setValue(context.getDebtRatingGrid().getAToDRatingForDensity(debtDensity(SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, context))),
- (context, issues) -> context.setValue(context.getDebtRatingGrid().getAToDRatingForDensity(debtDensity(SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, context))),
+ (context, issues) -> context.setValue(context.getDebtRatingGrid().getRatingForDensity(debtDensity(SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, context))),
+ (context, issues) -> context.setValue(context.getDebtRatingGrid().getRatingForDensity(debtDensity(SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, context))),
asList(SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, CoreMetrics.DEVELOPMENT_COST)),
new MeasureUpdateFormula(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING, true, true,
- (context, formula) -> context.setValue(context.getDebtRatingGrid().getAToDRatingForDensity(newDebtDensity(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, context))),
- (context, issues) -> context.setValue(context.getDebtRatingGrid().getAToDRatingForDensity(newDebtDensity(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, context))),
+ (context, formula) -> context.setValue(context.getDebtRatingGrid().getRatingForDensity(newDebtDensity(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, context))),
+ (context, issues) -> context.setValue(context.getDebtRatingGrid().getRatingForDensity(newDebtDensity(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, context))),
asList(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, CoreMetrics.NEW_DEVELOPMENT_COST)),
new MeasureUpdateFormula(EFFORT_TO_REACH_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_A, false, true,
@@ -355,20 +352,6 @@ public class MeasureUpdateFormulaFactoryImpl implements MeasureUpdateFormulaFact
.map(RATING_BY_SOFTWARE_QUALITY_SEVERITY::get)
.orElse(Rating.A);
context.setValue(rating);
- }),
-
- new MeasureUpdateFormula(SOFTWARE_QUALITY_SECURITY_REVIEW_RATING, false, true,
- (context, formula) -> context.setValue(computeAToDRating(context.getValue(SECURITY_HOTSPOTS_REVIEWED).orElse(null))),
- (context, issues) -> {
- Optional<Double> percent = computePercent(issues.countHotspotsByStatus(Issue.STATUS_TO_REVIEW, false), issues.countHotspotsByStatus(Issue.STATUS_REVIEWED, false));
- context.setValue(computeAToDRating(percent.orElse(null)));
- }),
-
- new MeasureUpdateFormula(NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING, true, true,
- (context, formula) -> context.setValue(computeAToDRating(context.getValue(NEW_SECURITY_HOTSPOTS_REVIEWED).orElse(null))),
- (context, issues) -> {
- Optional<Double> percent = computePercent(issues.countHotspotsByStatus(Issue.STATUS_TO_REVIEW, true), issues.countHotspotsByStatus(Issue.STATUS_REVIEWED, true));
- context.setValue(computeAToDRating(percent.orElse(null)));
}));
private static final Set<Metric> FORMULA_METRICS = MeasureUpdateFormulaFactory.extractMetrics(FORMULAS);
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java
index e72cd6362b8..16a11c4b5a5 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java
@@ -57,7 +57,6 @@ public class MeasuresWsModule extends Module {
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING,
- SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT,
@@ -67,7 +66,6 @@ public class MeasuresWsModule extends Module {
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING,
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING,
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING,
- SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING,
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT,
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT,
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT)
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleMapper.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleMapper.java
index d4f1ca3f818..5f695661ae8 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleMapper.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleMapper.java
@@ -45,6 +45,7 @@ import org.sonar.db.rule.RuleParamDto;
import org.sonar.db.user.UserDto;
import org.sonar.markdown.Markdown;
import org.sonar.server.common.text.MacroInterpreter;
+import org.sonar.server.issue.ImpactFormatter;
import org.sonar.server.rule.RuleDescriptionFormatter;
import org.sonar.server.rule.ws.RulesResponseFormatter.SearchResult;
import org.sonarqube.ws.Common;
@@ -164,7 +165,7 @@ public class RuleMapper {
}
private static Common.Impact toImpact(ImpactDto impactDto) {
- Common.ImpactSeverity severity = Common.ImpactSeverity.valueOf(impactDto.getSeverity().name());
+ Common.ImpactSeverity severity = ImpactFormatter.mapImpactSeverity(impactDto.getSeverity());
Common.SoftwareQuality softwareQuality = Common.SoftwareQuality.valueOf(impactDto.getSoftwareQuality().name());
return Common.Impact.newBuilder().setSeverity(severity).setSoftwareQuality(softwareQuality).build();
}
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ImpactFormatterTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ImpactFormatterTest.java
new file mode 100644
index 00000000000..3a801c4e6cb
--- /dev/null
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ImpactFormatterTest.java
@@ -0,0 +1,38 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.issue;
+
+import org.junit.jupiter.api.Test;
+import org.sonar.api.issue.impact.Severity;
+import org.sonarqube.ws.Common;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class ImpactFormatterTest {
+
+ @Test
+ void mapImpactSeverity_shouldReturnExpectedValue() {
+ assertEquals(Common.ImpactSeverity.ImpactSeverity_BLOCKER, ImpactFormatter.mapImpactSeverity(Severity.BLOCKER));
+ assertEquals(Common.ImpactSeverity.HIGH, ImpactFormatter.mapImpactSeverity(Severity.HIGH));
+ assertEquals(Common.ImpactSeverity.MEDIUM, ImpactFormatter.mapImpactSeverity(Severity.MEDIUM));
+ assertEquals(Common.ImpactSeverity.LOW, ImpactFormatter.mapImpactSeverity(Severity.LOW));
+ assertEquals(Common.ImpactSeverity.ImpactSeverity_INFO, ImpactFormatter.mapImpactSeverity(Severity.INFO));
+ }
+}
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImplTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImplTest.java
index 1eb1e92a377..8d8d29c8a9e 100644
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImplTest.java
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImplTest.java
@@ -52,7 +52,9 @@ import org.sonar.server.measure.Rating;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.params.provider.Arguments.arguments;
+import static org.sonar.api.issue.impact.Severity.BLOCKER;
import static org.sonar.api.issue.impact.Severity.HIGH;
+import static org.sonar.api.issue.impact.Severity.INFO;
import static org.sonar.api.issue.impact.Severity.LOW;
import static org.sonar.api.issue.impact.Severity.MEDIUM;
import static org.sonar.api.issue.impact.SoftwareQuality.MAINTAINABILITY;
@@ -167,12 +169,6 @@ class MeasureUpdateFormulaFactoryImplTest {
@Test
void computeHierarchy_shouldRecomputeSoftwareQualityMetricsCombiningOtherMetrics() {
- new HierarchyTester(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING)
- .withValue(SECURITY_HOTSPOTS_REVIEWED, 0d)
- .expectedRating(Rating.D);
- new HierarchyTester(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING)
- .withValue(NEW_SECURITY_HOTSPOTS_REVIEWED, 0d)
- .expectedRating(Rating.D);
new HierarchyTester(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO)
.withValue(SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, 10d)
.withValue(CoreMetrics.DEVELOPMENT_COST, "40")
@@ -187,11 +183,26 @@ class MeasureUpdateFormulaFactoryImplTest {
.withValue(CoreMetrics.DEVELOPMENT_COST, "40")
.expectedRating(Rating.D);
+ new HierarchyTester(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING)
+ .withValue(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, 21d)
+ .withValue(CoreMetrics.DEVELOPMENT_COST, "40")
+ .expectedRating(Rating.E);
+
+ new HierarchyTester(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING)
+ .withValue(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, 1d)
+ .withValue(CoreMetrics.NEW_DEVELOPMENT_COST, 40d)
+ .expectedRating(Rating.A);
+
new HierarchyTester(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING)
.withValue(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, 10d)
.withValue(CoreMetrics.NEW_DEVELOPMENT_COST, 40d)
.expectedRating(Rating.D);
+ new HierarchyTester(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING)
+ .withValue(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, 21d)
+ .withValue(CoreMetrics.NEW_DEVELOPMENT_COST, 40d)
+ .expectedRating(Rating.E);
+
new HierarchyTester(SoftwareQualitiesMetrics.EFFORT_TO_REACH_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_A)
.withValue(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, 10d)
.withValue(CoreMetrics.DEVELOPMENT_COST, "40")
@@ -264,7 +275,7 @@ class MeasureUpdateFormulaFactoryImplTest {
newResolvedGroup(RuleType.BUG).setCount(7),
// not bugs
newGroup(RuleType.CODE_SMELL).setCount(11))
- .assertThatValueIs(CoreMetrics.BUGS, 3 + 5);
+ .assertThatValueIs(CoreMetrics.BUGS, 3 + 5);
}
@Test
@@ -277,7 +288,7 @@ class MeasureUpdateFormulaFactoryImplTest {
newResolvedGroup(RuleType.CODE_SMELL).setCount(7),
// not code smells
newGroup(RuleType.BUG).setCount(11))
- .assertThatValueIs(CoreMetrics.CODE_SMELLS, 3 + 5);
+ .assertThatValueIs(CoreMetrics.CODE_SMELLS, 3 + 5);
}
@Test
@@ -290,7 +301,7 @@ class MeasureUpdateFormulaFactoryImplTest {
newResolvedGroup(RuleType.VULNERABILITY).setCount(7),
// not vulnerabilities
newGroup(RuleType.BUG).setCount(11))
- .assertThatValueIs(CoreMetrics.VULNERABILITIES, 3 + 5);
+ .assertThatValueIs(CoreMetrics.VULNERABILITIES, 3 + 5);
}
@Test
@@ -303,7 +314,7 @@ class MeasureUpdateFormulaFactoryImplTest {
newResolvedGroup(RuleType.SECURITY_HOTSPOT).setCount(7),
// not hotspots
newGroup(RuleType.BUG).setCount(11))
- .assertThatValueIs(CoreMetrics.SECURITY_HOTSPOTS, 3 + 5);
+ .assertThatValueIs(CoreMetrics.SECURITY_HOTSPOTS, 3 + 5);
}
@Test
@@ -311,18 +322,15 @@ class MeasureUpdateFormulaFactoryImplTest {
with(
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_REVIEWED).setCount(3),
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(1))
- .assertThatValueIs(SECURITY_REVIEW_RATING, Rating.B)
- .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING, Rating.B);
+ .assertThatValueIs(SECURITY_REVIEW_RATING, Rating.B);
withNoIssues()
- .assertThatValueIs(SECURITY_REVIEW_RATING, Rating.A)
- .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING, Rating.A);
+ .assertThatValueIs(SECURITY_REVIEW_RATING, Rating.A);
with(
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(3).setInLeak(true),
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(1).setInLeak(true))
- .assertThatValueIs(SECURITY_REVIEW_RATING, Rating.E)
- .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING, Rating.D);
+ .assertThatValueIs(SECURITY_REVIEW_RATING, Rating.E);
}
@Test
@@ -330,7 +338,7 @@ class MeasureUpdateFormulaFactoryImplTest {
with(
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_REVIEWED).setCount(3),
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(1))
- .assertThatValueIs(SECURITY_HOTSPOTS_REVIEWED, 75.0);
+ .assertThatValueIs(SECURITY_HOTSPOTS_REVIEWED, 75.0);
withNoIssues()
.assertNoValue(SECURITY_HOTSPOTS_REVIEWED);
@@ -341,7 +349,7 @@ class MeasureUpdateFormulaFactoryImplTest {
with(
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_REVIEWED).setCount(3),
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(1))
- .assertThatValueIs(CoreMetrics.SECURITY_HOTSPOTS_REVIEWED_STATUS, 3.0);
+ .assertThatValueIs(CoreMetrics.SECURITY_HOTSPOTS_REVIEWED_STATUS, 3.0);
withNoIssues()
.assertThatValueIs(CoreMetrics.SECURITY_HOTSPOTS_REVIEWED_STATUS, 0.0);
@@ -352,7 +360,7 @@ class MeasureUpdateFormulaFactoryImplTest {
with(
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_REVIEWED).setCount(3),
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(1))
- .assertThatValueIs(CoreMetrics.SECURITY_HOTSPOTS_TO_REVIEW_STATUS, 1.0);
+ .assertThatValueIs(CoreMetrics.SECURITY_HOTSPOTS_TO_REVIEW_STATUS, 1.0);
withNoIssues()
.assertThatValueIs(CoreMetrics.SECURITY_HOTSPOTS_TO_REVIEW_STATUS, 0.0);
@@ -380,11 +388,11 @@ class MeasureUpdateFormulaFactoryImplTest {
newResolvedGroup(RuleType.VULNERABILITY).setSeverity(Severity.INFO).setCount(17),
newResolvedGroup(RuleType.BUG).setSeverity(Severity.MAJOR).setCount(19),
newResolvedGroup(RuleType.SECURITY_HOTSPOT).setSeverity(Severity.INFO).setCount(21))
- .assertThatValueIs(CoreMetrics.BLOCKER_VIOLATIONS, 11 + 13)
- .assertThatValueIs(CoreMetrics.CRITICAL_VIOLATIONS, 7)
- .assertThatValueIs(CoreMetrics.MAJOR_VIOLATIONS, 3 + 5)
- .assertThatValueIs(CoreMetrics.MINOR_VIOLATIONS, 0)
- .assertThatValueIs(CoreMetrics.INFO_VIOLATIONS, 0);
+ .assertThatValueIs(CoreMetrics.BLOCKER_VIOLATIONS, 11 + 13)
+ .assertThatValueIs(CoreMetrics.CRITICAL_VIOLATIONS, 7)
+ .assertThatValueIs(CoreMetrics.MAJOR_VIOLATIONS, 3 + 5)
+ .assertThatValueIs(CoreMetrics.MINOR_VIOLATIONS, 0)
+ .assertThatValueIs(CoreMetrics.INFO_VIOLATIONS, 0);
}
@Test
@@ -404,8 +412,8 @@ class MeasureUpdateFormulaFactoryImplTest {
// exclude unresolved
newGroup(RuleType.VULNERABILITY).setCount(17),
newGroup(RuleType.BUG).setCount(19))
- .assertThatValueIs(CoreMetrics.FALSE_POSITIVE_ISSUES, 5)
- .assertThatValueIs(CoreMetrics.ACCEPTED_ISSUES, 7 + 11);
+ .assertThatValueIs(CoreMetrics.FALSE_POSITIVE_ISSUES, 5)
+ .assertThatValueIs(CoreMetrics.ACCEPTED_ISSUES, 7 + 11);
}
@Test
@@ -424,9 +432,9 @@ class MeasureUpdateFormulaFactoryImplTest {
// exclude security hotspot
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_OPEN).setCount(12),
newResolvedGroup(Issue.RESOLUTION_FALSE_POSITIVE, Issue.STATUS_CLOSED).setCount(13))
- .assertThatValueIs(CoreMetrics.CONFIRMED_ISSUES, 3 + 5)
- .assertThatValueIs(CoreMetrics.OPEN_ISSUES, 9 + 11)
- .assertThatValueIs(CoreMetrics.REOPENED_ISSUES, 7);
+ .assertThatValueIs(CoreMetrics.CONFIRMED_ISSUES, 3 + 5)
+ .assertThatValueIs(CoreMetrics.OPEN_ISSUES, 9 + 11)
+ .assertThatValueIs(CoreMetrics.REOPENED_ISSUES, 7);
}
@Test
@@ -443,7 +451,7 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.BUG).setEffort(7.0),
// exclude resolved
newResolvedGroup(RuleType.CODE_SMELL).setEffort(17.0))
- .assertThatValueIs(CoreMetrics.TECHNICAL_DEBT, 3.0 + 5.0);
+ .assertThatValueIs(CoreMetrics.TECHNICAL_DEBT, 3.0 + 5.0);
}
@Test
@@ -457,7 +465,7 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.CODE_SMELL).setEffort(7.0),
// exclude resolved
newResolvedGroup(RuleType.BUG).setEffort(17.0))
- .assertThatValueIs(CoreMetrics.RELIABILITY_REMEDIATION_EFFORT, 3.0 + 5.0);
+ .assertThatValueIs(CoreMetrics.RELIABILITY_REMEDIATION_EFFORT, 3.0 + 5.0);
}
@Test
@@ -471,19 +479,21 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.CODE_SMELL).setEffort(7.0),
// exclude resolved
newResolvedGroup(RuleType.VULNERABILITY).setEffort(17.0))
- .assertThatValueIs(CoreMetrics.SECURITY_REMEDIATION_EFFORT, 3.0 + 5.0);
+ .assertThatValueIs(CoreMetrics.SECURITY_REMEDIATION_EFFORT, 3.0 + 5.0);
}
private static Stream<Arguments> maintainabilityMetrics() {
return Stream.of(
arguments(TECHNICAL_DEBT, SQALE_DEBT_RATIO, SQALE_RATING),
- arguments(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO,
+ arguments(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT,
+ SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING));
}
@ParameterizedTest
@MethodSource("maintainabilityMetrics")
- void test_sqale_debt_ratio_and_sqale_rating(Metric<?> maintainabilityRemediationEffortMetric, Metric<?> maintainabilityDebtRatioMetric, Metric<?> maintainabilityRatingMetric) {
+ void test_sqale_debt_ratio_and_sqale_rating(Metric<?> maintainabilityRemediationEffortMetric, Metric<?> maintainabilityDebtRatioMetric,
+ Metric<?> maintainabilityRatingMetric) {
withNoIssues()
.assertThatValueIs(maintainabilityDebtRatioMetric, 0)
.assertThatValueIs(maintainabilityRatingMetric, Rating.A);
@@ -519,8 +529,8 @@ class MeasureUpdateFormulaFactoryImplTest {
.andText(CoreMetrics.DEVELOPMENT_COST, "10")
.assertThatValueIs(maintainabilityDebtRatioMetric, 200.0);
switch (maintainabilityRatingMetric.key()) {
- case SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY -> verifier.assertThatValueIs(maintainabilityRatingMetric, Rating.D);
- case SQALE_RATING_KEY -> verifier.assertThatValueIs(maintainabilityRatingMetric, Rating.E);
+ case SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, SQALE_RATING_KEY ->
+ verifier.assertThatValueIs(maintainabilityRatingMetric, Rating.E);
default -> throw new IllegalArgumentException("Unexpected metric: " + maintainabilityRatingMetric.key());
}
@@ -619,14 +629,14 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.BUG).setSeverity(Severity.MINOR).setCount(5),
// excluded, not a bug
newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setCount(3))
- // highest severity of bugs is CRITICAL --> D
- .assertThatValueIs(CoreMetrics.RELIABILITY_RATING, Rating.D);
+ // highest severity of bugs is CRITICAL --> D
+ .assertThatValueIs(CoreMetrics.RELIABILITY_RATING, Rating.D);
with(
newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setCount(3),
newGroup(RuleType.VULNERABILITY).setSeverity(Severity.CRITICAL).setCount(5))
- // no bugs --> A
- .assertThatValueIs(CoreMetrics.RELIABILITY_RATING, Rating.A);
+ // no bugs --> A
+ .assertThatValueIs(CoreMetrics.RELIABILITY_RATING, Rating.A);
}
@Test
@@ -635,15 +645,27 @@ class MeasureUpdateFormulaFactoryImplTest {
.assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.A);
with(
+ newImpactGroup(RELIABILITY, BLOCKER, 1))
+ .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.E);
+
+ with(
+ newImpactGroup(RELIABILITY, HIGH, 1))
+ .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.D);
+
+ with(
newImpactGroup(MAINTAINABILITY, HIGH, 1),
newImpactGroup(RELIABILITY, MEDIUM, 1),
newImpactGroup(RELIABILITY, LOW, 1),
newImpactGroup(SECURITY, MEDIUM, 1))
- .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.C);
+ .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.C);
with(
newImpactGroup(RELIABILITY, LOW, 1))
- .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.B);
+ .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.B);
+
+ with(
+ newImpactGroup(RELIABILITY, INFO, 1))
+ .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.A);
}
@Test
@@ -652,17 +674,31 @@ class MeasureUpdateFormulaFactoryImplTest {
.assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.A);
with(
+ newImpactGroup(RELIABILITY, BLOCKER, 1, true))
+ .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.E);
+
+ with(
+ newImpactGroup(RELIABILITY, HIGH, 1, true),
+ newImpactGroup(RELIABILITY, BLOCKER, 1, false))
+ .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.D);
+
+ with(
newImpactGroup(MAINTAINABILITY, HIGH, 1, true),
newImpactGroup(RELIABILITY, MEDIUM, 1, true),
newImpactGroup(RELIABILITY, LOW, 1, true),
newImpactGroup(RELIABILITY, HIGH, 1, false),
newImpactGroup(SECURITY, HIGH, 1, true))
- .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.C);
+ .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.C);
with(
newImpactGroup(RELIABILITY, LOW, 1, true),
newImpactGroup(RELIABILITY, MEDIUM, 1, false))
- .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.B);
+ .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.B);
+
+ with(
+ newImpactGroup(RELIABILITY, INFO, 1, true),
+ newImpactGroup(RELIABILITY, MEDIUM, 1, false))
+ .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING, Rating.A);
}
@Test
@@ -675,14 +711,14 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.VULNERABILITY).setSeverity(Severity.MINOR).setCount(5),
// excluded, not a vulnerability
newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setCount(3))
- // highest severity of vulnerabilities is CRITICAL --> D
- .assertThatValueIs(CoreMetrics.SECURITY_RATING, Rating.D);
+ // highest severity of vulnerabilities is CRITICAL --> D
+ .assertThatValueIs(CoreMetrics.SECURITY_RATING, Rating.D);
with(
newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setCount(3),
newGroup(RuleType.BUG).setSeverity(Severity.CRITICAL).setCount(5))
- // no vulnerabilities --> A
- .assertThatValueIs(CoreMetrics.SECURITY_RATING, Rating.A);
+ // no vulnerabilities --> A
+ .assertThatValueIs(CoreMetrics.SECURITY_RATING, Rating.A);
}
@Test
@@ -691,15 +727,27 @@ class MeasureUpdateFormulaFactoryImplTest {
.assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING, Rating.A);
with(
+ newImpactGroup(SECURITY, BLOCKER, 1))
+ .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING, Rating.E);
+
+ with(
+ newImpactGroup(SECURITY, HIGH, 1))
+ .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING, Rating.D);
+
+ with(
newImpactGroup(MAINTAINABILITY, HIGH, 1),
newImpactGroup(SECURITY, MEDIUM, 1),
newImpactGroup(SECURITY, LOW, 1),
newImpactGroup(RELIABILITY, MEDIUM, 1))
- .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING, Rating.C);
+ .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING, Rating.C);
with(
newImpactGroup(SECURITY, LOW, 1))
- .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING, Rating.B);
+ .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING, Rating.B);
+
+ with(
+ newImpactGroup(SECURITY, INFO, 2))
+ .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING, Rating.A);
}
@Test
@@ -708,17 +756,31 @@ class MeasureUpdateFormulaFactoryImplTest {
.assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING, Rating.A);
with(
+ newImpactGroup(SECURITY, BLOCKER, 1, true))
+ .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING, Rating.E);
+
+ with(
+ newImpactGroup(SECURITY, HIGH, 1, true),
+ newImpactGroup(SECURITY, BLOCKER, 1, false))
+ .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING, Rating.D);
+
+ with(
newImpactGroup(MAINTAINABILITY, HIGH, 1, true),
newImpactGroup(SECURITY, MEDIUM, 1, true),
newImpactGroup(SECURITY, LOW, 1, true),
newImpactGroup(SECURITY, HIGH, 1, false),
newImpactGroup(RELIABILITY, HIGH, 1, true))
- .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING, Rating.C);
+ .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING, Rating.C);
with(
newImpactGroup(SECURITY, LOW, 1, true),
newImpactGroup(SECURITY, MEDIUM, 1, false))
- .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING, Rating.B);
+ .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING, Rating.B);
+
+ with(
+ newImpactGroup(SECURITY, INFO, 1, true),
+ newImpactGroup(SECURITY, MEDIUM, 1, false))
+ .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING, Rating.A);
}
@Test
@@ -732,7 +794,7 @@ class MeasureUpdateFormulaFactoryImplTest {
// not bugs
newGroup(RuleType.CODE_SMELL).setInLeak(true).setCount(9),
newGroup(RuleType.VULNERABILITY).setInLeak(true).setCount(11))
- .assertThatLeakValueIs(CoreMetrics.NEW_BUGS, 5 + 7);
+ .assertThatLeakValueIs(CoreMetrics.NEW_BUGS, 5 + 7);
}
@@ -747,7 +809,7 @@ class MeasureUpdateFormulaFactoryImplTest {
// not code smells
newGroup(RuleType.BUG).setInLeak(true).setCount(9),
newGroup(RuleType.VULNERABILITY).setInLeak(true).setCount(11))
- .assertThatLeakValueIs(CoreMetrics.NEW_CODE_SMELLS, 5 + 7);
+ .assertThatLeakValueIs(CoreMetrics.NEW_CODE_SMELLS, 5 + 7);
}
@Test
@@ -761,7 +823,7 @@ class MeasureUpdateFormulaFactoryImplTest {
// not vulnerabilities
newGroup(RuleType.BUG).setInLeak(true).setCount(9),
newGroup(RuleType.CODE_SMELL).setInLeak(true).setCount(11))
- .assertThatLeakValueIs(CoreMetrics.NEW_VULNERABILITIES, 5 + 7);
+ .assertThatLeakValueIs(CoreMetrics.NEW_VULNERABILITIES, 5 + 7);
}
@Test
@@ -775,7 +837,7 @@ class MeasureUpdateFormulaFactoryImplTest {
// not hotspots
newGroup(RuleType.BUG).setInLeak(true).setCount(9),
newGroup(RuleType.CODE_SMELL).setInLeak(true).setCount(11))
- .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_HOTSPOTS, 5 + 7);
+ .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_HOTSPOTS, 5 + 7);
}
@Test
@@ -790,7 +852,7 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.BUG).setInLeak(false).setCount(11),
newGroup(RuleType.CODE_SMELL).setInLeak(false).setCount(13),
newGroup(RuleType.VULNERABILITY).setInLeak(false).setCount(17))
- .assertThatLeakValueIs(CoreMetrics.NEW_VIOLATIONS, 5 + 7 + 9);
+ .assertThatLeakValueIs(CoreMetrics.NEW_VIOLATIONS, 5 + 7 + 9);
}
@Test
@@ -807,7 +869,7 @@ class MeasureUpdateFormulaFactoryImplTest {
// not in leak
newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setInLeak(false).setCount(11),
newGroup(RuleType.BUG).setSeverity(Severity.BLOCKER).setInLeak(false).setCount(13))
- .assertThatLeakValueIs(CoreMetrics.NEW_BLOCKER_VIOLATIONS, 3 + 5 + 7);
+ .assertThatLeakValueIs(CoreMetrics.NEW_BLOCKER_VIOLATIONS, 3 + 5 + 7);
}
@Test
@@ -824,7 +886,7 @@ class MeasureUpdateFormulaFactoryImplTest {
// not in leak
newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setInLeak(false).setCount(11),
newGroup(RuleType.BUG).setSeverity(Severity.CRITICAL).setInLeak(false).setCount(13))
- .assertThatLeakValueIs(CoreMetrics.NEW_CRITICAL_VIOLATIONS, 3 + 5 + 7);
+ .assertThatLeakValueIs(CoreMetrics.NEW_CRITICAL_VIOLATIONS, 3 + 5 + 7);
}
@Test
@@ -841,7 +903,7 @@ class MeasureUpdateFormulaFactoryImplTest {
// not in leak
newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setInLeak(false).setCount(11),
newGroup(RuleType.BUG).setSeverity(Severity.MAJOR).setInLeak(false).setCount(13))
- .assertThatLeakValueIs(CoreMetrics.NEW_MAJOR_VIOLATIONS, 3 + 5 + 7);
+ .assertThatLeakValueIs(CoreMetrics.NEW_MAJOR_VIOLATIONS, 3 + 5 + 7);
}
@Test
@@ -858,7 +920,7 @@ class MeasureUpdateFormulaFactoryImplTest {
// not in leak
newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MINOR).setInLeak(false).setCount(11),
newGroup(RuleType.BUG).setSeverity(Severity.MINOR).setInLeak(false).setCount(13))
- .assertThatLeakValueIs(CoreMetrics.NEW_MINOR_VIOLATIONS, 3 + 5 + 7);
+ .assertThatLeakValueIs(CoreMetrics.NEW_MINOR_VIOLATIONS, 3 + 5 + 7);
}
@Test
@@ -875,7 +937,7 @@ class MeasureUpdateFormulaFactoryImplTest {
// not in leak
newGroup(RuleType.CODE_SMELL).setSeverity(Severity.INFO).setInLeak(false).setCount(11),
newGroup(RuleType.BUG).setSeverity(Severity.INFO).setInLeak(false).setCount(13))
- .assertThatLeakValueIs(CoreMetrics.NEW_INFO_VIOLATIONS, 3 + 5 + 7);
+ .assertThatLeakValueIs(CoreMetrics.NEW_INFO_VIOLATIONS, 3 + 5 + 7);
}
@Test
@@ -891,7 +953,7 @@ class MeasureUpdateFormulaFactoryImplTest {
// not in leak
newGroup(RuleType.CODE_SMELL).setResolution(Issue.RESOLUTION_WONT_FIX).setInLeak(false).setCount(5),
newGroup(RuleType.BUG).setResolution(Issue.RESOLUTION_WONT_FIX).setInLeak(false).setCount(50))
- .assertThatLeakValueIs(CoreMetrics.NEW_ACCEPTED_ISSUES, 4 + 40);
+ .assertThatLeakValueIs(CoreMetrics.NEW_ACCEPTED_ISSUES, 4 + 40);
}
@Test
@@ -907,7 +969,7 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.BUG).setEffort(7.0).setInLeak(true),
// exclude resolved
newResolvedGroup(RuleType.CODE_SMELL).setEffort(17.0).setInLeak(true))
- .assertThatLeakValueIs(CoreMetrics.NEW_TECHNICAL_DEBT, 3.0);
+ .assertThatLeakValueIs(CoreMetrics.NEW_TECHNICAL_DEBT, 3.0);
}
@Test
@@ -922,7 +984,7 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.CODE_SMELL).setEffort(7.0).setInLeak(true),
// exclude resolved
newResolvedGroup(RuleType.BUG).setEffort(17.0).setInLeak(true))
- .assertThatLeakValueIs(CoreMetrics.NEW_RELIABILITY_REMEDIATION_EFFORT, 3.0);
+ .assertThatLeakValueIs(CoreMetrics.NEW_RELIABILITY_REMEDIATION_EFFORT, 3.0);
}
@Test
@@ -937,7 +999,7 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.CODE_SMELL).setEffort(7.0).setInLeak(true),
// exclude resolved
newResolvedGroup(RuleType.VULNERABILITY).setEffort(17.0).setInLeak(true))
- .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_REMEDIATION_EFFORT, 3.0);
+ .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_REMEDIATION_EFFORT, 3.0);
}
@Test
@@ -953,8 +1015,8 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setInLeak(true),
// exclude resolved
newResolvedGroup(RuleType.BUG).setSeverity(Severity.BLOCKER).setInLeak(true))
- // highest severity of bugs on leak period is minor -> B
- .assertThatLeakValueIs(CoreMetrics.NEW_RELIABILITY_RATING, Rating.B);
+ // highest severity of bugs on leak period is minor -> B
+ .assertThatLeakValueIs(CoreMetrics.NEW_RELIABILITY_RATING, Rating.B);
}
@Test
@@ -970,8 +1032,8 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setInLeak(true),
// exclude resolved
newResolvedGroup(RuleType.VULNERABILITY).setSeverity(Severity.BLOCKER).setInLeak(true))
- // highest severity of bugs on leak period is minor -> B
- .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_RATING, Rating.B);
+ // highest severity of bugs on leak period is minor -> B
+ .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_RATING, Rating.B);
}
@Test
@@ -981,20 +1043,17 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(1).setInLeak(true),
// not in leak
newGroup(RuleType.SECURITY_HOTSPOT).setSeverity(Issue.STATUS_TO_REVIEW).setInLeak(false))
- .assertThatLeakValueIs(NEW_SECURITY_REVIEW_RATING, Rating.B)
- .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING, Rating.B);
+ .assertThatLeakValueIs(NEW_SECURITY_REVIEW_RATING, Rating.B);
withNoIssues()
- .assertThatLeakValueIs(NEW_SECURITY_REVIEW_RATING, Rating.A)
- .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING, Rating.A);
+ .assertThatLeakValueIs(NEW_SECURITY_REVIEW_RATING, Rating.A);
with(
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(3).setInLeak(true),
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(1).setInLeak(true),
// not in leak
newGroup(RuleType.SECURITY_HOTSPOT).setSeverity(Issue.STATUS_TO_REVIEW).setInLeak(false))
- .assertThatLeakValueIs(NEW_SECURITY_REVIEW_RATING, Rating.E)
- .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING, Rating.D);
+ .assertThatLeakValueIs(NEW_SECURITY_REVIEW_RATING, Rating.E);
}
@Test
@@ -1004,7 +1063,7 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(1).setInLeak(true),
// not in leak
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(5).setInLeak(false))
- .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_HOTSPOTS_REVIEWED, 75.0);
+ .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_HOTSPOTS_REVIEWED, 75.0);
withNoIssues()
.assertNoLeakValue(CoreMetrics.NEW_SECURITY_HOTSPOTS_REVIEWED);
@@ -1017,7 +1076,7 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(1).setInLeak(true),
// not in leak
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(5).setInLeak(false))
- .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_HOTSPOTS_REVIEWED_STATUS, 3.0);
+ .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_HOTSPOTS_REVIEWED_STATUS, 3.0);
withNoIssues()
.assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_HOTSPOTS_REVIEWED_STATUS, 0.0);
@@ -1030,7 +1089,7 @@ class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(1).setInLeak(true),
// not in leak
newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW).setCount(5).setInLeak(false))
- .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_HOTSPOTS_TO_REVIEW_STATUS, 1.0);
+ .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_HOTSPOTS_TO_REVIEW_STATUS, 1.0);
withNoIssues()
.assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_HOTSPOTS_TO_REVIEW_STATUS, 0.0);
@@ -1039,13 +1098,15 @@ class MeasureUpdateFormulaFactoryImplTest {
private static Stream<Arguments> newMaintainabilityMetrics() {
return Stream.of(
arguments(CoreMetrics.NEW_TECHNICAL_DEBT, CoreMetrics.NEW_SQALE_DEBT_RATIO, CoreMetrics.NEW_MAINTAINABILITY_RATING),
- arguments(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO,
+ arguments(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT,
+ SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO,
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING));
}
@ParameterizedTest
@MethodSource("newMaintainabilityMetrics")
- void test_new_sqale_debt_ratio_and_new_maintainability_rating(Metric<?> newMaintainabilityRemediationEffortMetric, Metric<?> newMaintainabilityDebtRatioMetric,
+ void test_new_sqale_debt_ratio_and_new_maintainability_rating(Metric<?> newMaintainabilityRemediationEffortMetric,
+ Metric<?> newMaintainabilityDebtRatioMetric,
Metric<?> newMaintainabilityRatingMetric) {
withNoIssues()
.assertThatLeakValueIs(newMaintainabilityDebtRatioMetric, 0)
@@ -1082,8 +1143,8 @@ class MeasureUpdateFormulaFactoryImplTest {
.and(CoreMetrics.NEW_DEVELOPMENT_COST, 10.0D)
.assertThatLeakValueIs(newMaintainabilityDebtRatioMetric, 200.0);
switch (newMaintainabilityRatingMetric.key()) {
- case NEW_MAINTAINABILITY_RATING_KEY -> verifier.assertThatLeakValueIs(newMaintainabilityRatingMetric, Rating.E);
- case SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY -> verifier.assertThatLeakValueIs(newMaintainabilityRatingMetric, Rating.D);
+ case NEW_MAINTAINABILITY_RATING_KEY, SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY ->
+ verifier.assertThatLeakValueIs(newMaintainabilityRatingMetric, Rating.E);
default -> throw new IllegalArgumentException("Unexpected metric: " + newMaintainabilityRatingMetric.key());
}
@@ -1135,7 +1196,7 @@ class MeasureUpdateFormulaFactoryImplTest {
newImpactGroup(SECURITY, LOW, Issue.STATUS_RESOLVED, Issue.RESOLUTION_WONT_FIX, 6),
newImpactGroup(SECURITY, HIGH, Issue.STATUS_RESOLVED, Issue.RESOLUTION_FALSE_POSITIVE, 7),
newImpactGroup(RELIABILITY, HIGH, Issue.STATUS_RESOLVED, Issue.RESOLUTION_WONT_FIX, 8))
- .assertThatValueIs(CoreMetrics.HIGH_IMPACT_ACCEPTED_ISSUES, 4 + 8);
+ .assertThatValueIs(CoreMetrics.HIGH_IMPACT_ACCEPTED_ISSUES, 4 + 8);
}
@Test
@@ -1157,12 +1218,12 @@ class MeasureUpdateFormulaFactoryImplTest {
newImpactGroup(SECURITY, HIGH, Issue.STATUS_RESOLVED, Issue.RESOLUTION_WONT_FIX, 4, 1d, false),
newImpactGroup(RELIABILITY, HIGH, Issue.STATUS_RESOLVED, Issue.RESOLUTION_WONT_FIX, 8, 1d, false),
newImpactGroup(MAINTAINABILITY, MEDIUM, Issue.STATUS_RESOLVED, Issue.RESOLUTION_WONT_FIX, 8, 1d, false))
- .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, 1d + 2d)
- .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT, 1d + 2d)
- .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT, 1d)
- .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, 2d)
- .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT, 2d)
- .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT, 0d);
+ .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, 1d + 2d)
+ .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT, 1d + 2d)
+ .assertThatValueIs(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT, 1d)
+ .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT, 2d)
+ .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT, 2d)
+ .assertThatLeakValueIs(SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT, 0d);
}
@Test
@@ -1186,9 +1247,9 @@ class MeasureUpdateFormulaFactoryImplTest {
newImpactGroup(MAINTAINABILITY, MEDIUM, 10),
newImpactGroup(MAINTAINABILITY, LOW, 11),
newImpactGroup(SECURITY, HIGH, 3))
- .assertThatJsonValueIs(CoreMetrics.RELIABILITY_ISSUES, impactMeasureToJson(8, 3, 4, 1))
- .assertThatJsonValueIs(CoreMetrics.MAINTAINABILITY_ISSUES, impactMeasureToJson(21, 0, 10, 11))
- .assertThatJsonValueIs(CoreMetrics.SECURITY_ISSUES, impactMeasureToJson(3, 3, 0, 0));
+ .assertThatJsonValueIs(CoreMetrics.RELIABILITY_ISSUES, impactMeasureToJson(8, 3, 4, 1))
+ .assertThatJsonValueIs(CoreMetrics.MAINTAINABILITY_ISSUES, impactMeasureToJson(21, 0, 10, 11))
+ .assertThatJsonValueIs(CoreMetrics.SECURITY_ISSUES, impactMeasureToJson(3, 3, 0, 0));
}
@Test
@@ -1347,19 +1408,23 @@ class MeasureUpdateFormulaFactoryImplTest {
return newImpactGroup(softwareQuality, severity, status, resolution, count, 0, false);
}
- private static IssueImpactGroupDto newImpactGroup(SoftwareQuality softwareQuality, org.sonar.api.issue.impact.Severity severity, long count) {
+ private static IssueImpactGroupDto newImpactGroup(SoftwareQuality softwareQuality, org.sonar.api.issue.impact.Severity severity,
+ long count) {
return newImpactGroup(softwareQuality, severity, Issue.STATUS_OPEN, null, count, 0, false);
}
- private static IssueImpactGroupDto newImpactGroup(SoftwareQuality softwareQuality, org.sonar.api.issue.impact.Severity severity, long count, boolean inLeak) {
+ private static IssueImpactGroupDto newImpactGroup(SoftwareQuality softwareQuality, org.sonar.api.issue.impact.Severity severity,
+ long count, boolean inLeak) {
return newImpactGroup(softwareQuality, severity, Issue.STATUS_OPEN, null, count, 0, inLeak);
}
- private static IssueImpactGroupDto newImpactGroup(SoftwareQuality softwareQuality, org.sonar.api.issue.impact.Severity severity, long count, double effort) {
+ private static IssueImpactGroupDto newImpactGroup(SoftwareQuality softwareQuality, org.sonar.api.issue.impact.Severity severity,
+ long count, double effort) {
return newImpactGroup(softwareQuality, severity, Issue.STATUS_OPEN, null, count, effort, false);
}
- private static IssueImpactGroupDto newImpactGroup(SoftwareQuality softwareQuality, org.sonar.api.issue.impact.Severity severity, long count, double effort, boolean inLeak) {
+ private static IssueImpactGroupDto newImpactGroup(SoftwareQuality softwareQuality, org.sonar.api.issue.impact.Severity severity,
+ long count, double effort, boolean inLeak) {
return newImpactGroup(softwareQuality, severity, Issue.STATUS_OPEN, null, count, effort, inLeak);
}
@@ -1420,7 +1485,7 @@ class MeasureUpdateFormulaFactoryImplTest {
@Override
public DebtRatingGrid getDebtRatingGrid() {
- return new DebtRatingGrid(new double[] {0.05, 0.1, 0.2, 0.5});
+ return new DebtRatingGrid(new double[]{0.05, 0.1, 0.2, 0.5});
}
@Override
@@ -1491,7 +1556,8 @@ class MeasureUpdateFormulaFactoryImplTest {
return this;
}
- public HierarchyTester withChildrenHotspotsCounts(long childrenHotspotsReviewed, long childrenNewHotspotsReviewed, long childrenHotspotsToReview,
+ public HierarchyTester withChildrenHotspotsCounts(long childrenHotspotsReviewed, long childrenNewHotspotsReviewed,
+ long childrenHotspotsToReview,
long childrenNewHotspotsToReview) {
this.initialValues.childrenHotspotsReviewed = childrenHotspotsReviewed;
this.initialValues.childrenNewHotspotsReviewed = childrenNewHotspotsReviewed;
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/MeasuresWsModuleTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/MeasuresWsModuleTest.java
index 51d90e14b61..1463035e7f1 100644
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/MeasuresWsModuleTest.java
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/MeasuresWsModuleTest.java
@@ -52,10 +52,10 @@ public class MeasuresWsModuleTest {
public void getNewMetricsInSonarQube107_shouldReturnExactString() {
String actual = MeasuresWsModule.getNewMetricsInSonarQube107();
assertThat(actual).isEqualTo("'software_quality_maintainability_debt_ratio', 'software_quality_maintainability_rating', 'software_quality_reliability_rating', " +
- "'software_quality_security_rating', 'software_quality_security_review_rating', 'software_quality_maintainability_remediation_effort', " +
+ "'software_quality_security_rating', 'software_quality_maintainability_remediation_effort', " +
"'software_quality_reliability_remediation_effort', 'software_quality_security_remediation_effort', 'effort_to_reach_software_quality_maintainability_rating_a', " +
"'new_software_quality_maintainability_debt_ratio', 'new_software_quality_maintainability_rating', 'new_software_quality_reliability_rating', " +
- "'new_software_quality_security_rating', 'new_software_quality_security_review_rating', 'new_software_quality_maintainability_remediation_effort'," +
+ "'new_software_quality_security_rating', 'new_software_quality_maintainability_remediation_effort'," +
" 'new_software_quality_reliability_remediation_effort', 'new_software_quality_security_remediation_effort'");
}
}
diff --git a/sonar-core/src/main/java/org/sonar/core/metric/SoftwareQualitiesMetrics.java b/sonar-core/src/main/java/org/sonar/core/metric/SoftwareQualitiesMetrics.java
index 5738de6bdf6..ddac90bfbc4 100644
--- a/sonar-core/src/main/java/org/sonar/core/metric/SoftwareQualitiesMetrics.java
+++ b/sonar-core/src/main/java/org/sonar/core/metric/SoftwareQualitiesMetrics.java
@@ -26,7 +26,6 @@ import org.sonar.api.measures.Metrics;
import static org.sonar.api.measures.CoreMetrics.DOMAIN_MAINTAINABILITY;
import static org.sonar.api.measures.CoreMetrics.DOMAIN_RELIABILITY;
import static org.sonar.api.measures.CoreMetrics.DOMAIN_SECURITY;
-import static org.sonar.api.measures.CoreMetrics.DOMAIN_SECURITY_REVIEW;
public class SoftwareQualitiesMetrics implements Metrics {
@@ -39,7 +38,7 @@ public class SoftwareQualitiesMetrics implements Metrics {
.setDirection(Metric.DIRECTION_WORST)
.setQualitative(true)
.setBestValue(1.0)
- .setWorstValue(4.0)
+ .setWorstValue(5.0)
.create();
public static final String NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY = "new_software_quality_maintainability_rating";
@@ -54,7 +53,7 @@ public class SoftwareQualitiesMetrics implements Metrics {
.setOptimizedBestValue(true)
.setQualitative(true)
.setBestValue(1.0)
- .setWorstValue(4.0)
+ .setWorstValue(5.0)
.create();
public static final String SOFTWARE_QUALITY_RELIABILITY_RATING_KEY = "software_quality_reliability_rating";
@@ -66,7 +65,7 @@ public class SoftwareQualitiesMetrics implements Metrics {
.setDirection(Metric.DIRECTION_WORST)
.setQualitative(true)
.setBestValue(1.0)
- .setWorstValue(4.0)
+ .setWorstValue(5.0)
.create();
public static final String NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY = "new_software_quality_reliability_rating";
@@ -81,7 +80,7 @@ public class SoftwareQualitiesMetrics implements Metrics {
.setOptimizedBestValue(true)
.setQualitative(true)
.setBestValue(1.0)
- .setWorstValue(4.0)
+ .setWorstValue(5.0)
.create();
public static final String SOFTWARE_QUALITY_SECURITY_RATING_KEY = "software_quality_security_rating";
@@ -93,7 +92,7 @@ public class SoftwareQualitiesMetrics implements Metrics {
.setDirection(Metric.DIRECTION_WORST)
.setQualitative(true)
.setBestValue(1.0)
- .setWorstValue(4.0)
+ .setWorstValue(5.0)
.create();
public static final String NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY = "new_software_quality_security_rating";
@@ -107,36 +106,9 @@ public class SoftwareQualitiesMetrics implements Metrics {
.setOptimizedBestValue(true)
.setQualitative(true)
.setBestValue(1.0)
- .setWorstValue(4.0)
+ .setWorstValue(5.0)
.create();
- public static final String SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY = "software_quality_security_review_rating";
-
- public static final Metric<Integer> SOFTWARE_QUALITY_SECURITY_REVIEW_RATING =
- new Metric.Builder(SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY, "Software Quality Security Review Rating", Metric.ValueType.RATING)
- .setDescription("Software quality security review rating")
- .setDomain(DOMAIN_SECURITY_REVIEW)
- .setDirection(Metric.DIRECTION_WORST)
- .setQualitative(true)
- .setBestValue(1.0)
- .setWorstValue(4.0)
- .create();
-
- public static final String NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY = "new_software_quality_security_review_rating";
-
- public static final Metric<Integer> NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING =
- new Metric.Builder(NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING_KEY, "Software Quality Security Review Rating on New Code",
- Metric.ValueType.RATING)
- .setDescription("Software quality security review rating on new code")
- .setDomain(DOMAIN_SECURITY_REVIEW)
- .setDirection(Metric.DIRECTION_WORST)
- .setDeleteHistoricalData(true)
- .setOptimizedBestValue(true)
- .setQualitative(true)
- .setBestValue(1.0)
- .setWorstValue(4.0)
- .create();
-
public static final String EFFORT_TO_REACH_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_A_KEY =
"effort_to_reach_software_quality_maintainability_rating_a";
@@ -271,8 +243,6 @@ public class SoftwareQualitiesMetrics implements Metrics {
NEW_SOFTWARE_QUALITY_RELIABILITY_RATING,
SOFTWARE_QUALITY_SECURITY_RATING,
NEW_SOFTWARE_QUALITY_SECURITY_RATING,
- SOFTWARE_QUALITY_SECURITY_REVIEW_RATING,
- NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING,
EFFORT_TO_REACH_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_A,
SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT,
NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT,
diff --git a/sonar-core/src/main/java/org/sonar/core/util/ProtobufJsonFormat.java b/sonar-core/src/main/java/org/sonar/core/util/ProtobufJsonFormat.java
index e849eba4b3c..522f4dd84f5 100644
--- a/sonar-core/src/main/java/org/sonar/core/util/ProtobufJsonFormat.java
+++ b/sonar-core/src/main/java/org/sonar/core/util/ProtobufJsonFormat.java
@@ -222,7 +222,8 @@ public class ProtobufJsonFormat {
writer.value((String) value);
break;
case ENUM:
- writer.value(((Descriptors.EnumValueDescriptor) value).getName());
+ String enumValue = formatEnumValue(fieldDescriptor, (Descriptors.EnumValueDescriptor) value);
+ writer.value(enumValue);
break;
case MESSAGE:
writeMessageValue((Message) value, writer);
@@ -232,6 +233,20 @@ public class ProtobufJsonFormat {
}
}
+ /**
+ * As a limitation from protobuf, there can't be the same enum value defined twice in proto, even if they belong to different enums.
+ * To remove this constraint, we let the possibility to have the enum name as the prefix of the enum value to make it unique.
+ * The class will make sure to remove it when converted to JSON.
+ * @see <a href="https://github.com/protocolbuffers/protobuf/issues/5425">https://github.com/protocolbuffers/protobuf/issues/5425</a>
+ */
+ private static String formatEnumValue(Descriptors.FieldDescriptor fieldDescriptor, Descriptors.EnumValueDescriptor value) {
+ String enumValue = value.getName();
+ if (enumValue.startsWith(fieldDescriptor.getEnumType().getName())) {
+ enumValue = enumValue.substring(fieldDescriptor.getEnumType().getName().length() + 1);
+ }
+ return enumValue;
+ }
+
private static void writeMessageValue(Message message, JsonWriter writer) {
MessageType messageType = MessageType.of(message);
if (messageType.doesWrapRepeated) {
diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
index 890d4875c16..7604ab16d9f 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -1244,8 +1244,6 @@ issues.facet.createdAt.last_year=Last year
issues.facet.createdAt.bar_description={0} issues from {1} to {2}
issues.facet.authors=Author
issues.facet.impactSeverities=Severity
-issues.facet.impactSeverities.help.line1=Severities are now directly tied to the software quality impacted. This means that one software quality impacted has one severity.
-issues.facet.impactSeverities.help.line2=There are only three levels: high, medium, and low.
issues.facet.issues=Issue Key
issues.facet.mode=Display Mode
issues.facet.mode.count=Issues
@@ -1328,24 +1326,38 @@ projects.limited_set_of_projects=Displayed project set limited to the top {0} pr
projects.facets.quality_gate=Quality Gate
projects.facets.quality_gate.warning_help=Warning status is deprecated. This filter will disappear when no Warning Quality Gate remains.
projects.facets.rating_x={0} rating
-projects.facets.rating_option.reliability.1=0 issues
+projects.facets.rating_option.reliability.legacy.1=≥ 0 info issues
+projects.facets.rating_option.reliability.legacy.2=≥ 1 minor issue
+projects.facets.rating_option.reliability.legacy.3=≥ 1 major issue
+projects.facets.rating_option.reliability.legacy.4=≥ 1 critical issue
+projects.facets.rating_option.reliability.legacy.5=≥ 1 blocker issue
+projects.facets.rating_option.reliability.1=≥ 0 info issues
projects.facets.rating_option.reliability.2=≥ 1 low issue
projects.facets.rating_option.reliability.3=≥ 1 medium issue
projects.facets.rating_option.reliability.4=≥ 1 high issue
-projects.facets.rating_option.security.1=0 issues
+projects.facets.rating_option.reliability.5=≥ 1 blocker issue
+projects.facets.rating_option.security.legacy.1=≥ 0 info issues
+projects.facets.rating_option.security.legacy.2=≥ 1 minor issue
+projects.facets.rating_option.security.legacy.3=≥ 1 major issue
+projects.facets.rating_option.security.legacy.4=≥ 1 critical issue
+projects.facets.rating_option.security.legacy.5=≥ 1 blocker issue
+projects.facets.rating_option.security.1=≥ 0 info issues
projects.facets.rating_option.security.2=≥ 1 low issue
projects.facets.rating_option.security.3=≥ 1 medium issue
projects.facets.rating_option.security.4=≥ 1 high issue
+projects.facets.rating_option.security.5=≥ 1 blocker issue
projects.facets.rating_option.maintainability.1=≤ 5% to 0%
projects.facets.rating_option.maintainability.2=≥ 5% to <10%
projects.facets.rating_option.maintainability.3=≥ 10% to <20%
-projects.facets.rating_option.maintainability.4=≥ 20%
-projects.facets.rating_option.security_review.1== 100%
-projects.facets.rating_option.security_review.2=≥ 70% to <100%
+projects.facets.rating_option.maintainability.4=≥ 20% to <50%
+projects.facets.rating_option.maintainability.5=≥ 50%
+projects.facets.rating_option.security_review.1=≥ 80%
+projects.facets.rating_option.security_review.2=≥ 70% to <80%
projects.facets.rating_option.security_review.3=≥ 50% to <70%
-projects.facets.rating_option.security_review.4=< 50%
+projects.facets.rating_option.security_review.4=≥ 30% to <50%
+projects.facets.rating_option.security_review.5=< 30%
projects.facets.security_review.description=The percentage of reviewed (fixed or safe) security hotspots
-projects.facets.maintainability.description=Ratio of the size of the project to the estimated time needed to fix all outstanding maintainability issues
+projects.facets.maintainability.description=Ratio of the estimated time needed to fix all outstanding maintainability issues to the size of the project
projects.facets.languages=Languages
projects.facets.search.languages=Search for languages
projects.facets.new_lines=New Lines
@@ -2938,12 +2950,20 @@ 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.
+severity_impact.title=Severity of impact
+severity_impact.levels=Severity levels
+severity_impact.BLOCKER=Blocker
+severity_impact.BLOCKER.description=Must be fixed immediately.
+severity_impact.HIGH=High
+severity_impact.HIGH.description=Must be reviewed immediately and fixed soon.
+severity_impact.MEDIUM=Medium
+severity_impact.MEDIUM.description=High potential for significant to moderate impact.
+severity_impact.LOW=Low
+severity_impact.LOW.description=Potential for moderate to minor impact.
+severity_impact.INFO=Info
+severity_impact.INFO.description=Neither a bug nor a quality flaw. Just a finding.
+severity_impact.help.line1=Severities are now directly tied to the software quality impacted. This means that one software quality impacted has one severity.
+severity_impact.help.line2=There are five levels of severity: blocker, high, medium, low and info.
#------------------------------------------------------------------------------
@@ -3309,9 +3329,6 @@ metric.new_software_quality_security_remediation_effort.extra_short_name=Remedia
metric.new_security_review_rating.description=Security Review Rating on New Code
metric.new_security_review_rating.name=Security Review Rating on New Code
metric.new_security_review_rating.extra_short_name=Rating
-metric.new_software_quality_security_review_rating.description=Security Review Rating on New Code
-metric.new_software_quality_security_review_rating.name=Security Review Rating on New Code
-metric.new_software_quality_security_review_rating.extra_short_name=Rating
metric.new_sqale_debt_ratio.description=Technical Debt Ratio of new/changed code.
metric.new_sqale_debt_ratio.name=Technical Debt Ratio on New Code
metric.new_sqale_debt_ratio.short_name=Debt Ratio on new code
@@ -3413,11 +3430,11 @@ metric.software_quality_releasability_rating.name=Releasability Rating
metric.software_quality_reliability_rating.description=Reliability rating
metric.software_quality_reliability_rating.name=Reliability Rating
metric.software_quality_reliability_rating.extra_short_name=Rating
-metric.software_quality_reliability_rating.tooltip.A=Reliability rating is A when there are no reliability issues.
+metric.software_quality_reliability_rating.tooltip.A=Reliability rating is A when there are no reliability issues above info severity.
metric.software_quality_reliability_rating.tooltip.B=Reliability rating is B when there is at least one low reliability issue.
metric.software_quality_reliability_rating.tooltip.C=Reliability rating is C when there is at least one medium reliability issue.
metric.software_quality_reliability_rating.tooltip.D=Reliability rating is D when there is at least one high reliability issue.
-metric.software_quality_reliability_rating.tooltip.E=Reliability rating is E when there is at least one high reliability issue.
+metric.software_quality_reliability_rating.tooltip.E=Reliability rating is E when there is at least one blocker reliability issue.
metric.reliability_remediation_effort.description=Reliability Remediation Effort
metric.reliability_remediation_effort.name=Reliability Remediation Effort
metric.reliability_remediation_effort.extra_short_name=Remediation Effort
@@ -3452,11 +3469,11 @@ metric.security_rating.tooltip.E=Security rating is E when there is at least one
metric.software_quality_security_rating.description=Security rating
metric.software_quality_security_rating.name=Security Rating
metric.software_quality_security_rating.extra_short_name=Rating
-metric.software_quality_security_rating.tooltip.A=Security rating is A when there are no security issues.
+metric.software_quality_security_rating.tooltip.A=Security rating is A when there are no security issues above info severity.
metric.software_quality_security_rating.tooltip.B=Security rating is B when there is at least one low security issue.
metric.software_quality_security_rating.tooltip.C=Security rating is C when there is at least one medium security issue.
metric.software_quality_security_rating.tooltip.D=Security rating is D when there is at least one high security issue.
-metric.software_quality_security_rating.tooltip.E=Security rating is E when there is at least one high security issue.
+metric.software_quality_security_rating.tooltip.E=Security rating is E when there is at least one blocker security issue.
metric.security_remediation_effort.description=Security remediation effort
metric.security_remediation_effort.name=Security Remediation Effort
metric.security_remediation_effort.extra_short_name=Remediation Effort
@@ -3466,19 +3483,11 @@ metric.software_quality_security_remediation_effort.extra_short_name=Remediation
metric.security_review_rating.description=Security Review Rating
metric.security_review_rating.name=Security Review Rating
metric.security_review_rating.extra_short_name=Rating
-metric.software_quality_security_review_rating.description=Security Review Rating
-metric.software_quality_security_review_rating.name=Security Review Rating
-metric.software_quality_security_review_rating.extra_short_name=Rating
metric.security_review_rating.tooltip.A=Security Review rating is A when at least 80% of Security Hotspots are reviewed.
metric.security_review_rating.tooltip.B=Security Review rating is B when less than 80% of Security Hotspots are reviewed.
metric.security_review_rating.tooltip.C=Security Review rating is C when less than 70% of Security Hotspots are reviewed.
metric.security_review_rating.tooltip.D=Security Review rating is D when less than 50% of Security Hotspots are reviewed.
metric.security_review_rating.tooltip.E=Security Review rating is E when less than 30% of Security Hotspots are reviewed.
-metric.software_quality_security_review_rating.tooltip.A=Security Review rating is A when all Security Hotspots are reviewed.
-metric.software_quality_security_review_rating.tooltip.B=Security Review rating is B when less than 100% of Security Hotspots are reviewed.
-metric.software_quality_security_review_rating.tooltip.C=Security Review rating is C when less than 70% of Security Hotspots are reviewed.
-metric.software_quality_security_review_rating.tooltip.D=Security Review rating is D when less than 50% of Security Hotspots are reviewed.
-metric.software_quality_security_review_rating.tooltip.E=Security Review rating is E when less than 30% of Security Hotspots are reviewed.
metric.skipped_tests.description=Number of skipped unit tests
metric.skipped_tests.name=Skipped Unit Tests
metric.skipped_tests.short_name=Skipped
@@ -4221,7 +4230,7 @@ overview.measures.software_impact.severity.LOW=L
overview.measures.software_impact.severity.LOW.tooltip=Low Impact
overview.measures.software_impact.severity.LOW.improve_tooltip=low
overview.measures.software_impact.improve_rating_tooltip=The {softwareQuality} rating is {ratingLabel} when there is at least one issue with {severity} impact on the {_softwareQuality} of your software.
-overview.measures.software_impact.improve_rating_tooltip.A=The {softwareQuality} rating is {ratingLabel} when there are no issues with impact on the {_softwareQuality} of your software.
+overview.measures.software_impact.improve_rating_tooltip.A=The {softwareQuality} rating is {ratingLabel} when there are no issues above info severity with impact on the {_softwareQuality} of your software.
overview.measures.software_impact.improve_rating_tooltip.MAINTAINABILITY=The Maintainability rating is {ratingLabel} if the code has a relatively higher level of technical debt when compared to the size of the codebase.
overview.measures.software_impact.improve_rating_tooltip.MAINTAINABILITY.A=The Maintainability rating is A if the code has a relatively lower level of technical debt when compared to the size of the codebase.
diff --git a/sonar-core/src/test/java/org/sonar/core/metric/SoftwareQualitiesMetricsTest.java b/sonar-core/src/test/java/org/sonar/core/metric/SoftwareQualitiesMetricsTest.java
index 1f46975d3c4..a230b33a6d5 100644
--- a/sonar-core/src/test/java/org/sonar/core/metric/SoftwareQualitiesMetricsTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/metric/SoftwareQualitiesMetricsTest.java
@@ -34,8 +34,6 @@ class SoftwareQualitiesMetricsTest {
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING,
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING,
- SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REVIEW_RATING,
- SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REVIEW_RATING,
SoftwareQualitiesMetrics.EFFORT_TO_REACH_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_A,
SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT,
SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT,
diff --git a/sonar-core/src/test/java/org/sonar/core/util/ProtobufJsonFormatTest.java b/sonar-core/src/test/java/org/sonar/core/util/ProtobufJsonFormatTest.java
index 6dd4375a170..d5721ebdcb5 100644
--- a/sonar-core/src/test/java/org/sonar/core/util/ProtobufJsonFormatTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/util/ProtobufJsonFormatTest.java
@@ -59,6 +59,21 @@ public class ProtobufJsonFormatTest {
}
@Test
+ public void toJson_whenPrefixedEnum_shouldConvertToExpectedEnumValue() {
+ PrimitiveTypeMsg protobuf = PrimitiveTypeMsg.newBuilder()
+ .setStringField("foo")
+ .setIntField(10)
+ .setLongField(100L)
+ .setDoubleField(3.14)
+ .setBooleanField(true)
+ .setEnumField(org.sonar.core.test.Test.FakeEnum.FakeEnum_YELLOW)
+ .build();
+
+ assertThat(toJson(protobuf)).isEqualTo(
+ "{\"stringField\":\"foo\",\"intField\":10,\"longField\":100,\"doubleField\":3.14,\"booleanField\":true,\"enumField\":\"YELLOW\"}");
+ }
+
+ @Test
public void bytes_field_can_not_be_converted() {
assertThatThrownBy(() -> {
PrimitiveTypeMsg protobuf = PrimitiveTypeMsg.newBuilder()
diff --git a/sonar-core/src/test/protobuf/test.proto b/sonar-core/src/test/protobuf/test.proto
index e81ca6cffbe..46e4ad106ea 100644
--- a/sonar-core/src/test/protobuf/test.proto
+++ b/sonar-core/src/test/protobuf/test.proto
@@ -32,6 +32,7 @@ enum FakeEnum {
BLUE = 0;
RED = 1;
GREEN = 2;
+ FakeEnum_YELLOW = 3;
}
message PrimitiveTypeMsg {
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java
index bdbd28fcdaa..e8ff234901d 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java
@@ -46,6 +46,7 @@ import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.sonar.api.issue.impact.Severity.BLOCKER;
import static org.sonar.api.issue.impact.Severity.HIGH;
import static org.sonar.api.issue.impact.Severity.LOW;
import static org.sonar.api.issue.impact.SoftwareQuality.MAINTAINABILITY;
@@ -109,7 +110,7 @@ public class ExternalIssueImporterTest {
ExternalIssue output = context.allExternalIssues().iterator().next();
assertThat(output.engineId()).isEqualTo(RULE_ENGINE_ID);
assertThat(output.ruleId()).isEqualTo(RULE_ID);
- assertThat(output.severity()).isEqualTo(Severity.CRITICAL); //backmapped
+ assertThat(output.severity()).isEqualTo(Severity.BLOCKER); // backmapped
assertThat(output.type()).isEqualTo(RuleType.VULNERABILITY); //backmapped
assertThat(output.remediationEffort()).isNull();
assertThat(logs.logs(Level.INFO)).contains("Imported 1 issue in 1 file");
@@ -119,10 +120,10 @@ public class ExternalIssueImporterTest {
assertThat(output1.ruleId()).isEqualTo(RULE_ID);
assertThat(output1.name()).isEqualTo(RULE_NAME);
assertThat(output1.engineId()).isEqualTo(RULE_ENGINE_ID);
- assertThat(output1.severity()).isEqualTo(Severity.CRITICAL); //backmapped
+ assertThat(output1.severity()).isEqualTo(Severity.BLOCKER); // backmapped
assertThat(output1.type()).isEqualTo(RuleType.VULNERABILITY); //backmapped
assertThat(output1.cleanCodeAttribute()).isEqualTo(RULE_ATTRIBUTE);
- assertThat(output1.defaultImpacts()).containsExactlyInAnyOrderEntriesOf(Map.of(SECURITY, HIGH, MAINTAINABILITY, LOW));
+ assertThat(output1.defaultImpacts()).containsExactlyInAnyOrderEntriesOf(Map.of(SECURITY, BLOCKER, MAINTAINABILITY, LOW));
}
@Test
@@ -333,7 +334,7 @@ public class ExternalIssueImporterTest {
private static ExternalIssueReport.Rule createRule() {
- return createRule(RULE_ATTRIBUTE.name(), SECURITY.name(), HIGH.name());
+ return createRule(RULE_ATTRIBUTE.name(), SECURITY.name(), BLOCKER.name());
}
private static ExternalIssueReport.Rule createRule(String cleanCodeAttribute, String softwareQuality, String impactSeverity) {
diff --git a/sonar-ws/src/main/protobuf/ws-commons.proto b/sonar-ws/src/main/protobuf/ws-commons.proto
index 7fa09b59828..e999f837afd 100644
--- a/sonar-ws/src/main/protobuf/ws-commons.proto
+++ b/sonar-ws/src/main/protobuf/ws-commons.proto
@@ -121,6 +121,9 @@ enum ImpactSeverity {
LOW = 1;
MEDIUM = 2;
HIGH = 3;
+ // INFO and BLOCKER conflicts with Severity enum, so we use different values prefixed with enum name
+ ImpactSeverity_INFO = 4;
+ ImpactSeverity_BLOCKER = 5;
}
// Lines start at 1 and line offsets start at 0