From 67045c090faf055cea3946b888929f84df52b03d Mon Sep 17 00:00:00 2001 From: Daniel Schwarz Date: Thu, 18 May 2017 16:04:38 +0200 Subject: [PATCH] SONAR-9245 facet new_reliability_rating in search_projects WS --- .../src/test/java/it/Category4Suite.java | 3 - .../src/test/java/it/Category6Suite.java | 4 +- .../it/projectSearch/SearchProjectsTest.java | 174 ++++++++++++--- it/it-tests/src/test/java/util/ItUtils.java | 2 +- .../SearchProjectsTest/with-many-rules.xml | 43 ++++ .../measure/index/ProjectMeasuresIndex.java | 3 + .../ws/SearchProjectsActionTest.java | 201 +++++++++++------- .../index/ProjectMeasuresIndexTest.java | 45 +++- .../client/component/ComponentsService.java | 3 +- .../component/ComponentsServiceTest.java | 5 +- 10 files changed, 369 insertions(+), 114 deletions(-) create mode 100644 it/it-tests/src/test/resources/projectSearch/SearchProjectsTest/with-many-rules.xml diff --git a/it/it-tests/src/test/java/it/Category4Suite.java b/it/it-tests/src/test/java/it/Category4Suite.java index 20fc6409fec..878c8eb846d 100644 --- a/it/it-tests/src/test/java/it/Category4Suite.java +++ b/it/it-tests/src/test/java/it/Category4Suite.java @@ -31,7 +31,6 @@ import it.duplication.DuplicationsTest; import it.duplication.NewDuplicationsTest; import it.projectEvent.EventTest; import it.projectEvent.ProjectActivityPageTest; -import it.projectSearch.SearchProjectsTest; import it.qualityProfile.QualityProfilesPageTest; import it.qualityProfile.QualityProfilesRestoreAndSearchTest; import it.serverSystem.HttpHeadersTest; @@ -85,8 +84,6 @@ import static util.ItUtils.xooPlugin; // project event EventTest.class, ProjectActivityPageTest.class, - // project search - SearchProjectsTest.class, // http HttpHeadersTest.class, // ui diff --git a/it/it-tests/src/test/java/it/Category6Suite.java b/it/it-tests/src/test/java/it/Category6Suite.java index effe0c20cfb..7c17870ee35 100644 --- a/it/it-tests/src/test/java/it/Category6Suite.java +++ b/it/it-tests/src/test/java/it/Category6Suite.java @@ -25,6 +25,7 @@ import it.issue.OrganizationIssueAssignTest; import it.organization.BillingTest; import it.organization.OrganizationMembershipTest; import it.organization.OrganizationTest; +import it.projectSearch.SearchProjectsTest; import it.qualityProfile.OrganizationQualityProfilesPageTest; import it.uiExtension.OrganizationUiExtensionsTest; import it.user.OrganizationIdentityProviderTest; @@ -49,7 +50,8 @@ import static util.ItUtils.xooPlugin; OrganizationTest.class, OrganizationUiExtensionsTest.class, BillingTest.class, - IssueTagsTest.class + IssueTagsTest.class, + SearchProjectsTest.class }) public class Category6Suite { diff --git a/it/it-tests/src/test/java/it/projectSearch/SearchProjectsTest.java b/it/it-tests/src/test/java/it/projectSearch/SearchProjectsTest.java index 619c6b5dc24..3dc6497bb82 100644 --- a/it/it-tests/src/test/java/it/projectSearch/SearchProjectsTest.java +++ b/it/it-tests/src/test/java/it/projectSearch/SearchProjectsTest.java @@ -20,55 +20,74 @@ package it.projectSearch; import com.sonar.orchestrator.Orchestrator; -import it.Category4Suite; +import com.sonar.orchestrator.build.SonarScanner; +import it.Category6Suite; import java.io.IOException; +import org.assertj.core.groups.Tuple; +import org.junit.After; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; -import org.sonarqube.ws.Common.FacetValue; +import org.sonarqube.ws.Common; import org.sonarqube.ws.WsComponents.Component; import org.sonarqube.ws.WsComponents.SearchProjectsWsResponse; import org.sonarqube.ws.client.component.SearchProjectsRequest; +import org.sonarqube.ws.client.organization.CreateWsRequest; +import org.sonarqube.ws.client.project.CreateRequest; +import util.ItUtils; import static com.sonar.orchestrator.build.SonarScanner.create; +import static it.Category6Suite.enableOrganizationsSupport; +import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.groups.Tuple.tuple; +import static util.ItUtils.deleteOrganizationsIfExists; import static util.ItUtils.newAdminWsClient; +import static util.ItUtils.newProjectKey; import static util.ItUtils.projectDir; +import static util.ItUtils.restoreProfile; +import static util.ItUtils.setServerProperty; /** * Tests WS api/components/search_projects */ public class SearchProjectsTest { - private static final String PROJECT_KEY = "sample"; - private static final String PROJECT_NAME = "Sample"; - @ClassRule - public static Orchestrator orchestrator = Category4Suite.ORCHESTRATOR; + public static Orchestrator orchestrator = Category6Suite.ORCHESTRATOR; + + private String organizationKey; + + @BeforeClass + public static void beforeClass() throws Exception { + enableOrganizationsSupport(); + } @Before public void setUp() throws Exception { - orchestrator.resetData(); + organizationKey = ItUtils.newOrganizationKey(); + newAdminWsClient(orchestrator).organizations().create(CreateWsRequest.builder() + .setKey(organizationKey) + .setName(organizationKey) + .build()); + restoreProfile(orchestrator, SearchProjectsTest.class.getResource("/projectSearch/SearchProjectsTest/with-many-rules.xml"), organizationKey); } - @Test - public void filter_projects_by_measure_values() throws Exception { - orchestrator.executeBuild(create(projectDir("shared/xoo-sample"))); - - verifyFilterMatches("ncloc > 1"); - verifyFilterMatches("ncloc > 1 and comment_lines < 10000"); - verifyFilterDoesNotMatch("ncloc <= 1"); + @After + public void tearDown() throws Exception { + deleteOrganizationsIfExists(orchestrator, organizationKey); } @Test - public void provisioned_projects_should_be_included_to_results() throws Exception { - orchestrator.getServer().provisionProject(PROJECT_KEY, PROJECT_NAME); - - SearchProjectsWsResponse response = searchProjects(SearchProjectsRequest.builder().build()); + public void filter_projects_by_measure_values() throws Exception { + String projectKey = newProjectKey(); + analyzeProject(projectKey, "shared/xoo-sample"); - assertThat(response.getComponentsList()).extracting(Component::getKey).containsOnly(PROJECT_KEY); + verifyFilterMatches(projectKey, "ncloc > 1"); + verifyFilterMatches(projectKey, "ncloc > 1 and comment_lines < 10000"); + verifyFilterDoesNotMatch("ncloc <= 1"); } @Test @@ -90,27 +109,130 @@ public class SearchProjectsTest { .extracting(Component::getKey).containsExactly("project3"); assertThat(searchProjects(SearchProjectsRequest.builder().setFilter("query = \"nd\" AND ncloc > 50").build()).getComponentsList()) .extracting(Component::getKey).containsExactly("project3", "project4"); - assertThat(searchProjects(SearchProjectsRequest.builder().setFilter("query = \"unknown\" AND ncloc > 50").build()).getComponentsList()).isEmpty();; + assertThat(searchProjects(SearchProjectsRequest.builder().setFilter("query = \"unknown\" AND ncloc > 50").build()).getComponentsList()).isEmpty(); + ; // Check facets assertThat(searchProjects(SearchProjectsRequest.builder().setFilter("query = \"apache\"").setFacets(singletonList("ncloc")).build()).getFacets().getFacets(0).getValuesList()) - .extracting(FacetValue::getVal, FacetValue::getCount) + .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount) .containsOnly(tuple("*-1000.0", 3L), tuple("1000.0-10000.0", 0L), tuple("10000.0-100000.0", 0L), tuple("100000.0-500000.0", 0L), tuple("500000.0-*", 0L)); assertThat(searchProjects(SearchProjectsRequest.builder().setFilter("query = \"unknown\"").setFacets(singletonList("ncloc")).build()).getFacets().getFacets(0) - .getValuesList()).extracting(FacetValue::getVal, FacetValue::getCount) - .containsOnly(tuple("*-1000.0", 0L), tuple("1000.0-10000.0", 0L), tuple("10000.0-100000.0", 0L), tuple("100000.0-500000.0", 0L), tuple("500000.0-*", 0L)); + .getValuesList()).extracting(Common.FacetValue::getVal, Common.FacetValue::getCount) + .containsOnly(tuple("*-1000.0", 0L), tuple("1000.0-10000.0", 0L), tuple("10000.0-100000.0", 0L), tuple("100000.0-500000.0", 0L), tuple("500000.0-*", 0L)); + } + + @Test + public void provisioned_projects_should_be_included_to_results() throws Exception { + String projectKey = newProjectKey(); + newAdminWsClient(orchestrator).projects().create(CreateRequest.builder().setKey(projectKey).setName(projectKey).setOrganization(organizationKey).build()); + + SearchProjectsWsResponse response = searchProjects(SearchProjectsRequest.builder().setOrganization(organizationKey).build()); + + assertThat(response.getComponentsList()).extracting(Component::getKey).contains(projectKey); + } + + @Test + public void should_return_facets() throws Exception { + analyzeProject(newProjectKey(), "shared/xoo-sample"); + analyzeProject(newProjectKey(), "shared/xoo-multi-modules-sample"); + + SearchProjectsWsResponse response = searchProjects(SearchProjectsRequest.builder().setOrganization(organizationKey).setFacets(asList( + "alert_status", + "coverage", + "duplicated_lines_density", + "languages", + "ncloc", + "reliability_rating", + "security_rating", + "sqale_rating", + "tags")).build()); + + checkFacet(response, "alert_status", + tuple("OK", 2L), + tuple("WARN", 0L), + tuple("ERROR", 0L)); + checkFacet(response, "coverage", + tuple("*-30.0", 0L), + tuple("30.0-50.0", 0L), + tuple("50.0-70.0", 0L), + tuple("70.0-80.0", 0L), + tuple("80.0-*", 0L)); + checkFacet(response, "duplicated_lines_density", + tuple("*-3.0", 2L), + tuple("3.0-5.0", 0L), + tuple("5.0-10.0", 0L), + tuple("10.0-20.0", 0L), + tuple("20.0-*", 0L)); + checkFacet(response, "languages", + tuple("xoo", 2L)); + checkFacet(response, "ncloc", + tuple("*-1000.0", 2L), + tuple("1000.0-10000.0", 0L), + tuple("10000.0-100000.0", 0L), + tuple("100000.0-500000.0", 0L), + tuple("500000.0-*", 0L)); + checkFacet(response, "reliability_rating", + tuple("1", 2L), + tuple("2", 0L), + tuple("3", 0L), + tuple("4", 0L), + tuple("5", 0L)); + checkFacet(response, "security_rating", + tuple("1", 2L), + tuple("2", 0L), + tuple("3", 0L), + tuple("4", 0L), + tuple("5", 0L)); + checkFacet(response, "sqale_rating", + tuple("1", 0L), + tuple("2", 0L), + tuple("3", 0L), + tuple("4", 2L), + tuple("5", 0L)); + checkFacet(response, "tags"); + } + + @Test + public void should_return_facets_on_leak() throws Exception { + setServerProperty(orchestrator, "sonar.leak.period", "previous_analysis"); + String projectKey = newProjectKey(); + analyzeProject(projectKey, "shared/xoo-history-v1"); + analyzeProject(projectKey, "shared/xoo-history-v2"); + + SearchProjectsWsResponse response = searchProjects(SearchProjectsRequest.builder().setOrganization(organizationKey).setFacets(asList( + "new_reliability_rating")).build()); + + checkFacet(response, "new_reliability_rating", + tuple("1", 1L), + tuple("2", 0L), + tuple("3", 0L), + tuple("4", 0L), + tuple("5", 0L)); + } + + private void checkFacet(SearchProjectsWsResponse response, String facetKey, Tuple... values) { + Common.Facet facet = response.getFacets().getFacetsList().stream().filter(f -> f.getProperty().equals(facetKey)).findAny().get(); + assertThat(facet.getValuesList()).extracting(Common.FacetValue::getVal, Common.FacetValue::getCount).containsExactly(values); + } + + private void analyzeProject(String projectKey, String relativePath) { + orchestrator.executeBuild(SonarScanner.create(projectDir(relativePath), + "sonar.projectKey", projectKey, + "sonar.organization", organizationKey, + "sonar.profile", "with-many-rules", + "sonar.login", "admin", "sonar.password", "admin")); } private SearchProjectsWsResponse searchProjects(String filter) throws IOException { - return searchProjects(SearchProjectsRequest.builder().setFilter(filter).build()); + return searchProjects(SearchProjectsRequest.builder().setOrganization(organizationKey).setFilter(filter).build()); } private SearchProjectsWsResponse searchProjects(SearchProjectsRequest request) throws IOException { return newAdminWsClient(orchestrator).components().searchProjects(request); } - private void verifyFilterMatches(String filter) throws IOException { - assertThat(searchProjects(filter).getComponentsList()).extracting(Component::getKey).containsOnly(PROJECT_KEY); + private void verifyFilterMatches(String projectKey, String filter) throws IOException { + assertThat(searchProjects(filter).getComponentsList()).extracting(Component::getKey).containsOnly(projectKey); } private void verifyFilterDoesNotMatch(String filter) throws IOException { diff --git a/it/it-tests/src/test/java/util/ItUtils.java b/it/it-tests/src/test/java/util/ItUtils.java index 367e3a724c8..d3ad26424f6 100644 --- a/it/it-tests/src/test/java/util/ItUtils.java +++ b/it/it-tests/src/test/java/util/ItUtils.java @@ -369,7 +369,7 @@ public class ItUtils { } public static String newProjectKey() { - return "key-" + randomAlphabetic(200); + return "key-" + randomAlphabetic(100); } public static void deleteOrganizationsIfExists(Orchestrator orchestrator, String... organizationKeys) { diff --git a/it/it-tests/src/test/resources/projectSearch/SearchProjectsTest/with-many-rules.xml b/it/it-tests/src/test/resources/projectSearch/SearchProjectsTest/with-many-rules.xml new file mode 100644 index 00000000000..366a3ab7576 --- /dev/null +++ b/it/it-tests/src/test/resources/projectSearch/SearchProjectsTest/with-many-rules.xml @@ -0,0 +1,43 @@ + + with-many-rules + xoo + + + xoo + OneIssuePerLine + MINOR + + + xoo + OneIssuePerFile + MAJOR + + + xoo + OneIssuePerModule + CRITICAL + + + xoo + HasTag + INFO + + + tag + xoo + + + + + common-xoo + InsufficientLineCoverage + BLOCKER + + + minimumLineCoverageRatio + 90 + + + + + diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java b/server/sonar-server/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java index 9fa14bd5785..3e2b76526ea 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java @@ -65,6 +65,7 @@ import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY; import static org.sonar.api.measures.CoreMetrics.COVERAGE_KEY; import static org.sonar.api.measures.CoreMetrics.DUPLICATED_LINES_DENSITY_KEY; import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY; +import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_RATING_KEY; import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING_KEY; import static org.sonar.api.measures.CoreMetrics.SECURITY_RATING_KEY; import static org.sonar.api.measures.CoreMetrics.SQALE_RATING_KEY; @@ -90,6 +91,7 @@ public class ProjectMeasuresIndex { COVERAGE_KEY, SQALE_RATING_KEY, RELIABILITY_RATING_KEY, + NEW_RELIABILITY_RATING_KEY, SECURITY_RATING_KEY, ALERT_STATUS_KEY, FILTER_LANGUAGES, @@ -104,6 +106,7 @@ public class ProjectMeasuresIndex { .put(COVERAGE_KEY, (esSearch, query, facetBuilder) -> addRangeFacet(esSearch, COVERAGE_KEY, facetBuilder, 30d, 50d, 70d, 80d)) .put(SQALE_RATING_KEY, (esSearch, query, facetBuilder) -> addRatingFacet(esSearch, SQALE_RATING_KEY, facetBuilder)) .put(RELIABILITY_RATING_KEY, (esSearch, query, facetBuilder) -> addRatingFacet(esSearch, RELIABILITY_RATING_KEY, facetBuilder)) + .put(NEW_RELIABILITY_RATING_KEY, (esSearch, query, facetBuilder) -> addRatingFacet(esSearch, NEW_RELIABILITY_RATING_KEY, facetBuilder)) .put(SECURITY_RATING_KEY, (esSearch, query, facetBuilder) -> addRatingFacet(esSearch, SECURITY_RATING_KEY, facetBuilder)) .put(ALERT_STATUS_KEY, (esSearch, query, facetBuilder) -> esSearch.addAggregation(createStickyFacet(ALERT_STATUS_KEY, facetBuilder, createQualityGateFacet()))) .put(FILTER_LANGUAGES, ProjectMeasuresIndex::addLanguagesFacet) diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java index 716ab387525..bdbd3b21a8d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java @@ -42,7 +42,6 @@ import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDbTester; import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; import org.sonar.db.organization.OrganizationDto; import org.sonar.db.property.PropertyDto; import org.sonar.server.es.EsTester; @@ -69,6 +68,8 @@ import static java.util.Optional.ofNullable; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; import static org.sonar.api.measures.CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION_KEY; +import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_RATING_KEY; +import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING_KEY; import static org.sonar.api.measures.Metric.ValueType.INT; import static org.sonar.api.measures.Metric.ValueType.LEVEL; import static org.sonar.api.server.ws.WebService.Param.ASCENDING; @@ -158,23 +159,23 @@ public class SearchProjectsActionTest { Param facets = def.param("facets"); assertThat(facets.defaultValue()).isNull(); assertThat(facets.possibleValues()).containsOnly("ncloc", "duplicated_lines_density", "coverage", "sqale_rating", "reliability_rating", "security_rating", "alert_status", - "languages", "tags"); + "languages", "tags", "new_reliability_rating"); } @Test public void json_example() { OrganizationDto organization1Dto = db.organizations().insertForKey("my-org-key-1"); OrganizationDto organization2Dto = db.organizations().insertForKey("my-org-key-2"); - ComponentDto project1 = insertProjectInDbAndEs(ComponentTesting.newPublicProjectDto(organization1Dto) + ComponentDto project1 = insertProjectInDbAndEs(newPublicProjectDto(organization1Dto) .setUuid(Uuids.UUID_EXAMPLE_01) .setKey(KeyExamples.KEY_PROJECT_EXAMPLE_001) .setName("My Project 1") .setTagsString("finance, java")); - insertProjectInDbAndEs(ComponentTesting.newPublicProjectDto(organization1Dto) + insertProjectInDbAndEs(newPublicProjectDto(organization1Dto) .setUuid(Uuids.UUID_EXAMPLE_02) .setKey(KeyExamples.KEY_PROJECT_EXAMPLE_002) .setName("My Project 2")); - insertProjectInDbAndEs(ComponentTesting.newPublicProjectDto(organization2Dto) + insertProjectInDbAndEs(newPublicProjectDto(organization2Dto) .setUuid(Uuids.UUID_EXAMPLE_03) .setKey(KeyExamples.KEY_PROJECT_EXAMPLE_003) .setName("My Project 3") @@ -190,9 +191,9 @@ public class SearchProjectsActionTest { @Test public void order_by_name_case_insensitive() { - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()).setName("Maven")); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()).setName("Apache")); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()).setName("guava")); + insertProjectInDbAndEs(newPrivateProjectDto(db.getDefaultOrganization()).setName("Maven")); + insertProjectInDbAndEs(newPrivateProjectDto(db.getDefaultOrganization()).setName("Apache")); + insertProjectInDbAndEs(newPrivateProjectDto(db.getDefaultOrganization()).setName("guava")); SearchProjectsWsResponse result = call(request); @@ -202,7 +203,7 @@ public class SearchProjectsActionTest { @Test public void paginate_result() { - IntStream.rangeClosed(1, 9).forEach(i -> insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()).setName("PROJECT-" + i))); + IntStream.rangeClosed(1, 9).forEach(i -> insertProjectInDbAndEs(newPrivateProjectDto(db.getDefaultOrganization()).setName("PROJECT-" + i))); SearchProjectsWsResponse result = call(request.setPage(2).setPageSize(3)); @@ -229,7 +230,7 @@ public class SearchProjectsActionTest { @Test public void return_only_projects() { OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto).setName("SonarQube"); + ComponentDto project = newPrivateProjectDto(organizationDto).setName("SonarQube"); ComponentDto directory = newDirectory(project, "path"); insertProjectInDbAndEs(project); componentDb.insertComponents(newModuleDto(project), newView(organizationDto), directory, newFileDto(project, directory)); @@ -243,9 +244,9 @@ public class SearchProjectsActionTest { @Test public void filter_projects_with_query() { OrganizationDto organizationDto = db.organizations().insertForKey("my-org-key-1"); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 10_000d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_001d))); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 10_000d))); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d))); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_001d))); insertMetrics(COVERAGE, NCLOC); request.setFilter("coverage <= 80 and ncloc <= 10000"); @@ -259,9 +260,9 @@ public class SearchProjectsActionTest { public void filter_projects_with_query_within_specified_organization() { OrganizationDto organization1 = db.organizations().insert(); OrganizationDto organization2 = db.organizations().insert(); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization1).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 10_000d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization1).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization2).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_001d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization1).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 10_000d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization1).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization2).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_001d))); insertMetrics(COVERAGE, NCLOC); assertThat(call(request.setOrganization(null)).getComponentsList()) @@ -278,9 +279,9 @@ public class SearchProjectsActionTest { @Test public void filter_projects_by_quality_gate() { OrganizationDto organizationDto = db.organizations().insertForKey("my-org-key-1"); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setName("Sonar Java"), "OK"); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setName("Sonar Markdown"), "OK"); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setName("Sonar Qube"), "ERROR"); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setName("Sonar Java"), "OK"); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setName("Sonar Markdown"), "OK"); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setName("Sonar Qube"), "ERROR"); insertMetrics(COVERAGE, NCLOC); request.setFilter("alert_status = OK"); @@ -292,10 +293,10 @@ public class SearchProjectsActionTest { @Test public void filter_projects_by_languages() { OrganizationDto organizationDto = db.organizations().insertForKey("my-org-key-1"); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81d)), null, asList("", "java", "xoo")); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81)), null, asList("java", "xoo")); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d)), null, asList("xoo")); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d)), null, asList("", "java", "xoo")); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81d)), null, asList("", "java", "xoo")); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81)), null, asList("java", "xoo")); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d)), null, asList("xoo")); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d)), null, asList("", "java", "xoo")); insertMetrics(COVERAGE, NCLOC_LANGUAGE_DISTRIBUTION_KEY); request.setFilter("languages IN (java, js, )"); @@ -307,9 +308,9 @@ public class SearchProjectsActionTest { @Test public void filter_projects_by_tags() { OrganizationDto organizationDto = db.organizations().insertForKey("my-org-key-1"); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setName("Sonar Java").setTags(newArrayList("finance", "platform"))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setName("Sonar Markdown").setTags(singletonList("marketing"))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setName("Sonar Qube").setTags(newArrayList("offshore"))); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setName("Sonar Java").setTags(newArrayList("finance", "platform"))); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setName("Sonar Markdown").setTags(singletonList("marketing"))); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setName("Sonar Qube").setTags(newArrayList("offshore"))); request.setFilter("tags in (finance, offshore)"); SearchProjectsWsResponse result = call(request); @@ -320,10 +321,10 @@ public class SearchProjectsActionTest { @Test public void filter_projects_by_text_query() { OrganizationDto organizationDto = db.organizations().insertForKey("my-org-key-1"); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setKey("sonar-java").setName("Sonar Java")); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setKey("sonar-groovy").setName("Sonar Groovy")); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setKey("sonar-markdown").setName("Sonar Markdown")); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto).setKey("sonarqube").setName("Sonar Qube")); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setKey("sonar-java").setName("Sonar Java")); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setKey("sonar-groovy").setName("Sonar Groovy")); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setKey("sonar-markdown").setName("Sonar Markdown")); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto).setKey("sonarqube").setName("Sonar Qube")); assertThat(call(request.setFilter("query = \"Groovy\"")).getComponentsList()).extracting(Component::getName).containsOnly("Sonar Groovy"); assertThat(call(request.setFilter("query = \"oNar\"")).getComponentsList()).extracting(Component::getName).containsOnly("Sonar Java", "Sonar Groovy", "Sonar Markdown", @@ -340,13 +341,13 @@ public class SearchProjectsActionTest { OrganizationDto organization4 = db.organizations().insert(); OrganizationDto organization5 = db.organizations().insert(); List> someMeasure = singletonList(newMeasure(COVERAGE, 81)); - ComponentDto favourite1_1 = insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization1), someMeasure); - ComponentDto favourite1_2 = insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization1), someMeasure); - ComponentDto nonFavourite1 = insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization1), someMeasure); - ComponentDto favourite2 = insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization2), someMeasure); - ComponentDto nonFavourite2 = insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization2), someMeasure); - ComponentDto favourite3 = insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization3), someMeasure); - ComponentDto nonFavourite4 = insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization4), someMeasure); + ComponentDto favourite1_1 = insertProjectInDbAndEs(newPrivateProjectDto(organization1), someMeasure); + ComponentDto favourite1_2 = insertProjectInDbAndEs(newPrivateProjectDto(organization1), someMeasure); + ComponentDto nonFavourite1 = insertProjectInDbAndEs(newPrivateProjectDto(organization1), someMeasure); + ComponentDto favourite2 = insertProjectInDbAndEs(newPrivateProjectDto(organization2), someMeasure); + ComponentDto nonFavourite2 = insertProjectInDbAndEs(newPrivateProjectDto(organization2), someMeasure); + ComponentDto favourite3 = insertProjectInDbAndEs(newPrivateProjectDto(organization3), someMeasure); + ComponentDto nonFavourite4 = insertProjectInDbAndEs(newPrivateProjectDto(organization4), someMeasure); Stream.of(favourite1_1, favourite1_2, favourite2, favourite3) .forEach(this::addFavourite); insertMetrics(COVERAGE, NCLOC); @@ -387,7 +388,7 @@ public class SearchProjectsActionTest { newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 10_000d))); ComponentDto markDownProject = insertProjectInDbAndEs(newPrivateProjectDto(db.getDefaultOrganization(), "markdown-id").setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(db.organizations().insert()).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_001d))); + insertProjectInDbAndEs(newPrivateProjectDto(db.organizations().insert()).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_001d))); addFavourite(javaProject); addFavourite(markDownProject); dbSession.commit(); @@ -403,7 +404,7 @@ public class SearchProjectsActionTest { public void filtering_on_favorites_returns_empty_results_if_not_logged_in() { ComponentDto javaProject = insertProjectInDbAndEs(newPrivateProjectDto(db.getDefaultOrganization(), "java-id").setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 10_000d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(db.organizations().insert()).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_001d))); + insertProjectInDbAndEs(newPrivateProjectDto(db.organizations().insert()).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_001d))); addFavourite(javaProject); dbSession.commit(); request.setFilter("isFavorite"); @@ -416,7 +417,7 @@ public class SearchProjectsActionTest { @Test public void do_not_return_isFavorite_if_anonymous_user() { - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81))); + insertProjectInDbAndEs(newPrivateProjectDto(db.getDefaultOrganization()).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81))); insertMetrics(COVERAGE); userSession.anonymous(); @@ -428,7 +429,7 @@ public class SearchProjectsActionTest { @Test public void empty_list_if_isFavorite_filter_and_anonymous_user() { - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81))); + insertProjectInDbAndEs(newPrivateProjectDto(db.getDefaultOrganization()).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81))); insertMetrics(COVERAGE); userSession.anonymous(); request.setFilter("isFavorite"); @@ -441,10 +442,10 @@ public class SearchProjectsActionTest { @Test public void return_nloc_facet() { OrganizationDto organization = db.getDefaultOrganization(); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 500_001d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 500_001d))); insertMetrics(COVERAGE, NCLOC); SearchProjectsWsResponse result = call(request.setFacets(singletonList(NCLOC))); @@ -467,10 +468,10 @@ public class SearchProjectsActionTest { @Test public void return_languages_facet() { OrganizationDto organization = db.getDefaultOrganization(); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81d)), null, asList("", "java", "xoo")); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81)), null, asList("java", "xoo")); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d)), null, asList("xoo")); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d)), null, asList("", "java", "xoo")); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81d)), null, asList("", "java", "xoo")); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81)), null, asList("java", "xoo")); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d)), null, asList("xoo")); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d)), null, asList("", "java", "xoo")); insertMetrics(COVERAGE, NCLOC_LANGUAGE_DISTRIBUTION_KEY); SearchProjectsWsResponse result = call(request.setFacets(singletonList(FILTER_LANGUAGES))); @@ -490,8 +491,8 @@ public class SearchProjectsActionTest { @Test public void return_languages_facet_with_language_having_no_project_if_language_is_in_filter() { OrganizationDto organization = db.getDefaultOrganization(); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81d)), null, asList("", "java")); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81)), null, asList("java")); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81d)), null, asList("", "java")); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81)), null, asList("java")); insertMetrics(COVERAGE, NCLOC_LANGUAGE_DISTRIBUTION_KEY); SearchProjectsWsResponse result = call(request.setFilter("languages = xoo").setFacets(singletonList(FILTER_LANGUAGES))); @@ -510,9 +511,9 @@ public class SearchProjectsActionTest { @Test public void return_tags_facet() { OrganizationDto organization = db.getDefaultOrganization(); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Java").setTags(newArrayList("finance", "platform"))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Markdown").setTags(singletonList("offshore"))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Qube").setTags(newArrayList("offshore"))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Java").setTags(newArrayList("finance", "platform"))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Markdown").setTags(singletonList("offshore"))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Qube").setTags(newArrayList("offshore"))); SearchProjectsWsResponse result = call(request.setFacets(singletonList(FILTER_TAGS))); @@ -531,9 +532,9 @@ public class SearchProjectsActionTest { @Test public void return_tags_facet_with_tags_having_no_project_if_tags_is_in_filter() { OrganizationDto organization = db.getDefaultOrganization(); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Java").setTags(newArrayList("finance", "platform"))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Markdown").setTags(singletonList("offshore"))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Qube").setTags(newArrayList("offshore"))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Java").setTags(newArrayList("finance", "platform"))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Markdown").setTags(singletonList("offshore"))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Qube").setTags(newArrayList("offshore"))); SearchProjectsWsResponse result = call(request.setFilter("tags = marketing").setFacets(singletonList(FILTER_TAGS))); @@ -549,13 +550,61 @@ public class SearchProjectsActionTest { tuple("marketing", 0L)); } + @Test + public void return_reliability_rating_facet() throws Exception { + OrganizationDto organization = db.getDefaultOrganization(); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Java"), newArrayList(newMeasure(RELIABILITY_RATING_KEY, 1d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Groovy"), newArrayList(newMeasure(RELIABILITY_RATING_KEY, 1d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Markdown"), newArrayList(newMeasure(RELIABILITY_RATING_KEY, 3d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Qube"), newArrayList(newMeasure(RELIABILITY_RATING_KEY, 5d))); + insertMetrics(RELIABILITY_RATING_KEY); + + SearchProjectsWsResponse result = call(request.setFacets(singletonList(RELIABILITY_RATING_KEY))); + + Common.Facet facet = result.getFacets().getFacetsList().stream() + .filter(oneFacet -> RELIABILITY_RATING_KEY.equals(oneFacet.getProperty())) + .findFirst().orElseThrow(IllegalStateException::new); + assertThat(facet.getValuesList()) + .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount) + .containsExactly( + tuple("1", 2L), + tuple("2", 0L), + tuple("3", 1L), + tuple("4", 0L), + tuple("5", 1L)); + } + + @Test + public void return_new_reliability_rating_facet() throws Exception { + OrganizationDto organization = db.getDefaultOrganization(); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Java"), newArrayList(newMeasure(NEW_RELIABILITY_RATING_KEY, 1d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Groovy"), newArrayList(newMeasure(NEW_RELIABILITY_RATING_KEY, 1d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Markdown"), newArrayList(newMeasure(NEW_RELIABILITY_RATING_KEY, 3d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Qube"), newArrayList(newMeasure(NEW_RELIABILITY_RATING_KEY, 5d))); + insertMetrics(NEW_RELIABILITY_RATING_KEY); + + SearchProjectsWsResponse result = call(request.setFacets(singletonList(NEW_RELIABILITY_RATING_KEY))); + + Common.Facet facet = result.getFacets().getFacetsList().stream() + .filter(oneFacet -> NEW_RELIABILITY_RATING_KEY.equals(oneFacet.getProperty())) + .findFirst().orElseThrow(IllegalStateException::new); + assertThat(facet.getValuesList()) + .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount) + .containsExactly( + tuple("1", 2L), + tuple("2", 0L), + tuple("3", 1L), + tuple("4", 0L), + tuple("5", 1L)); + } + @Test public void default_sort_is_by_ascending_name() throws Exception { OrganizationDto organization = db.getDefaultOrganization(); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 500_001d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 500_001d))); SearchProjectsWsResponse result = call(request); @@ -565,10 +614,10 @@ public class SearchProjectsActionTest { @Test public void sort_by_name() throws Exception { OrganizationDto organization = db.getDefaultOrganization(); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 500_001d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 500_001d))); assertThat(call(request.setSort("name").setAsc(true)).getComponentsList()).extracting(Component::getName) .containsExactly("Sonar Groovy", "Sonar Java", "Sonar Markdown", "Sonar Qube"); @@ -579,10 +628,10 @@ public class SearchProjectsActionTest { @Test public void sort_by_coverage() throws Exception { OrganizationDto organization = db.getDefaultOrganization(); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d))); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 500_001d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d))); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 500_001d))); insertMetrics(COVERAGE); assertThat(call(request.setSort(COVERAGE).setAsc(true)).getComponentsList()).extracting(Component::getName) @@ -594,10 +643,10 @@ public class SearchProjectsActionTest { @Test public void sort_by_quality_gate() throws Exception { OrganizationDto organization = db.getDefaultOrganization(); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Java"), "ERROR"); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Groovy"), "WARN"); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Markdown"), "OK"); - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organization).setName("Sonar Qube"), "OK"); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Java"), "ERROR"); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Groovy"), "WARN"); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Markdown"), "OK"); + insertProjectInDbAndEs(newPrivateProjectDto(organization).setName("Sonar Qube"), "OK"); dbClient.metricDao().insert(dbSession, newMetricDto().setKey(QUALITY_GATE_STATUS).setValueType(LEVEL.name()).setEnabled(true).setHidden(false)); db.commit(); @@ -610,13 +659,13 @@ public class SearchProjectsActionTest { @Test public void return_last_analysis_date() { OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project1 = insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto)); + ComponentDto project1 = insertProjectInDbAndEs(newPrivateProjectDto(organizationDto)); db.components().insertSnapshot(newAnalysis(project1).setCreatedAt(10_000_000_000L).setLast(false)); db.components().insertSnapshot(newAnalysis(project1).setCreatedAt(20_000_000_000L).setLast(true)); - ComponentDto project2 = insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto)); + ComponentDto project2 = insertProjectInDbAndEs(newPrivateProjectDto(organizationDto)); db.components().insertSnapshot(newAnalysis(project2).setCreatedAt(30_000_000_000L).setLast(true)); // No snapshot on project 3 - insertProjectInDbAndEs(ComponentTesting.newPrivateProjectDto(organizationDto)); + insertProjectInDbAndEs(newPrivateProjectDto(organizationDto)); SearchProjectsWsResponse result = call(request.setAdditionalFields(singletonList("analysisDate"))); diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java index 58ad169b97d..2276b5edf5a 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java @@ -69,6 +69,7 @@ public class ProjectMeasuresIndexTest { private static final String MAINTAINABILITY_RATING = "sqale_rating"; private static final String RELIABILITY_RATING = "reliability_rating"; + private static final String NEW_RELIABILITY_RATING = "new_reliability_rating"; private static final String SECURITY_RATING = "security_rating"; private static final String COVERAGE = "coverage"; private static final String DUPLICATION = "duplicated_lines_density"; @@ -870,6 +871,41 @@ public class ProjectMeasuresIndexTest { entry("5", 5L)); } + @Test + public void facet_new_reliability_rating() { + index( + // 3 docs with rating A + newDoc(NEW_RELIABILITY_RATING, 1d), + newDoc(NEW_RELIABILITY_RATING, 1d), + newDoc(NEW_RELIABILITY_RATING, 1d), + // 2 docs with rating B + newDoc(NEW_RELIABILITY_RATING, 2d), + newDoc(NEW_RELIABILITY_RATING, 2d), + // 4 docs with rating C + newDoc(NEW_RELIABILITY_RATING, 3d), + newDoc(NEW_RELIABILITY_RATING, 3d), + newDoc(NEW_RELIABILITY_RATING, 3d), + newDoc(NEW_RELIABILITY_RATING, 3d), + // 2 docs with rating D + newDoc(NEW_RELIABILITY_RATING, 4d), + newDoc(NEW_RELIABILITY_RATING, 4d), + // 5 docs with rating E + newDoc(NEW_RELIABILITY_RATING, 5d), + newDoc(NEW_RELIABILITY_RATING, 5d), + newDoc(NEW_RELIABILITY_RATING, 5d), + newDoc(NEW_RELIABILITY_RATING, 5d), + newDoc(NEW_RELIABILITY_RATING, 5d)); + + Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(NEW_RELIABILITY_RATING)).getFacets(); + + assertThat(facets.get(NEW_RELIABILITY_RATING)).containsExactly( + entry("1", 3L), + entry("2", 2L), + entry("3", 4L), + entry("4", 2L), + entry("5", 5L)); + } + @Test public void facet_security_rating() { index( @@ -1074,8 +1110,7 @@ public class ProjectMeasuresIndexTest { entry("ruby", 1L), entry("scala", 1L), entry("xoo", 1L), - entry("xml", 1L) - ); + entry("xml", 1L)); } @Test @@ -1158,9 +1193,11 @@ public class ProjectMeasuresIndexTest { newDoc().setTags(newArrayList("finance1", "finance2", "finance3", "finance4", "finance5", "finance6", "finance7", "finance8", "finance9", "finance10")), newDoc().setTags(newArrayList("solo", "solo2"))); - Map result = underTest.search(new ProjectMeasuresQuery().setTags(ImmutableSet.of("solo", "solo2")), new SearchOptions().addFacets(FIELD_TAGS)).getFacets().get(FIELD_TAGS); + Map result = underTest.search(new ProjectMeasuresQuery().setTags(ImmutableSet.of("solo", "solo2")), new SearchOptions().addFacets(FIELD_TAGS)).getFacets() + .get(FIELD_TAGS); - assertThat(result).hasSize(12).containsOnlyKeys("finance1", "finance2", "finance3", "finance4", "finance5", "finance6", "finance7", "finance8", "finance9", "finance10", "solo", "solo2"); + assertThat(result).hasSize(12).containsOnlyKeys("finance1", "finance2", "finance3", "finance4", "finance5", "finance6", "finance7", "finance8", "finance9", "finance10", "solo", + "solo2"); } @Test diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java index 202e7eb33ea..005e47d92ed 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java @@ -80,10 +80,11 @@ public class ComponentsService extends BaseService { public SearchProjectsWsResponse searchProjects(SearchProjectsRequest request) { List additionalFields = request.getAdditionalFields(); + List facets = request.getFacets(); GetRequest get = new GetRequest(path(ACTION_SEARCH_PROJECTS)) .setParam(PARAM_ORGANIZATION, request.getOrganization()) .setParam(PARAM_FILTER, request.getFilter()) - .setParam(Param.FACETS, request.getFacets()) + .setParam(Param.FACETS, !facets.isEmpty() ? inlineMultipleParamValue(facets) : null) .setParam(Param.SORT, request.getSort()) .setParam(Param.ASCENDING, request.getAsc()) .setParam(Param.PAGE, request.getPage()) diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/component/ComponentsServiceTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/component/ComponentsServiceTest.java index 1096ae43486..36d6b5d565e 100644 --- a/sonar-ws/src/test/java/org/sonarqube/ws/client/component/ComponentsServiceTest.java +++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/component/ComponentsServiceTest.java @@ -24,6 +24,7 @@ import org.junit.Test; import org.sonarqube.ws.client.ServiceTester; import org.sonarqube.ws.client.WsConnector; +import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.mockito.Mockito.mock; import static org.sonar.api.server.ws.WebService.Param.ASCENDING; @@ -45,7 +46,7 @@ public class ComponentsServiceTest { public void search_projects() { underTest.searchProjects(SearchProjectsRequest.builder() .setFilter("ncloc > 10") - .setFacets(singletonList("ncloc")) + .setFacets(asList("ncloc", "duplicated_lines_density")) .setSort("coverage") .setAsc(true) .setPage(3) @@ -56,7 +57,7 @@ public class ComponentsServiceTest { serviceTester.assertThat(serviceTester.getGetRequest()) .hasPath("search_projects") .hasParam(PARAM_FILTER, "ncloc > 10") - .hasParam(FACETS, singletonList("ncloc")) + .hasParam(FACETS, "ncloc,duplicated_lines_density") .hasParam(SORT, "coverage") .hasParam(ASCENDING, true) .hasParam(PAGE, 3) -- 2.39.5