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;
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;
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)),
.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();
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());
*/
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;
.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)),
.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)),
// 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));
.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)),