Browse Source

SONAR-12026 add new hotspots statuses to facet

tags/7.8
Pierre Guillot 5 years ago
parent
commit
023f54edfe

+ 16
- 7
server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java View File

@@ -34,7 +34,6 @@ import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.sonar.api.Startable;
import org.sonar.api.config.Configuration;
import org.sonar.api.issue.Issue;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
import org.sonar.api.server.ws.Change;
@@ -67,6 +66,15 @@ import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toList;
import static org.sonar.api.issue.Issue.RESOLUTIONS;
import static org.sonar.api.issue.Issue.RESOLUTION_FIXED;
import static org.sonar.api.issue.Issue.RESOLUTION_REMOVED;
import static org.sonar.api.issue.Issue.STATUSES;
import static org.sonar.api.issue.Issue.STATUS_IN_REVIEW;
import static org.sonar.api.issue.Issue.STATUS_OPEN;
import static org.sonar.api.issue.Issue.STATUS_REOPENED;
import static org.sonar.api.issue.Issue.STATUS_REVIEWED;
import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW;
import static org.sonar.api.server.ws.WebService.Param.FACETS;
import static org.sonar.api.utils.Paging.forPageIndex;
import static org.sonar.core.util.stream.MoreCollectors.toSet;
@@ -189,6 +197,7 @@ public class SearchAction implements IssuesWsAction, Startable {
PARAM_COMPONENT_KEYS, PARAM_COMPONENT_UUIDS)
.setSince("3.6")
.setChangelog(
new Change("7.8", format("added new Security Hotspots statuses : %s, %s and %s", STATUS_TO_REVIEW, STATUS_IN_REVIEW, STATUS_REVIEWED)),
new Change("7.8", "Security hotspots are returned by default"),
new Change("7.7", format("Value '%s' in parameter '%s' is deprecated, please use '%s' instead", DEPRECATED_PARAM_AUTHORS, FACETS, PARAM_AUTHOR)),
new Change("7.6", format("The use of module keys in parameter '%s' is deprecated", PARAM_COMPONENT_KEYS)),
@@ -229,12 +238,12 @@ public class SearchAction implements IssuesWsAction, Startable {
.setPossibleValues(Severity.ALL);
action.createParam(PARAM_STATUSES)
.setDescription("Comma-separated list of statuses")
.setExampleValue(Issue.STATUS_OPEN + "," + Issue.STATUS_REOPENED)
.setPossibleValues(Issue.STATUSES);
.setExampleValue(STATUS_OPEN + "," + STATUS_REOPENED)
.setPossibleValues(STATUSES);
action.createParam(PARAM_RESOLUTIONS)
.setDescription("Comma-separated list of resolutions")
.setExampleValue(Issue.RESOLUTION_FIXED + "," + Issue.RESOLUTION_REMOVED)
.setPossibleValues(Issue.RESOLUTIONS);
.setExampleValue(RESOLUTION_FIXED + "," + RESOLUTION_REMOVED)
.setPossibleValues(RESOLUTIONS);
action.createParam(PARAM_RESOLVED)
.setDescription("To match resolved or unresolved issues")
.setBooleanPossibleValues();
@@ -453,8 +462,8 @@ public class SearchAction implements IssuesWsAction, Startable {

private void completeFacets(Facets facets, SearchRequest request, IssueQuery query) {
addMandatoryValuesToFacet(facets, PARAM_SEVERITIES, Severity.ALL);
addMandatoryValuesToFacet(facets, PARAM_STATUSES, Issue.STATUSES);
addMandatoryValuesToFacet(facets, PARAM_RESOLUTIONS, concat(singletonList(""), Issue.RESOLUTIONS));
addMandatoryValuesToFacet(facets, PARAM_STATUSES, STATUSES);
addMandatoryValuesToFacet(facets, PARAM_RESOLUTIONS, concat(singletonList(""), RESOLUTIONS));
addMandatoryValuesToFacet(facets, FACET_PROJECTS, query.projectUuids());
addMandatoryValuesToFacet(facets, PARAM_MODULE_UUIDS, query.moduleUuids());
addMandatoryValuesToFacet(facets, PARAM_FILE_UUIDS, query.fileUuids());

+ 15
- 4
server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionFacetsTest.java View File

@@ -19,7 +19,9 @@
*/
package org.sonar.server.issue.ws;

import com.google.common.collect.ImmutableMap;
import java.time.Clock;
import java.util.Map;
import java.util.stream.IntStream;
import org.junit.Rule;
import org.junit.Test;
@@ -112,11 +114,14 @@ public class SearchActionFacetsTest {
.setParam(FACETS, "severities,statuses,resolutions,rules,types,languages,projects,moduleUuids,fileUuids,assignees")
.executeProtobuf(SearchWsResponse.class);

Map<String, Number> expectedStatuses = ImmutableMap.<String, Number>builder().put("OPEN", 1L).put("CONFIRMED", 0L)
.put("REOPENED", 0L).put("RESOLVED", 0L).put("CLOSED", 0L).put("INREVIEW", 0L).put("TOREVIEW", 0L).put("REVIEWED", 0L).build();

assertThat(response.getFacets().getFacetsList())
.extracting(Common.Facet::getProperty, facet -> facet.getValuesList().stream().collect(toMap(FacetValue::getVal, FacetValue::getCount)))
.containsExactlyInAnyOrder(
tuple("severities", of("INFO", 0L, "MINOR", 0L, "MAJOR", 1L, "CRITICAL", 0L, "BLOCKER", 0L)),
tuple("statuses", of("OPEN", 1L, "CONFIRMED", 0L, "REOPENED", 0L, "RESOLVED", 0L, "CLOSED", 0L)),
tuple("statuses", expectedStatuses),
tuple("resolutions", of("", 1L, "FALSE-POSITIVE", 0L, "FIXED", 0L, "REMOVED", 0L, "WONTFIX", 0L)),
tuple("rules", of(rule.getKey().toString(), 1L)),
tuple("types", of("CODE_SMELL", 1L, "BUG", 0L, "VULNERABILITY", 0L, "SECURITY_HOTSPOT", 0L)),
@@ -147,11 +152,14 @@ public class SearchActionFacetsTest {
.setParam("facetMode", FACET_MODE_EFFORT)
.executeProtobuf(SearchWsResponse.class);

Map<String, Number> expectedStatuses = ImmutableMap.<String, Number>builder().put("OPEN", 10L).put("CONFIRMED", 0L)
.put("REOPENED", 0L).put("RESOLVED", 0L).put("CLOSED", 0L).put("INREVIEW", 0L).put("TOREVIEW", 0L).put("REVIEWED", 0L).build();

assertThat(response.getFacets().getFacetsList())
.extracting(Common.Facet::getProperty, facet -> facet.getValuesList().stream().collect(toMap(FacetValue::getVal, FacetValue::getCount)))
.containsExactlyInAnyOrder(
tuple("severities", of("INFO", 0L, "MINOR", 0L, "MAJOR", 10L, "CRITICAL", 0L, "BLOCKER", 0L)),
tuple("statuses", of("OPEN", 10L, "CONFIRMED", 0L, "REOPENED", 0L, "RESOLVED", 0L, "CLOSED", 0L)),
tuple("statuses", expectedStatuses),
tuple("resolutions", of("", 10L, "FALSE-POSITIVE", 0L, "FIXED", 0L, "REMOVED", 0L, "WONTFIX", 0L)),
tuple("rules", of(rule.getKey().toString(), 10L)),
tuple("types", of("CODE_SMELL", 10L, "BUG", 0L, "VULNERABILITY", 0L, "SECURITY_HOTSPOT", 0L)),
@@ -440,7 +448,7 @@ public class SearchActionFacetsTest {
// Assignees contains one additional element : it's the empty string that will return number of unassigned issues
tuple("assignees", 101),
// Following facets returned fixed number of elements
tuple("statuses", 5),
tuple("statuses", 8),
tuple("resolutions", 5),
tuple("severities", 5),
tuple("types", 4));
@@ -498,11 +506,14 @@ public class SearchActionFacetsTest {
.setParam(FACETS, "severities,statuses,resolutions,rules,types,languages,projects,moduleUuids,fileUuids,assignees")
.executeProtobuf(SearchWsResponse.class);

Map<String, Number> expectedStatuses = ImmutableMap.<String, Number>builder().put("OPEN", 1L).put("CONFIRMED", 0L)
.put("REOPENED", 0L).put("RESOLVED", 0L).put("CLOSED", 0L).put("INREVIEW", 0L).put("TOREVIEW", 0L).put("REVIEWED", 0L).build();

assertThat(response.getFacets().getFacetsList())
.extracting(Common.Facet::getProperty, facet -> facet.getValuesList().stream().collect(toMap(FacetValue::getVal, FacetValue::getCount)))
.containsExactlyInAnyOrder(
tuple("severities", of("INFO", 0L, "MINOR", 0L, "MAJOR", 1L, "CRITICAL", 0L, "BLOCKER", 0L)),
tuple("statuses", of("OPEN", 1L, "CONFIRMED", 0L, "REOPENED", 0L, "RESOLVED", 0L, "CLOSED", 0L)),
tuple("statuses", expectedStatuses),
tuple("resolutions", of("", 1L, "FALSE-POSITIVE", 0L, "FIXED", 0L, "REMOVED", 0L, "WONTFIX", 0L)),
tuple("rules", of(rule1.getKey().toString(), 1L, rule2.getKey().toString(), 0L)),
tuple("types", of("CODE_SMELL", 1L, "BUG", 0L, "VULNERABILITY", 0L, "SECURITY_HOTSPOT", 0L)),

+ 4
- 2
sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java View File

@@ -29,6 +29,7 @@ import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.Duration;

import static java.util.Arrays.asList;
import static java.util.Collections.unmodifiableList;

/**
* @since 3.6
@@ -73,7 +74,7 @@ public interface Issue extends Serializable {
*/
String RESOLUTION_WONT_FIX = "WONTFIX";

List<String> RESOLUTIONS = asList(RESOLUTION_FALSE_POSITIVE, RESOLUTION_WONT_FIX, RESOLUTION_FIXED, RESOLUTION_REMOVED);
List<String> RESOLUTIONS = unmodifiableList(asList(RESOLUTION_FALSE_POSITIVE, RESOLUTION_WONT_FIX, RESOLUTION_FIXED, RESOLUTION_REMOVED));

/**
* @since 7.8
@@ -95,7 +96,8 @@ public interface Issue extends Serializable {
*
* @since 4.4
*/
List<String> STATUSES = asList(STATUS_OPEN, STATUS_CONFIRMED, STATUS_REOPENED, STATUS_RESOLVED, STATUS_CLOSED);
List<String> STATUSES = unmodifiableList(asList(STATUS_OPEN, STATUS_CONFIRMED, STATUS_REOPENED, STATUS_RESOLVED, STATUS_CLOSED,
STATUS_TO_REVIEW, STATUS_IN_REVIEW, STATUS_REVIEWED));

/**
* Unique generated key. It looks like "d2de809c-1512-4ae2-9f34-f5345c9f1a13".

Loading…
Cancel
Save