3 * Copyright (C) 2009-2020 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.server.component.ws;
22 import com.google.common.base.Joiner;
23 import com.tngtech.java.junit.dataprovider.DataProvider;
24 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
25 import com.tngtech.java.junit.dataprovider.UseDataProvider;
26 import java.util.Arrays;
27 import java.util.Date;
28 import java.util.List;
29 import java.util.Optional;
30 import java.util.function.Consumer;
31 import java.util.stream.IntStream;
32 import java.util.stream.Stream;
33 import org.junit.Before;
34 import org.junit.Rule;
35 import org.junit.Test;
36 import org.junit.rules.ExpectedException;
37 import org.junit.runner.RunWith;
38 import org.sonar.api.measures.Metric;
39 import org.sonar.api.resources.Qualifiers;
40 import org.sonar.api.server.ws.WebService;
41 import org.sonar.api.server.ws.WebService.Param;
42 import org.sonar.api.utils.System2;
43 import org.sonar.core.platform.EditionProvider.Edition;
44 import org.sonar.core.platform.PlatformEditionProvider;
45 import org.sonar.db.DbClient;
46 import org.sonar.db.DbSession;
47 import org.sonar.db.DbTester;
48 import org.sonar.db.component.ComponentDto;
49 import org.sonar.db.measure.LiveMeasureDto;
50 import org.sonar.db.metric.MetricDto;
51 import org.sonar.db.organization.OrganizationDto;
52 import org.sonar.db.project.ProjectDto;
53 import org.sonar.db.property.PropertyDto;
54 import org.sonar.server.component.ws.SearchProjectsAction.RequestBuilder;
55 import org.sonar.server.component.ws.SearchProjectsAction.SearchProjectsRequest;
56 import org.sonar.server.es.EsTester;
57 import org.sonar.server.issue.index.IssueIndexSyncProgressChecker;
58 import org.sonar.server.measure.index.ProjectMeasuresIndex;
59 import org.sonar.server.measure.index.ProjectMeasuresIndexer;
60 import org.sonar.server.permission.index.PermissionIndexerTester;
61 import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
62 import org.sonar.server.qualitygate.ProjectsInWarning;
63 import org.sonar.server.tester.UserSessionRule;
64 import org.sonar.server.ws.TestRequest;
65 import org.sonar.server.ws.WsActionTester;
66 import org.sonarqube.ws.Common;
67 import org.sonarqube.ws.Components.Component;
68 import org.sonarqube.ws.Components.SearchProjectsWsResponse;
70 import static java.util.Arrays.asList;
71 import static java.util.Collections.singletonList;
72 import static java.util.Optional.ofNullable;
73 import static org.assertj.core.api.Assertions.assertThat;
74 import static org.assertj.core.api.Assertions.assertThatThrownBy;
75 import static org.assertj.core.api.Assertions.tuple;
76 import static org.mockito.Mockito.mock;
77 import static org.mockito.Mockito.when;
78 import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
79 import static org.sonar.api.measures.CoreMetrics.DUPLICATED_LINES_DENSITY_KEY;
80 import static org.sonar.api.measures.CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION_KEY;
81 import static org.sonar.api.measures.CoreMetrics.NEW_DUPLICATED_LINES_DENSITY_KEY;
82 import static org.sonar.api.measures.CoreMetrics.NEW_LINES_KEY;
83 import static org.sonar.api.measures.CoreMetrics.NEW_MAINTAINABILITY_RATING_KEY;
84 import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_RATING_KEY;
85 import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_RATING_KEY;
86 import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING_KEY;
87 import static org.sonar.api.measures.CoreMetrics.SECURITY_RATING_KEY;
88 import static org.sonar.api.measures.CoreMetrics.SQALE_RATING_KEY;
89 import static org.sonar.api.measures.Metric.ValueType.DATA;
90 import static org.sonar.api.measures.Metric.ValueType.INT;
91 import static org.sonar.api.measures.Metric.ValueType.LEVEL;
92 import static org.sonar.api.server.ws.WebService.Param.ASCENDING;
93 import static org.sonar.api.server.ws.WebService.Param.FACETS;
94 import static org.sonar.api.server.ws.WebService.Param.FIELDS;
95 import static org.sonar.api.server.ws.WebService.Param.PAGE;
96 import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
97 import static org.sonar.api.server.ws.WebService.Param.SORT;
98 import static org.sonar.api.utils.DateUtils.formatDateTime;
99 import static org.sonar.core.util.stream.MoreCollectors.toList;
100 import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
101 import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_002;
102 import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_003;
103 import static org.sonar.test.JsonAssert.assertJson;
104 import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER;
105 import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
106 import static org.sonarqube.ws.client.project.ProjectsWsParameters.FILTER_LANGUAGES;
107 import static org.sonarqube.ws.client.project.ProjectsWsParameters.FILTER_QUALIFIER;
108 import static org.sonarqube.ws.client.project.ProjectsWsParameters.FILTER_TAGS;
110 @RunWith(DataProviderRunner.class)
111 public class SearchProjectsActionTest {
113 private static final String NCLOC = "ncloc";
114 private static final String COVERAGE = "coverage";
115 private static final String NEW_COVERAGE = "new_coverage";
116 private static final String LEAK_PROJECTS_KEY = "leak_projects";
117 private static final String QUALITY_GATE_STATUS = "alert_status";
118 private static final String ANALYSIS_DATE = "analysisDate";
119 private static final String IS_FAVOURITE_CRITERION = "isFavorite";
122 public ExpectedException expectedException = ExpectedException.none();
124 public UserSessionRule userSession = UserSessionRule.standalone();
126 public EsTester es = EsTester.create();
128 public DbTester db = DbTester.create(System2.INSTANCE);
131 public static Object[][] rating_metric_keys() {
132 return new Object[][] {{SQALE_RATING_KEY}, {RELIABILITY_RATING_KEY}, {SECURITY_RATING_KEY}};
136 public static Object[][] new_rating_metric_keys() {
137 return new Object[][] {{NEW_MAINTAINABILITY_RATING_KEY}, {NEW_RELIABILITY_RATING_KEY}, {NEW_SECURITY_RATING_KEY}};
141 public static Object[][] component_qualifiers_for_valid_editions() {
142 return new Object[][] {
143 {new String[] {Qualifiers.PROJECT}, Edition.COMMUNITY},
144 {new String[] {Qualifiers.PROJECT}, Edition.DEVELOPER},
145 {new String[] {Qualifiers.APP, Qualifiers.PROJECT}, Edition.ENTERPRISE},
146 {new String[] {Qualifiers.APP, Qualifiers.PROJECT}, Edition.DATACENTER},
151 public static Object[][] community_or_developer_edition() {
152 return new Object[][] {
159 public static Object[][] enterprise_or_datacenter_edition() {
160 return new Object[][] {
161 {Edition.ENTERPRISE},
162 {Edition.DATACENTER},
166 private DbClient dbClient = db.getDbClient();
167 private DbSession dbSession = db.getSession();
169 private PlatformEditionProvider editionProviderMock = mock(PlatformEditionProvider.class);
170 private PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(es, new ProjectMeasuresIndexer(dbClient, es.client()));
171 private ProjectMeasuresIndex index = new ProjectMeasuresIndex(es.client(), new WebAuthorizationTypeSupport(userSession), System2.INSTANCE);
172 private ProjectMeasuresIndexer projectMeasuresIndexer = new ProjectMeasuresIndexer(db.getDbClient(), es.client());
173 private ProjectsInWarning projectsInWarning = new ProjectsInWarning();
175 private WsActionTester ws = new WsActionTester(new SearchProjectsAction(dbClient, index, userSession, projectsInWarning, editionProviderMock,
176 new IssueIndexSyncProgressChecker(db.getDbClient())));
178 private RequestBuilder request = SearchProjectsRequest.builder();
181 public void setUp() {
182 projectsInWarning.update(0L);
186 public void verify_definition() {
187 WebService.Action def = ws.getDef();
189 assertThat(def.key()).isEqualTo("search_projects");
190 assertThat(def.since()).isEqualTo("6.2");
191 assertThat(def.isInternal()).isTrue();
192 assertThat(def.isPost()).isFalse();
193 assertThat(def.responseExampleAsString()).isNotEmpty();
194 assertThat(def.params().stream().map(Param::key).collect(toList())).containsOnly("organization", "filter", "facets", "s", "asc", "ps", "p", "f");
195 assertThat(def.changelog()).hasSize(2);
197 Param organization = def.param("organization");
198 assertThat(organization.isRequired()).isFalse();
199 assertThat(organization.description()).isEqualTo("the organization to search projects in");
200 assertThat(organization.since()).isEqualTo("6.3");
202 Param sort = def.param("s");
203 assertThat(sort.defaultValue()).isEqualTo("name");
204 assertThat(sort.possibleValues()).containsExactlyInAnyOrder(
206 "reliability_rating",
207 "duplicated_lines_density",
208 "ncloc_language_distribution",
212 "security_review_rating",
213 "new_security_review_rating",
214 "security_hotspots_reviewed",
215 "new_security_hotspots_reviewed",
216 "new_reliability_rating",
218 "new_security_rating",
220 "new_duplicated_lines_density",
223 "new_maintainability_rating",
227 Param asc = def.param("asc");
228 assertThat(asc.defaultValue()).isEqualTo("true");
229 assertThat(asc.possibleValues()).containsOnly("true", "false", "yes", "no");
231 Param f = def.param("f");
232 assertThat(f.defaultValue()).isNull();
233 assertThat(f.possibleValues()).containsOnly("_all", "organizations", "analysisDate", "leakPeriodDate");
235 Param facets = def.param("facets");
236 assertThat(facets.defaultValue()).isNull();
237 assertThat(facets.possibleValues()).containsOnly("ncloc", "duplicated_lines_density", "coverage", "sqale_rating", "reliability_rating", "security_rating", "alert_status",
238 "languages", "tags", "qualifier", "new_reliability_rating", "new_security_rating", "new_maintainability_rating", "new_coverage", "new_duplicated_lines_density", "new_lines",
239 "security_review_rating", "security_hotspots_reviewed", "new_security_hotspots_reviewed", "new_security_review_rating");
243 public void json_example() {
245 OrganizationDto organization1Dto = db.organizations().insert(dto -> dto.setKey("my-org-key-1").setName("Foo"));
246 OrganizationDto organization2Dto = db.organizations().insert(dto -> dto.setKey("my-org-key-2").setName("Bar"));
248 MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType("PERCENT"));
249 ComponentDto project1 = insertProject(organization1Dto,
250 c -> c.setDbKey(KEY_PROJECT_EXAMPLE_001).setName("My Project 1"),
251 p -> p.setTagsString("finance, java"),
252 new Measure(coverage, c -> c.setValue(80d)));
254 db.components().insertProjectBranch(db.components().getProjectDto(project1), branchDto -> branchDto.setNeedIssueSync(true));
256 ComponentDto project2 = insertProject(organization1Dto,
257 c -> c.setDbKey(KEY_PROJECT_EXAMPLE_002).setName("My Project 2"),
258 new Measure(coverage, c -> c.setValue(90d)));
259 ComponentDto project3 = insertProject(organization2Dto,
260 c -> c.setDbKey(KEY_PROJECT_EXAMPLE_003).setName("My Project 3"),
261 p -> p.setTagsString("sales, offshore, java"),
262 new Measure(coverage, c -> c.setValue(20d)));
263 addFavourite(project1);
265 String jsonResult = ws.newRequest()
266 .setParam(FACETS, COVERAGE)
267 .setParam(FIELDS, "_all")
268 .execute().getInput();
270 assertJson(jsonResult).ignoreFields("id").isSimilarTo(ws.getDef().responseExampleAsString());
271 assertJson(ws.getDef().responseExampleAsString()).ignoreFields("id").isSimilarTo(jsonResult);
273 SearchProjectsWsResponse protobufResult = ws.newRequest()
274 .setParam(FACETS, COVERAGE)
275 .executeProtobuf(SearchProjectsWsResponse.class);
277 assertThat(protobufResult.getComponentsList()).extracting(Component::getKey)
278 .containsExactly(project1.getDbKey(), project2.getDbKey(), project3.getDbKey());
282 public void order_by_name_case_insensitive() {
284 OrganizationDto organization = db.organizations().insert();
285 insertProject(organization, c -> c.setName("Maven"));
286 insertProject(organization, c -> c.setName("Apache"));
287 insertProject(organization, c -> c.setName("guava"));
289 SearchProjectsWsResponse result = call(request);
291 assertThat(result.getComponentsList()).extracting(Component::getName)
292 .containsExactly("Apache", "guava", "Maven");
296 public void paginate_result() {
298 OrganizationDto organization = db.organizations().insert();
299 IntStream.rangeClosed(1, 9).forEach(i -> insertProject(organization, c -> c.setName("PROJECT-" + i)));
301 SearchProjectsWsResponse result = call(request.setPage(2).setPageSize(3));
303 assertThat(result.getPaging().getPageIndex()).isEqualTo(2);
304 assertThat(result.getPaging().getPageSize()).isEqualTo(3);
305 assertThat(result.getPaging().getTotal()).isEqualTo(9);
306 assertThat(result.getComponentsCount()).isEqualTo(3);
307 assertThat(result.getComponentsList())
308 .extracting(Component::getName)
309 .containsExactly("PROJECT-4", "PROJECT-5", "PROJECT-6");
313 public void empty_result() {
316 SearchProjectsWsResponse result = call(request);
318 assertThat(result.getComponentsCount()).isEqualTo(0);
319 Common.Paging paging = result.getPaging();
320 assertThat(paging.getPageIndex()).isEqualTo(1);
321 assertThat(paging.getPageSize()).isEqualTo(100);
322 assertThat(paging.getTotal()).isEqualTo(0);
326 public void filter_projects_with_query() {
328 OrganizationDto organizationDto = db.organizations().insert();
329 MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType(INT.name()));
330 MetricDto ncloc = db.measures().insertMetric(c -> c.setKey(NCLOC).setValueType(INT.name()));
331 ComponentDto project1 = insertProject(organizationDto,
332 new Measure(coverage, c -> c.setValue(81d)),
333 new Measure(ncloc, c -> c.setValue(10_000d)));
334 ComponentDto project2 = insertProject(organizationDto,
335 new Measure(coverage, c -> c.setValue(80d)),
336 new Measure(ncloc, c -> c.setValue(10_000d)));
337 ComponentDto project3 = insertProject(organizationDto,
338 new Measure(coverage, c -> c.setValue(80d)),
339 new Measure(ncloc, c -> c.setValue(10_001d)));
341 SearchProjectsWsResponse result = call(request.setFilter("coverage <= 80 and ncloc <= 10000"));
343 assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactly(project2.getDbKey());
347 public void filter_projects_with_query_within_specified_organization() {
349 OrganizationDto organization1 = db.organizations().insert();
350 OrganizationDto organization2 = db.organizations().insert();
351 MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType("PERCENT"));
352 MetricDto ncloc = db.measures().insertMetric(c -> c.setKey(NCLOC).setValueType(INT.name()));
353 ComponentDto project1 = insertProject(organization1, new Measure(coverage, c -> c.setValue(81d)), new Measure(ncloc, c -> c.setValue(10_000d)));
354 ComponentDto project2 = insertProject(organization1, new Measure(coverage, c -> c.setValue(80d)), new Measure(ncloc, c -> c.setValue(10_000d)));
355 ComponentDto project3 = insertProject(organization2, new Measure(coverage, c -> c.setValue(80d)), new Measure(ncloc, c -> c.setValue(10_000d)));
357 assertThat(call(request.setOrganization(null)).getComponentsList())
358 .extracting(Component::getKey)
359 .containsOnly(project1.getDbKey(), project2.getDbKey(), project3.getDbKey());
360 assertThat(call(request.setOrganization(organization1.getKey())).getComponentsList())
361 .extracting(Component::getKey)
362 .containsOnly(project1.getDbKey(), project2.getDbKey());
363 assertThat(call(request.setOrganization(organization2.getKey())).getComponentsList())
364 .extracting(Component::getKey)
365 .containsOnly(project3.getDbKey());
369 public void filter_projects_by_quality_gate() {
371 OrganizationDto organizationDto = db.organizations().insert();
372 MetricDto qualityGateStatus = db.measures().insertMetric(c -> c.setKey(QUALITY_GATE_STATUS).setValueType(LEVEL.name()));
373 ComponentDto project1 = insertProject(organizationDto, new Measure(qualityGateStatus, c -> c.setValue(null).setData("OK")));
374 ComponentDto project2 = insertProject(organizationDto, new Measure(qualityGateStatus, c -> c.setValue(null).setData("OK")));
375 ComponentDto project3 = insertProject(organizationDto, new Measure(qualityGateStatus, c -> c.setValue(null).setData("ERROR")));
377 SearchProjectsWsResponse result = call(request.setFilter("alert_status = OK"));
379 assertThat(result.getComponentsList())
380 .extracting(Component::getKey)
381 .containsExactlyInAnyOrder(project1.getDbKey(), project2.getDbKey());
385 public void filter_projects_by_languages() {
387 OrganizationDto organizationDto = db.organizations().insert();
388 MetricDto languagesDistribution = db.measures().insertMetric(c -> c.setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY).setValueType("DATA"));
389 ComponentDto project1 = insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("<null>=2;java=6;xoo=18")));
390 ComponentDto project2 = insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("java=3;xoo=9")));
391 ComponentDto project3 = insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("xoo=1")));
392 ComponentDto project4 = insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("<null>=1;java=5;xoo=13")));
394 SearchProjectsWsResponse result = call(request.setFilter("languages IN (java, js, <null>)"));
396 assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactlyInAnyOrder(project1.getDbKey(), project2.getDbKey(), project4.getDbKey());
400 @UseDataProvider("rating_metric_keys")
401 public void filter_projects_by_rating(String metricKey) {
403 OrganizationDto organizationDto = db.organizations().insert();
404 MetricDto ratingMetric = db.measures().insertMetric(c -> c.setKey(metricKey).setValueType(INT.name()));
405 ComponentDto project1 = insertProject(organizationDto, new Measure(ratingMetric, c -> c.setValue(1d)));
406 ComponentDto project2 = insertProject(organizationDto, new Measure(ratingMetric, c -> c.setValue(2d)));
407 ComponentDto project3 = insertProject(organizationDto, new Measure(ratingMetric, c -> c.setValue(3d)));
409 SearchProjectsWsResponse result = call(request.setFilter(metricKey + " = 2"));
411 assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactly(project2.getDbKey());
415 @UseDataProvider("new_rating_metric_keys")
416 public void filter_projects_by_new_rating(String newMetricKey) {
418 OrganizationDto organizationDto = db.organizations().insert();
419 MetricDto ratingMetric = db.measures().insertMetric(c -> c.setKey(newMetricKey).setValueType(INT.name()));
420 insertProject(organizationDto, new Measure(ratingMetric, c -> c.setVariation(1d)));
421 ComponentDto project2 = insertProject(organizationDto, new Measure(ratingMetric, c -> c.setVariation(2d)));
422 insertProject(organizationDto, new Measure(ratingMetric, c -> c.setVariation(3d)));
424 SearchProjectsWsResponse result = call(request.setFilter(newMetricKey + " = 2"));
426 assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactly(project2.getDbKey());
430 public void filter_projects_by_tags() {
432 OrganizationDto organizationDto = db.organizations().insert();
433 ComponentDto project1 = insertProject(organizationDto, defaults(), p -> p.setTags(asList("finance", "platform")));
434 insertProject(organizationDto, defaults(), p -> p.setTags(singletonList("marketing")));
435 ComponentDto project3 = insertProject(organizationDto, defaults(), p -> p.setTags(singletonList("offshore")));
437 SearchProjectsWsResponse result = call(request.setFilter("tags in (finance, offshore)"));
439 assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactlyInAnyOrder(project1.getDbKey(), project3.getDbKey());
443 public void filter_projects_by_coverage() {
445 OrganizationDto organizationDto = db.organizations().insert();
446 MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType("PERCENT"));
447 ComponentDto project1 = insertProject(organizationDto, new Measure(coverage, c -> c.setValue(80d)));
448 ComponentDto project2 = insertProject(organizationDto, new Measure(coverage, c -> c.setValue(85d)));
449 ComponentDto project3 = insertProject(organizationDto, new Measure(coverage, c -> c.setValue(10d)));
451 SearchProjectsWsResponse result = call(request.setFilter("coverage <= 80"));
453 assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactlyInAnyOrder(project1.getDbKey(), project3.getDbKey());
457 public void filter_projects_by_new_coverage() {
459 OrganizationDto organizationDto = db.organizations().insert();
460 MetricDto coverage = db.measures().insertMetric(c -> c.setKey(NEW_COVERAGE).setValueType("PERCENT"));
461 ComponentDto project1 = insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(80d)));
462 ComponentDto project2 = insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(85d)));
463 ComponentDto project3 = insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(10d)));
465 SearchProjectsWsResponse result = call(request.setFilter("new_coverage <= 80"));
467 assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactlyInAnyOrder(project1.getDbKey(), project3.getDbKey());
471 public void filter_projects_by_duplications() {
473 OrganizationDto organizationDto = db.organizations().insert();
474 MetricDto duplications = db.measures().insertMetric(c -> c.setKey(DUPLICATED_LINES_DENSITY_KEY).setValueType("PERCENT"));
475 ComponentDto project1 = insertProject(organizationDto, new Measure(duplications, c -> c.setValue(80d)));
476 ComponentDto project2 = insertProject(organizationDto, new Measure(duplications, c -> c.setValue(85d)));
477 ComponentDto project3 = insertProject(organizationDto, new Measure(duplications, c -> c.setValue(10d)));
479 SearchProjectsWsResponse result = call(request.setFilter("duplicated_lines_density <= 80"));
481 assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactlyInAnyOrder(project1.getDbKey(), project3.getDbKey());
485 public void filter_projects_by_no_duplication() {
487 OrganizationDto organizationDto = db.organizations().insert();
488 MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType("PERCENT"));
489 MetricDto duplications = db.measures().insertMetric(c -> c.setKey(DUPLICATED_LINES_DENSITY_KEY).setValueType("PERCENT"));
490 ComponentDto project1 = insertProject(organizationDto, new Measure(coverage, c -> c.setValue(10d)));
491 ComponentDto project2 = insertProject(organizationDto, new Measure(duplications, c -> c.setValue(0d)));
492 ComponentDto project3 = insertProject(organizationDto, new Measure(duplications, c -> c.setValue(79d)));
494 SearchProjectsWsResponse result = call(request.setFilter("duplicated_lines_density = NO_DATA"));
496 assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactlyInAnyOrder(project1.getDbKey());
500 public void filter_projects_by_no_duplication_should_not_return_projects_with_duplication() {
502 OrganizationDto organizationDto = db.organizations().insert();
503 MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType("PERCENT"));
504 MetricDto duplications = db.measures().insertMetric(c -> c.setKey(DUPLICATED_LINES_DENSITY_KEY).setValueType("PERCENT"));
505 insertProject(organizationDto, new Measure(duplications, c -> c.setValue(10d)), new Measure(coverage, c -> c.setValue(50d)));
507 SearchProjectsWsResponse result = call(request.setFilter("duplicated_lines_density = NO_DATA"));
509 assertThat(result.getComponentsList()).extracting(Component::getKey).isEmpty();
513 public void filter_projects_by_new_duplications() {
515 OrganizationDto organizationDto = db.organizations().insert();
516 MetricDto newDuplications = db.measures().insertMetric(c -> c.setKey(NEW_DUPLICATED_LINES_DENSITY_KEY).setValueType("PERCENT"));
517 ComponentDto project1 = insertProject(organizationDto, new Measure(newDuplications, c -> c.setVariation(80d)));
518 ComponentDto project2 = insertProject(organizationDto, new Measure(newDuplications, c -> c.setVariation(85d)));
519 ComponentDto project3 = insertProject(organizationDto, new Measure(newDuplications, c -> c.setVariation(10d)));
521 SearchProjectsWsResponse result = call(request.setFilter("new_duplicated_lines_density <= 80"));
523 assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactlyInAnyOrder(project1.getDbKey(), project3.getDbKey());
527 public void filter_projects_by_ncloc() {
529 OrganizationDto organizationDto = db.organizations().insert();
530 MetricDto ncloc = db.measures().insertMetric(c -> c.setKey(NCLOC).setValueType(INT.name()));
531 ComponentDto project1 = insertProject(organizationDto, new Measure(ncloc, c -> c.setValue(80d)));
532 ComponentDto project2 = insertProject(organizationDto, new Measure(ncloc, c -> c.setValue(85d)));
533 ComponentDto project3 = insertProject(organizationDto, new Measure(ncloc, c -> c.setValue(10d)));
535 SearchProjectsWsResponse result = call(request.setFilter("ncloc <= 80"));
537 assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactlyInAnyOrder(project1.getDbKey(), project3.getDbKey());
541 public void filter_projects_by_new_lines() {
543 OrganizationDto organizationDto = db.organizations().insert();
544 MetricDto newLines = db.measures().insertMetric(c -> c.setKey(NEW_LINES_KEY).setValueType(INT.name()));
545 ComponentDto project1 = insertProject(organizationDto, new Measure(newLines, c -> c.setVariation(80d)));
546 ComponentDto project2 = insertProject(organizationDto, new Measure(newLines, c -> c.setVariation(85d)));
547 ComponentDto project3 = insertProject(organizationDto, new Measure(newLines, c -> c.setVariation(10d)));
549 SearchProjectsWsResponse result = call(request.setFilter("new_lines <= 80"));
551 assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactlyInAnyOrder(project1.getDbKey(), project3.getDbKey());
555 public void filter_projects_by_text_query() {
557 OrganizationDto organizationDto = db.organizations().insert();
558 insertProject(organizationDto, c -> c.setDbKey("sonar-java").setName("Sonar Java"));
559 insertProject(organizationDto, c -> c.setDbKey("sonar-groovy").setName("Sonar Groovy"));
560 insertProject(organizationDto, c -> c.setDbKey("sonar-markdown").setName("Sonar Markdown"));
561 insertProject(organizationDto, c -> c.setDbKey("sonarqube").setName("Sonar Qube"));
563 assertThat(call(request.setFilter("query = \"Groovy\"")).getComponentsList()).extracting(Component::getName).containsOnly("Sonar Groovy");
564 assertThat(call(request.setFilter("query = \"oNar\"")).getComponentsList()).extracting(Component::getName).containsOnly("Sonar Java", "Sonar Groovy", "Sonar Markdown",
566 assertThat(call(request.setFilter("query = \"sonar-java\"")).getComponentsList()).extracting(Component::getName).containsOnly("Sonar Java");
570 public void filter_favourite_projects_with_query_with_or_without_a_specified_organization() {
572 OrganizationDto organization1 = db.organizations().insert();
573 OrganizationDto organization2 = db.organizations().insert();
574 OrganizationDto organization3 = db.organizations().insert();
575 OrganizationDto organization4 = db.organizations().insert();
576 OrganizationDto organization5 = db.organizations().insert();
577 ComponentDto favourite1_1 = insertProject(organization1);
578 ComponentDto favourite1_2 = insertProject(organization1);
579 ComponentDto nonFavourite1 = insertProject(organization1);
580 ComponentDto favourite2 = insertProject(organization2);
581 ComponentDto nonFavourite2 = insertProject(organization2);
582 ComponentDto favourite3 = insertProject(organization3);
583 ComponentDto nonFavourite4 = insertProject(organization4);
584 Stream.of(favourite1_1, favourite1_2, favourite2, favourite3).forEach(this::addFavourite);
586 assertThat(call(request.setFilter(null).setOrganization(null)).getComponentsList())
587 .extracting(Component::getName)
588 .containsOnly(favourite1_1.name(), favourite1_2.name(), nonFavourite1.name(), favourite2.name(), nonFavourite2.name(), favourite3.name(), nonFavourite4.name());
589 assertThat(call(request.setFilter(IS_FAVOURITE_CRITERION).setOrganization(null)).getComponentsList())
590 .extracting(Component::getName)
591 .containsOnly(favourite1_1.name(), favourite1_2.name(), favourite2.name(), favourite3.name());
592 assertThat(call(request.setFilter(null).setOrganization(organization1.getKey())).getComponentsList())
593 .extracting(Component::getName)
594 .containsOnly(favourite1_1.name(), favourite1_2.name(), nonFavourite1.name());
595 assertThat(call(request.setFilter(IS_FAVOURITE_CRITERION).setOrganization(organization1.getKey())).getComponentsList())
596 .extracting(Component::getName)
597 .containsOnly(favourite1_1.name(), favourite1_2.name());
598 assertThat(call(request.setFilter(null).setOrganization(organization3.getKey())).getComponentsList())
599 .extracting(Component::getName)
600 .containsOnly(favourite3.name());
601 assertThat(call(request.setFilter(IS_FAVOURITE_CRITERION).setOrganization(organization3.getKey())).getComponentsList())
602 .extracting(Component::getName)
603 .containsOnly(favourite3.name());
604 assertThat(call(request.setFilter(null).setOrganization(organization4.getKey())).getComponentsList())
605 .extracting(Component::getName)
606 .containsOnly(nonFavourite4.name());
607 assertThat(call(request.setFilter(IS_FAVOURITE_CRITERION).setOrganization(organization4.getKey())).getComponentsList())
609 assertThat(call(request.setFilter(null).setOrganization(organization5.getKey())).getComponentsList())
611 assertThat(call(request.setFilter(IS_FAVOURITE_CRITERION).setOrganization(organization5.getKey())).getComponentsList())
616 public void filter_projects_on_favorites() {
618 OrganizationDto organization = db.organizations().insert();
619 ComponentDto javaProject = insertProject(organization);
620 ComponentDto markDownProject = insertProject(organization);
621 ComponentDto sonarQubeProject = insertProject(organization);
622 Stream.of(javaProject, markDownProject).forEach(this::addFavourite);
624 SearchProjectsWsResponse result = call(request.setFilter("isFavorite"));
626 assertThat(result.getComponentsCount()).isEqualTo(2);
627 assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactly(javaProject.getDbKey(), markDownProject.getDbKey());
631 public void filtering_on_favorites_returns_empty_results_if_not_logged_in() {
632 userSession.anonymous();
633 OrganizationDto organization = db.organizations().insert();
634 ComponentDto javaProject = insertProject(organization);
635 ComponentDto markDownProject = insertProject(organization);
636 ComponentDto sonarQubeProject = insertProject(organization);
637 Stream.of(javaProject, markDownProject).forEach(this::addFavourite);
639 SearchProjectsWsResponse result = call(request.setFilter("isFavorite"));
641 assertThat(result.getComponentsCount()).isZero();
645 @UseDataProvider("component_qualifiers_for_valid_editions")
646 public void default_filter_projects_and_apps_by_editions(String[] qualifiers, Edition edition) {
647 when(editionProviderMock.get()).thenReturn(Optional.of(edition));
649 OrganizationDto organization = db.organizations().insert();
650 ComponentDto portfolio1 = insertPortfolio(organization);
651 ComponentDto portfolio2 = insertPortfolio(organization);
653 ComponentDto application1 = insertApplication(organization);
654 ComponentDto application2 = insertApplication(organization);
655 ComponentDto application3 = insertApplication(organization);
657 ComponentDto project1 = insertProject(organization);
658 ComponentDto project2 = insertProject(organization);
659 ComponentDto project3 = insertProject(organization);
661 SearchProjectsWsResponse result = call(request);
663 assertThat(result.getComponentsCount()).isEqualTo(
664 Stream.of(application1, application2, application3, project1, project2, project3)
665 .filter(c -> Stream.of(qualifiers).anyMatch(s -> s.equals(c.qualifier())))
668 assertThat(result.getComponentsList()).extracting(Component::getKey)
670 Stream.of(application1, application2, application3, project1, project2, project3)
671 .filter(c -> Stream.of(qualifiers).anyMatch(s -> s.equals(c.qualifier())))
672 .map(ComponentDto::getDbKey)
673 .toArray(String[]::new));
677 public void should_return_projects_only_when_no_edition() {
678 when(editionProviderMock.get()).thenReturn(Optional.empty());
680 OrganizationDto organization = db.organizations().insert();
682 ComponentDto portfolio1 = insertPortfolio(organization);
683 ComponentDto portfolio2 = insertPortfolio(organization);
685 insertApplication(organization);
686 insertApplication(organization);
687 insertApplication(organization);
689 ComponentDto project1 = insertProject(organization);
690 ComponentDto project2 = insertProject(organization);
691 ComponentDto project3 = insertProject(organization);
693 SearchProjectsWsResponse result = call(request);
695 assertThat(result.getComponentsCount()).isEqualTo(3);
697 assertThat(result.getComponentsList()).extracting(Component::getKey)
698 .containsExactly(Stream.of(project1, project2, project3).map(ComponentDto::getDbKey).toArray(String[]::new));
702 @UseDataProvider("enterprise_or_datacenter_edition")
703 public void filter_projects_and_apps_by_APP_qualifier_when_ee_dc(Edition edition) {
704 when(editionProviderMock.get()).thenReturn(Optional.of(edition));
706 OrganizationDto organization = db.organizations().insert();
707 ComponentDto application1 = insertApplication(organization);
708 ComponentDto application2 = insertApplication(organization);
709 ComponentDto application3 = insertApplication(organization);
711 insertProject(organization);
712 insertProject(organization);
713 insertProject(organization);
715 SearchProjectsWsResponse result = call(request.setFilter("qualifier = APP"));
717 assertThat(result.getComponentsCount())
720 assertThat(result.getComponentsList()).extracting(Component::getKey)
722 Stream.of(application1, application2, application3)
723 .map(ComponentDto::getDbKey)
724 .toArray(String[]::new));
728 @UseDataProvider("enterprise_or_datacenter_edition")
729 public void filter_projects_and_apps_by_TRK_qualifier_when_ee_or_dc(Edition edition) {
730 when(editionProviderMock.get()).thenReturn(Optional.of(edition));
732 OrganizationDto organization = db.organizations().insert();
734 insertApplication(organization);
735 insertApplication(organization);
736 insertApplication(organization);
738 ComponentDto project1 = insertProject(organization);
739 ComponentDto project2 = insertProject(organization);
740 ComponentDto project3 = insertProject(organization);
742 SearchProjectsWsResponse result = call(request.setFilter("qualifier = TRK"));
744 assertThat(result.getComponentsCount())
747 assertThat(result.getComponentsList()).extracting(Component::getKey)
749 Stream.of(project1, project2, project3)
750 .map(ComponentDto::getDbKey)
751 .toArray(String[]::new));
755 @UseDataProvider("community_or_developer_edition")
756 public void fail_when_qualifier_filter_by_APP_set_when_ce_or_de(Edition edition) {
757 when(editionProviderMock.get()).thenReturn(Optional.of(edition));
759 OrganizationDto organization = db.organizations().insert();
761 assertThatThrownBy(() -> call(request.setFilter("qualifiers = APP")))
762 .isInstanceOf(IllegalArgumentException.class);
766 @UseDataProvider("enterprise_or_datacenter_edition")
767 public void fail_when_qualifier_filter_invalid_when_ee_or_dc(Edition edition) {
768 when(editionProviderMock.get()).thenReturn(Optional.of(edition));
770 OrganizationDto organization = db.organizations().insert();
772 assertThatThrownBy(() -> call(request.setFilter("qualifiers = BLA")))
773 .isInstanceOf(IllegalArgumentException.class);
777 public void do_not_return_isFavorite_if_anonymous_user() {
778 userSession.anonymous();
779 OrganizationDto organization = db.organizations().insert();
780 insertProject(organization);
782 SearchProjectsWsResponse result = call(request);
784 assertThat(result.getComponentsList()).extracting(Component::hasIsFavorite).containsExactlyInAnyOrder(false);
788 public void return_nloc_facet() {
790 OrganizationDto organizationDto = db.organizations().insert();
791 MetricDto ncloc = db.measures().insertMetric(c -> c.setKey(NCLOC).setValueType(INT.name()));
792 insertProject(organizationDto, new Measure(ncloc, c -> c.setValue(5d)));
793 insertProject(organizationDto, new Measure(ncloc, c -> c.setValue(5d)));
794 insertProject(organizationDto, new Measure(ncloc, c -> c.setValue(10_000d)));
795 insertProject(organizationDto, new Measure(ncloc, c -> c.setValue(500_001d)));
797 SearchProjectsWsResponse result = call(request.setFacets(singletonList(NCLOC)));
799 Common.Facet facet = result.getFacets().getFacetsList().stream()
800 .filter(oneFacet -> NCLOC.equals(oneFacet.getProperty()))
801 .findFirst().orElseThrow(IllegalStateException::new);
802 assertThat(facet.getValuesList())
803 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
805 tuple("*-1000.0", 2L),
806 tuple("1000.0-10000.0", 0L),
807 tuple("10000.0-100000.0", 1L),
808 tuple("100000.0-500000.0", 0L),
809 tuple("500000.0-*", 1L));
813 public void return_new_lines_facet() {
815 OrganizationDto organizationDto = db.organizations().insert();
816 MetricDto coverage = db.measures().insertMetric(c -> c.setKey(NEW_LINES_KEY).setValueType(INT.name()));
817 insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(100d)));
818 insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(15_000d)));
819 insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(50_000d)));
821 SearchProjectsWsResponse result = call(request.setFacets(singletonList(NEW_LINES_KEY)));
823 Common.Facet facet = result.getFacets().getFacetsList().stream()
824 .filter(oneFacet -> NEW_LINES_KEY.equals(oneFacet.getProperty()))
825 .findFirst().orElseThrow(IllegalStateException::new);
826 assertThat(facet.getValuesList())
827 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
829 tuple("*-1000.0", 1L),
830 tuple("1000.0-10000.0", 0L),
831 tuple("10000.0-100000.0", 2L),
832 tuple("100000.0-500000.0", 0L),
833 tuple("500000.0-*", 0L));
837 public void return_languages_facet() {
839 OrganizationDto organizationDto = db.organizations().insert();
840 MetricDto languagesDistribution = db.measures().insertMetric(c -> c.setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY).setValueType("DATA"));
841 insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("<null>=2;java=6;xoo=18")));
842 insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("java=5;xoo=19")));
843 insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("xoo=1")));
844 insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("<null>=1;java=3;xoo=8")));
846 SearchProjectsWsResponse result = call(request.setFacets(singletonList(FILTER_LANGUAGES)));
848 Common.Facet facet = result.getFacets().getFacetsList().stream()
849 .filter(oneFacet -> FILTER_LANGUAGES.equals(oneFacet.getProperty()))
850 .findFirst().orElseThrow(IllegalStateException::new);
851 assertThat(facet.getValuesList())
852 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
856 tuple("<null>", 2L));
860 public void return_languages_facet_with_language_having_no_project_if_language_is_in_filter() {
862 OrganizationDto organizationDto = db.organizations().insert();
863 MetricDto languagesDistribution = db.measures().insertMetric(c -> c.setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY).setValueType("DATA"));
864 insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("<null>=2;java=6")));
865 insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("java=5")));
867 SearchProjectsWsResponse result = call(request.setFilter("languages = xoo").setFacets(singletonList(FILTER_LANGUAGES)));
869 Common.Facet facet = result.getFacets().getFacetsList().stream()
870 .filter(oneFacet -> FILTER_LANGUAGES.equals(oneFacet.getProperty()))
871 .findFirst().orElseThrow(IllegalStateException::new);
872 assertThat(facet.getValuesList())
873 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
877 tuple("<null>", 1L));
881 public void return_tags_facet() {
883 OrganizationDto organization = db.getDefaultOrganization();
884 insertProject(organization, defaults(), p -> p.setTags(asList("finance", "platform")));
885 insertProject(organization, defaults(), p -> p.setTags(singletonList("offshore")));
886 insertProject(organization, defaults(), p -> p.setTags(singletonList("offshore")));
888 SearchProjectsWsResponse result = call(request.setFacets(singletonList(FILTER_TAGS)));
890 Common.Facet facet = result.getFacets().getFacetsList().stream()
891 .filter(oneFacet -> FILTER_TAGS.equals(oneFacet.getProperty()))
892 .findFirst().orElseThrow(IllegalStateException::new);
893 assertThat(facet.getValuesList())
894 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
896 tuple("offshore", 2L),
897 tuple("finance", 1L),
898 tuple("platform", 1L));
902 public void return_tags_facet_with_tags_having_no_project_if_tags_is_in_filter() {
904 OrganizationDto organization = db.getDefaultOrganization();
905 insertProject(organization, defaults(), p -> p.setTags(asList("finance", "platform")));
906 insertProject(organization, defaults(), p -> p.setTags(singletonList("offshore")));
907 insertProject(organization, defaults(), p -> p.setTags(singletonList("offshore")));
909 SearchProjectsWsResponse result = call(request.setFilter("tags = marketing").setFacets(singletonList(FILTER_TAGS)));
911 Common.Facet facet = result.getFacets().getFacetsList().stream()
912 .filter(oneFacet -> FILTER_TAGS.equals(oneFacet.getProperty()))
913 .findFirst().orElseThrow(IllegalStateException::new);
914 assertThat(facet.getValuesList())
915 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
917 tuple("offshore", 2L),
918 tuple("finance", 1L),
919 tuple("platform", 1L),
920 tuple("marketing", 0L));
924 public void return_qualifiers_facet() {
925 when(editionProviderMock.get()).thenReturn(Optional.of(Edition.ENTERPRISE));
927 OrganizationDto organization = db.organizations().insert();
928 ComponentDto application1 = insertApplication(organization);
929 ComponentDto application2 = insertApplication(organization);
930 ComponentDto application3 = insertApplication(organization);
931 ComponentDto application4 = insertApplication(organization);
933 ComponentDto project1 = insertProject(organization);
934 ComponentDto project2 = insertProject(organization);
935 ComponentDto project3 = insertProject(organization);
937 SearchProjectsWsResponse result = call(request.setFacets(singletonList(FILTER_QUALIFIER)));
939 Common.Facet facet = result.getFacets().getFacetsList().stream()
940 .filter(oneFacet -> FILTER_QUALIFIER.equals(oneFacet.getProperty()))
941 .findFirst().orElseThrow(IllegalStateException::new);
942 assertThat(facet.getValuesList())
943 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
950 public void return_qualifiers_facet_with_qualifiers_having_no_project_if_qualifiers_is_in_filter() {
951 when(editionProviderMock.get()).thenReturn(Optional.of(Edition.ENTERPRISE));
953 OrganizationDto organization = db.getDefaultOrganization();
954 ComponentDto application1 = insertApplication(organization);
955 ComponentDto application2 = insertApplication(organization);
956 ComponentDto application3 = insertApplication(organization);
957 ComponentDto application4 = insertApplication(organization);
959 SearchProjectsWsResponse result = call(request.setFilter("qualifier = APP").setFacets(singletonList(FILTER_QUALIFIER)));
961 Common.Facet facet = result.getFacets().getFacetsList().stream()
962 .filter(oneFacet -> FILTER_QUALIFIER.equals(oneFacet.getProperty()))
963 .findFirst().orElseThrow(IllegalStateException::new);
964 assertThat(facet.getValuesList())
965 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
972 @UseDataProvider("rating_metric_keys")
973 public void return_rating_facet(String ratingMetricKey) {
975 OrganizationDto organization = db.organizations().insert();
976 MetricDto ratingMetric = db.measures().insertMetric(c -> c.setKey(ratingMetricKey).setValueType("RATING"));
977 insertProject(organization, new Measure(ratingMetric, c -> c.setValue(1d)));
978 insertProject(organization, new Measure(ratingMetric, c -> c.setValue(1d)));
979 insertProject(organization, new Measure(ratingMetric, c -> c.setValue(3d)));
980 insertProject(organization, new Measure(ratingMetric, c -> c.setValue(5d)));
982 SearchProjectsWsResponse result = call(request.setFacets(singletonList(ratingMetricKey)));
984 Common.Facet facet = result.getFacets().getFacetsList().stream()
985 .filter(oneFacet -> ratingMetricKey.equals(oneFacet.getProperty()))
986 .findFirst().orElseThrow(IllegalStateException::new);
987 assertThat(facet.getValuesList())
988 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
998 @UseDataProvider("new_rating_metric_keys")
999 public void return_new_rating_facet(String newRatingMetricKey) {
1000 userSession.logIn();
1001 OrganizationDto organization = db.organizations().insert();
1002 MetricDto newRatingMetric = db.measures().insertMetric(c -> c.setKey(newRatingMetricKey).setValueType("RATING"));
1003 insertProject(organization, new Measure(newRatingMetric, c -> c.setVariation(1d)));
1004 insertProject(organization, new Measure(newRatingMetric, c -> c.setVariation(1d)));
1005 insertProject(organization, new Measure(newRatingMetric, c -> c.setVariation(3d)));
1006 insertProject(organization, new Measure(newRatingMetric, c -> c.setVariation(5d)));
1008 SearchProjectsWsResponse result = call(request.setFacets(singletonList(newRatingMetricKey)));
1010 Common.Facet facet = result.getFacets().getFacetsList().stream()
1011 .filter(oneFacet -> newRatingMetricKey.equals(oneFacet.getProperty()))
1012 .findFirst().orElseThrow(IllegalStateException::new);
1013 assertThat(facet.getValuesList())
1014 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
1024 public void return_coverage_facet() {
1025 userSession.logIn();
1026 OrganizationDto organizationDto = db.organizations().insert();
1027 MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType("PERCENT"));
1028 insertProject(organizationDto);
1029 insertProject(organizationDto, new Measure(coverage, c -> c.setValue(80d)));
1030 insertProject(organizationDto, new Measure(coverage, c -> c.setValue(85d)));
1031 insertProject(organizationDto, new Measure(coverage, c -> c.setValue(10d)));
1033 SearchProjectsWsResponse result = call(request.setFacets(singletonList(COVERAGE)));
1035 Common.Facet facet = result.getFacets().getFacetsList().stream()
1036 .filter(oneFacet -> COVERAGE.equals(oneFacet.getProperty()))
1037 .findFirst().orElseThrow(IllegalStateException::new);
1038 assertThat(facet.getValuesList())
1039 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
1041 tuple("NO_DATA", 1L),
1042 tuple("*-30.0", 1L),
1043 tuple("30.0-50.0", 0L),
1044 tuple("50.0-70.0", 0L),
1045 tuple("70.0-80.0", 0L),
1046 tuple("80.0-*", 2L));
1050 public void return_new_coverage_facet() {
1051 userSession.logIn();
1052 OrganizationDto organizationDto = db.organizations().insert();
1053 MetricDto coverage = db.measures().insertMetric(c -> c.setKey(NEW_COVERAGE).setValueType("PERCENT"));
1054 insertProject(organizationDto);
1055 insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(80d)));
1056 insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(85d)));
1057 insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(10d)));
1059 SearchProjectsWsResponse result = call(request.setFacets(singletonList(NEW_COVERAGE)));
1061 Common.Facet facet = result.getFacets().getFacetsList().stream()
1062 .filter(oneFacet -> NEW_COVERAGE.equals(oneFacet.getProperty()))
1063 .findFirst().orElseThrow(IllegalStateException::new);
1064 assertThat(facet.getValuesList())
1065 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
1067 tuple("NO_DATA", 1L),
1068 tuple("*-30.0", 1L),
1069 tuple("30.0-50.0", 0L),
1070 tuple("50.0-70.0", 0L),
1071 tuple("70.0-80.0", 0L),
1072 tuple("80.0-*", 2L));
1076 public void return_duplications_facet() {
1077 userSession.logIn();
1078 OrganizationDto organizationDto = db.organizations().insert();
1079 MetricDto coverage = db.measures().insertMetric(c -> c.setKey(DUPLICATED_LINES_DENSITY_KEY).setValueType("PERCENT"));
1080 insertProject(organizationDto, new Measure(coverage, c -> c.setValue(10d)));
1081 insertProject(organizationDto, new Measure(coverage, c -> c.setValue(15d)));
1082 insertProject(organizationDto, new Measure(coverage, c -> c.setValue(5d)));
1083 insertProject(organizationDto);
1085 SearchProjectsWsResponse result = call(request.setFacets(singletonList(DUPLICATED_LINES_DENSITY_KEY)));
1087 Common.Facet facet = result.getFacets().getFacetsList().stream()
1088 .filter(oneFacet -> DUPLICATED_LINES_DENSITY_KEY.equals(oneFacet.getProperty()))
1089 .findFirst().orElseThrow(IllegalStateException::new);
1090 assertThat(facet.getValuesList())
1091 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
1093 tuple("NO_DATA", 1L),
1095 tuple("3.0-5.0", 0L),
1096 tuple("5.0-10.0", 1L),
1097 tuple("10.0-20.0", 2L),
1098 tuple("20.0-*", 0L));
1102 public void return_new_duplications_facet() {
1103 userSession.logIn();
1104 OrganizationDto organizationDto = db.organizations().insert();
1105 MetricDto coverage = db.measures().insertMetric(c -> c.setKey(NEW_DUPLICATED_LINES_DENSITY_KEY).setValueType("PERCENT"));
1106 insertProject(organizationDto);
1107 insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(10d)));
1108 insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(15d)));
1109 insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(5d)));
1111 SearchProjectsWsResponse result = call(request.setFacets(singletonList(NEW_DUPLICATED_LINES_DENSITY_KEY)));
1113 Common.Facet facet = result.getFacets().getFacetsList().stream()
1114 .filter(oneFacet -> NEW_DUPLICATED_LINES_DENSITY_KEY.equals(oneFacet.getProperty()))
1115 .findFirst().orElseThrow(IllegalStateException::new);
1116 assertThat(facet.getValuesList())
1117 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
1119 tuple("NO_DATA", 1L),
1121 tuple("3.0-5.0", 0L),
1122 tuple("5.0-10.0", 1L),
1123 tuple("10.0-20.0", 2L),
1124 tuple("20.0-*", 0L));
1128 public void return_quality_gate_facet() {
1129 userSession.logIn();
1130 OrganizationDto organizationDto = db.organizations().insert();
1131 MetricDto qualityGateStatus = db.measures().insertMetric(c -> c.setKey(ALERT_STATUS_KEY).setValueType(LEVEL.name()));
1132 insertProject(organizationDto, new Measure(qualityGateStatus, c -> c.setData(Metric.Level.ERROR.name()).setValue(null)));
1133 insertProject(organizationDto, new Measure(qualityGateStatus, c -> c.setData(Metric.Level.ERROR.name()).setValue(null)));
1134 insertProject(organizationDto, new Measure(qualityGateStatus, c -> c.setData(Metric.Level.WARN.name()).setValue(null)));
1135 insertProject(organizationDto, new Measure(qualityGateStatus, c -> c.setData(Metric.Level.OK.name()).setValue(null)));
1136 projectsInWarning.update(1L);
1138 SearchProjectsWsResponse result = call(request.setFacets(singletonList(ALERT_STATUS_KEY)));
1140 Common.Facet facet = result.getFacets().getFacetsList().stream()
1141 .filter(oneFacet -> ALERT_STATUS_KEY.equals(oneFacet.getProperty()))
1142 .findFirst().orElseThrow(IllegalStateException::new);
1143 assertThat(facet.getValuesList())
1144 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
1152 public void return_quality_gate_facet_without_warning_when_no_projects_in_warning() {
1153 userSession.logIn();
1154 OrganizationDto organizationDto = db.organizations().insert();
1155 MetricDto qualityGateStatus = db.measures().insertMetric(c -> c.setKey(ALERT_STATUS_KEY).setValueType(LEVEL.name()));
1156 insertProject(organizationDto, new Measure(qualityGateStatus, c -> c.setData(Metric.Level.ERROR.name()).setValue(null)));
1157 insertProject(organizationDto, new Measure(qualityGateStatus, c -> c.setData(Metric.Level.ERROR.name()).setValue(null)));
1158 insertProject(organizationDto, new Measure(qualityGateStatus, c -> c.setData(Metric.Level.OK.name()).setValue(null)));
1159 projectsInWarning.update(0L);
1161 SearchProjectsWsResponse result = call(request.setFacets(singletonList(ALERT_STATUS_KEY)));
1163 Common.Facet facet = result.getFacets().getFacetsList().stream()
1164 .filter(oneFacet -> ALERT_STATUS_KEY.equals(oneFacet.getProperty()))
1165 .findFirst().orElseThrow(IllegalStateException::new);
1166 assertThat(facet.getValuesList())
1167 .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
1170 tuple("ERROR", 2L));
1174 public void default_sort_is_by_ascending_name() {
1175 userSession.logIn();
1176 OrganizationDto organization = db.getDefaultOrganization();
1177 insertProject(organization, c -> c.setName("Sonar Java"));
1178 insertProject(organization, c -> c.setName("Sonar Groovy"));
1179 insertProject(organization, c -> c.setName("Sonar Markdown"));
1180 insertProject(organization, c -> c.setName("Sonar Qube"));
1182 SearchProjectsWsResponse result = call(request);
1184 assertThat(result.getComponentsList()).extracting(Component::getName).containsExactly("Sonar Groovy", "Sonar Java", "Sonar Markdown", "Sonar Qube");
1188 public void sort_by_name() {
1189 userSession.logIn();
1190 OrganizationDto organization = db.getDefaultOrganization();
1191 insertProject(organization, c -> c.setName("Sonar Java"));
1192 insertProject(organization, c -> c.setName("Sonar Groovy"));
1193 insertProject(organization, c -> c.setName("Sonar Markdown"));
1194 insertProject(organization, c -> c.setName("Sonar Qube"));
1196 assertThat(call(request.setSort("name").setAsc(true)).getComponentsList()).extracting(Component::getName)
1197 .containsExactly("Sonar Groovy", "Sonar Java", "Sonar Markdown", "Sonar Qube");
1198 assertThat(call(request.setSort("name").setAsc(false)).getComponentsList()).extracting(Component::getName)
1199 .containsExactly("Sonar Qube", "Sonar Markdown", "Sonar Java", "Sonar Groovy");
1203 public void sort_by_coverage_then_by_name() {
1204 userSession.logIn();
1205 OrganizationDto organizationDto = db.organizations().insert();
1206 MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType(INT.name()));
1207 ComponentDto project1 = insertProject(organizationDto, c -> c.setName("Sonar Java"), new Measure(coverage, c -> c.setValue(81d)));
1208 ComponentDto project2 = insertProject(organizationDto, c -> c.setName("Sonar Groovy"), new Measure(coverage, c -> c.setValue(81d)));
1209 ComponentDto project3 = insertProject(organizationDto, c -> c.setName("Sonar Markdown"), new Measure(coverage, c -> c.setValue(80d)));
1210 ComponentDto project4 = insertProject(organizationDto, c -> c.setName("Sonar Qube"), new Measure(coverage, c -> c.setValue(80d)));
1212 assertThat(call(request.setSort(COVERAGE).setAsc(true)).getComponentsList()).extracting(Component::getKey)
1213 .containsExactly(project3.getDbKey(), project4.getDbKey(), project2.getDbKey(), project1.getDbKey());
1214 assertThat(call(request.setSort(COVERAGE).setAsc(false)).getComponentsList()).extracting(Component::getKey)
1215 .containsExactly(project2.getDbKey(), project1.getDbKey(), project3.getDbKey(), project4.getDbKey());
1219 public void sort_by_quality_gate_then_by_name() {
1220 userSession.logIn();
1221 OrganizationDto organization = db.organizations().insert();
1222 MetricDto qualityGateStatus = db.measures().insertMetric(c -> c.setKey(QUALITY_GATE_STATUS).setValueType(LEVEL.name()));
1223 ComponentDto project1 = insertProject(organization, c -> c.setName("Sonar Java"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("ERROR")));
1224 ComponentDto project2 = insertProject(organization, c -> c.setName("Sonar Groovy"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("ERROR")));
1225 ComponentDto project3 = insertProject(organization, c -> c.setName("Sonar Markdown"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("OK")));
1226 ComponentDto project4 = insertProject(organization, c -> c.setName("Sonar Qube"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("OK")));
1228 assertThat(call(request.setSort(QUALITY_GATE_STATUS).setAsc(true)).getComponentsList()).extracting(Component::getKey)
1229 .containsExactly(project3.getDbKey(), project4.getDbKey(), project2.getDbKey(), project1.getDbKey());
1230 assertThat(call(request.setSort(QUALITY_GATE_STATUS).setAsc(false)).getComponentsList()).extracting(Component::getKey)
1231 .containsExactly(project2.getDbKey(), project1.getDbKey(), project3.getDbKey(), project4.getDbKey());
1235 public void sort_by_last_analysis_date() {
1236 userSession.logIn();
1237 OrganizationDto organization = db.organizations().insert();
1238 ComponentDto project1 = db.components().insertPublicProject(organization, p -> p.setDbKey("project1"));
1239 authorizationIndexerTester.allowOnlyAnyone(project1);
1240 ComponentDto project2 = db.components().insertPublicProject(organization, p -> p.setDbKey("project2"));
1241 db.components().insertSnapshot(project2, snapshot -> snapshot.setCreatedAt(40_000_000_000L).setLast(true));
1242 authorizationIndexerTester.allowOnlyAnyone(project2);
1243 ComponentDto project3 = db.components().insertPublicProject(organization, p -> p.setDbKey("project3"));
1244 db.components().insertSnapshot(project3, snapshot -> snapshot.setCreatedAt(20_000_000_000L).setLast(true));
1245 authorizationIndexerTester.allowOnlyAnyone(project3);
1246 ComponentDto project4 = db.components().insertPublicProject(organization, p -> p.setDbKey("project4"));
1247 db.components().insertSnapshot(project4, snapshot -> snapshot.setCreatedAt(10_000_000_000L).setLast(false));
1248 db.components().insertSnapshot(project4, snapshot -> snapshot.setCreatedAt(30_000_000_000L).setLast(true));
1249 authorizationIndexerTester.allowOnlyAnyone(project4);
1250 projectMeasuresIndexer.indexOnStartup(null);
1252 assertThat(call(request.setSort(ANALYSIS_DATE).setAsc(true)).getComponentsList()).extracting(Component::getKey)
1253 .containsExactly(project3.getDbKey(), project4.getDbKey(), project2.getDbKey(), project1.getDbKey());
1255 assertThat(call(request.setSort(ANALYSIS_DATE).setAsc(false)).getComponentsList()).extracting(Component::getKey)
1256 .containsExactly(project2.getDbKey(), project4.getDbKey(), project3.getDbKey(), project1.getDbKey());
1260 public void return_last_analysis_date() {
1261 userSession.logIn();
1262 OrganizationDto organization = db.organizations().insert();
1263 ComponentDto project1 = db.components().insertPublicProject(organization);
1264 db.components().insertSnapshot(project1, snapshot -> snapshot.setCreatedAt(10_000_000_000L).setLast(false));
1265 db.components().insertSnapshot(project1, snapshot -> snapshot.setCreatedAt(20_000_000_000L).setLast(true));
1266 authorizationIndexerTester.allowOnlyAnyone(project1);
1267 ComponentDto project2 = db.components().insertPublicProject(organization);
1268 db.components().insertSnapshot(project2, snapshot -> snapshot.setCreatedAt(30_000_000_000L).setLast(true));
1269 authorizationIndexerTester.allowOnlyAnyone(project2);
1270 // No snapshot on project 3
1271 ComponentDto project3 = db.components().insertPublicProject(organization);
1272 authorizationIndexerTester.allowOnlyAnyone(project3);
1273 projectMeasuresIndexer.indexOnStartup(null);
1275 SearchProjectsWsResponse result = call(request.setAdditionalFields(singletonList("analysisDate")));
1277 assertThat(result.getComponentsList()).extracting(Component::getKey, Component::hasAnalysisDate, Component::getAnalysisDate)
1279 tuple(project1.getDbKey(), true, formatDateTime(new Date(20_000_000_000L))),
1280 tuple(project2.getDbKey(), true, formatDateTime(new Date(30_000_000_000L))),
1281 tuple(project3.getDbKey(), false, ""));
1285 public void return_leak_period_date() {
1286 when(editionProviderMock.get()).thenReturn(Optional.of(Edition.ENTERPRISE));
1287 userSession.logIn();
1288 OrganizationDto organization = db.organizations().insert();
1289 ComponentDto project1 = db.components().insertPublicProject(organization);
1290 db.components().insertSnapshot(project1, snapshot -> snapshot.setPeriodDate(10_000_000_000L));
1291 authorizationIndexerTester.allowOnlyAnyone(project1);
1293 ComponentDto project2 = db.components().insertPublicProject(organization);
1294 db.components().insertSnapshot(project2, snapshot -> snapshot.setPeriodDate(null));
1295 authorizationIndexerTester.allowOnlyAnyone(project2);
1296 // No snapshot on project 3
1297 ComponentDto project3 = db.components().insertPublicProject(organization);
1298 authorizationIndexerTester.allowOnlyAnyone(project3);
1300 MetricDto leakProjects = db.measures().insertMetric(c -> c.setKey(LEAK_PROJECTS_KEY).setValueType(DATA.name()));
1301 ComponentDto application1 = insertApplication(organization,
1302 new Measure(leakProjects, c -> c.setData("{\"leakProjects\":[{\"id\": 1, \"leak\":20000000000}, {\"id\": 2, \"leak\":10000000000}]}")));
1303 db.components().insertSnapshot(application1);
1305 authorizationIndexerTester.allowOnlyAnyone(application1);
1306 projectMeasuresIndexer.indexOnStartup(null);
1308 SearchProjectsWsResponse result = call(request.setAdditionalFields(singletonList("leakPeriodDate")));
1310 assertThat(result.getComponentsList()).extracting(Component::getKey, Component::hasLeakPeriodDate, Component::getLeakPeriodDate)
1312 tuple(project1.getDbKey(), true, formatDateTime(new Date(10_000_000_000L))),
1313 tuple(project2.getDbKey(), false, ""),
1314 tuple(project3.getDbKey(), false, ""),
1315 tuple(application1.getDbKey(), true, formatDateTime(new Date(10_000_000_000L))));
1319 public void return_visibility_flag() {
1320 userSession.logIn();
1321 OrganizationDto organization = db.organizations().insert();
1322 ComponentDto privateProject = db.components().insertPublicProject(organization);
1323 authorizationIndexerTester.allowOnlyAnyone(privateProject);
1324 ComponentDto publicProject = db.components().insertPrivateProject(organization);
1325 authorizationIndexerTester.allowOnlyAnyone(publicProject);
1326 projectMeasuresIndexer.indexOnStartup(null);
1328 SearchProjectsWsResponse result = call(request);
1330 assertThat(result.getComponentsList()).extracting(Component::getKey, Component::getVisibility)
1332 tuple(privateProject.getDbKey(), privateProject.isPrivate() ? "private" : "public"),
1333 tuple(publicProject.getDbKey(), publicProject.isPrivate() ? "private" : "public"));
1337 public void does_not_return_branches() {
1338 ComponentDto project = db.components().insertPublicProject();
1339 authorizationIndexerTester.allowOnlyAnyone(project);
1340 ComponentDto branch = db.components().insertProjectBranch(project);
1341 projectMeasuresIndexer.indexOnStartup(null);
1343 SearchProjectsWsResponse result = call(request);
1345 assertThat(result.getComponentsList()).extracting(Component::getKey)
1346 .containsExactlyInAnyOrder(project.getDbKey());
1350 public void use_deprecated_warning_quality_gate_in_filter() {
1351 userSession.logIn();
1352 OrganizationDto organization = db.organizations().insert();
1353 MetricDto qualityGateStatus = db.measures().insertMetric(c -> c.setKey(QUALITY_GATE_STATUS).setValueType(LEVEL.name()));
1354 ComponentDto project1 = insertProject(organization, c -> c.setName("Sonar Java"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("ERROR")));
1355 ComponentDto project2 = insertProject(organization, c -> c.setName("Sonar Groovy"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("WARN")));
1356 ComponentDto project3 = insertProject(organization, c -> c.setName("Sonar Markdown"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("WARN")));
1357 ComponentDto project4 = insertProject(organization, c -> c.setName("Sonar Qube"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("OK")));
1359 List<Component> projects = call(request
1360 .setFilter("alert_status = WARN"))
1361 .getComponentsList();
1363 assertThat(projects)
1364 .extracting(Component::getKey)
1365 .containsExactly(project2.getKey(), project3.getKey());
1369 public void fail_when_filter_metrics_are_unknown() {
1370 userSession.logIn();
1371 expectedException.expect(IllegalArgumentException.class);
1372 expectedException.expectMessage("Following metrics are not supported: 'debt'");
1374 request.setFilter("debt > 80");
1380 public void fail_when_sort_metrics_are_unknown() {
1381 userSession.logIn();
1382 expectedException.expect(IllegalArgumentException.class);
1383 expectedException.expectMessage("Value of parameter 's' (debt) must be one of: [");
1385 request.setSort("debt");
1391 public void fail_if_page_size_greater_than_500() {
1392 userSession.logIn();
1394 expectedException.expect(IllegalArgumentException.class);
1396 call(request.setPageSize(501));
1399 private SearchProjectsWsResponse call(RequestBuilder requestBuilder) {
1400 SearchProjectsRequest wsRequest = requestBuilder.build();
1401 TestRequest httpRequest = ws.newRequest();
1402 ofNullable(wsRequest.getOrganization()).ifPresent(organization -> httpRequest.setParam(PARAM_ORGANIZATION, organization));
1403 ofNullable(wsRequest.getFilter()).ifPresent(filter -> httpRequest.setParam(PARAM_FILTER, filter));
1404 ofNullable(wsRequest.getSort()).ifPresent(sort -> httpRequest.setParam(SORT, sort));
1405 ofNullable(wsRequest.getAsc()).ifPresent(asc -> httpRequest.setParam(ASCENDING, Boolean.toString(asc)));
1406 httpRequest.setParam(PAGE, String.valueOf(wsRequest.getPage()));
1407 httpRequest.setParam(PAGE_SIZE, String.valueOf(wsRequest.getPageSize()));
1408 httpRequest.setParam(FACETS, Joiner.on(",").join(wsRequest.getFacets()));
1409 httpRequest.setParam(FIELDS, Joiner.on(",").join(wsRequest.getAdditionalFields()));
1410 return httpRequest.executeProtobuf(SearchProjectsWsResponse.class);
1413 private void addFavourite(ComponentDto project) {
1414 dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("favourite").setComponentUuid(project.uuid()).setUserUuid(userSession.getUuid()));
1418 private ComponentDto insertProject(OrganizationDto organizationDto, Measure... measures) {
1419 return insertProject(organizationDto, defaults(), defaults(), measures);
1422 private ComponentDto insertProject(OrganizationDto organizationDto, Consumer<ComponentDto> componentConsumer, Measure... measures) {
1423 return insertProject(organizationDto, componentConsumer, defaults(), measures);
1426 private ComponentDto insertProject(OrganizationDto organizationDto, Consumer<ComponentDto> componentConsumer, Consumer<ProjectDto> projectConsumer,
1427 Measure... measures) {
1428 ComponentDto project = db.components().insertPublicProject(organizationDto, componentConsumer, projectConsumer);
1429 Arrays.stream(measures).forEach(m -> db.measures().insertLiveMeasure(project, m.metric, m.consumer));
1430 authorizationIndexerTester.allowOnlyAnyone(project);
1431 projectMeasuresIndexer.indexOnAnalysis(project.uuid());
1435 private ComponentDto insertApplication(OrganizationDto organizationDto, Measure... measures) {
1436 return insertApplication(organizationDto, defaults(), measures);
1439 private ComponentDto insertApplication(OrganizationDto organizationDto, Consumer<ComponentDto> componentConsumer, Measure... measures) {
1440 ComponentDto application = db.components().insertPublicApplication(organizationDto, componentConsumer);
1441 Arrays.stream(measures).forEach(m -> db.measures().insertLiveMeasure(application, m.metric, m.consumer));
1442 authorizationIndexerTester.allowOnlyAnyone(application);
1443 projectMeasuresIndexer.indexOnAnalysis(application.uuid());
1447 private ComponentDto insertPortfolio(OrganizationDto organizationDto) {
1448 ComponentDto portfolio = db.components().insertPublicPortfolio(organizationDto);
1449 authorizationIndexerTester.allowOnlyAnyone(portfolio);
1450 projectMeasuresIndexer.indexOnAnalysis(portfolio.uuid());
1454 private static class Measure {
1455 private final MetricDto metric;
1456 private final Consumer<LiveMeasureDto> consumer;
1458 public Measure(MetricDto metric, Consumer<LiveMeasureDto> consumer) {
1459 this.metric = metric;
1460 this.consumer = consumer;
1464 private static <T> Consumer<T> defaults() {