3 * Copyright (C) 2009-2023 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.measure.index;
22 import com.google.common.collect.ImmutableMap;
23 import com.google.common.collect.ImmutableSet;
24 import com.google.common.collect.Sets;
25 import com.tngtech.java.junit.dataprovider.DataProvider;
26 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
27 import com.tngtech.java.junit.dataprovider.UseDataProvider;
28 import java.util.Arrays;
29 import java.util.LinkedHashMap;
30 import java.util.List;
32 import java.util.stream.IntStream;
33 import org.junit.Rule;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.sonar.api.utils.System2;
37 import org.sonar.db.component.ComponentDto;
38 import org.sonar.db.component.ComponentTesting;
39 import org.sonar.db.user.GroupDto;
40 import org.sonar.db.user.UserDto;
41 import org.sonar.server.es.EsTester;
42 import org.sonar.server.es.Facets;
43 import org.sonar.server.es.SearchIdResult;
44 import org.sonar.server.es.SearchOptions;
45 import org.sonar.server.measure.index.ProjectMeasuresQuery.MetricCriterion;
46 import org.sonar.server.permission.index.IndexPermissions;
47 import org.sonar.server.permission.index.PermissionIndexerTester;
48 import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
49 import org.sonar.server.tester.UserSessionRule;
51 import static com.google.common.collect.Lists.newArrayList;
52 import static com.google.common.collect.Sets.newHashSet;
53 import static java.util.Arrays.asList;
54 import static java.util.Arrays.stream;
55 import static java.util.Collections.singletonList;
56 import static java.util.stream.Collectors.toList;
57 import static org.assertj.core.api.Assertions.assertThat;
58 import static org.assertj.core.api.Assertions.assertThatThrownBy;
59 import static org.assertj.core.api.Assertions.entry;
60 import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
61 import static org.sonar.api.measures.CoreMetrics.COVERAGE_KEY;
62 import static org.sonar.api.measures.Metric.Level.ERROR;
63 import static org.sonar.api.measures.Metric.Level.OK;
64 import static org.sonar.api.measures.Metric.Level.WARN;
65 import static org.sonar.api.resources.Qualifiers.APP;
66 import static org.sonar.api.resources.Qualifiers.PROJECT;
67 import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
68 import static org.sonar.db.user.GroupTesting.newGroupDto;
69 import static org.sonar.db.user.UserTesting.newUserDto;
70 import static org.sonar.server.measure.index.ProjectMeasuresIndexDefinition.FIELD_TAGS;
71 import static org.sonar.server.measure.index.ProjectMeasuresIndexDefinition.TYPE_PROJECT_MEASURES;
72 import static org.sonar.server.measure.index.ProjectMeasuresQuery.Operator;
73 import static org.sonarqube.ws.client.project.ProjectsWsParameters.FILTER_QUALIFIER;
75 @RunWith(DataProviderRunner.class)
76 public class ProjectMeasuresIndexTest {
78 private static final String MAINTAINABILITY_RATING = "sqale_rating";
79 private static final String NEW_MAINTAINABILITY_RATING_KEY = "new_maintainability_rating";
80 private static final String RELIABILITY_RATING = "reliability_rating";
81 private static final String NEW_RELIABILITY_RATING = "new_reliability_rating";
82 private static final String SECURITY_RATING = "security_rating";
83 private static final String NEW_SECURITY_RATING = "new_security_rating";
84 private static final String SECURITY_REVIEW_RATING = "security_review_rating";
85 private static final String NEW_SECURITY_REVIEW_RATING = "new_security_review_rating";
86 private static final String SECURITY_HOTSPOTS_REVIEWED = "security_hotspots_reviewed";
87 private static final String NEW_SECURITY_HOTSPOTS_REVIEWED = "new_security_hotspots_reviewed";
88 private static final String COVERAGE = "coverage";
89 private static final String NEW_COVERAGE = "new_coverage";
90 private static final String DUPLICATION = "duplicated_lines_density";
91 private static final String NEW_DUPLICATION = "new_duplicated_lines_density";
92 private static final String NCLOC = "ncloc";
93 private static final String NEW_LINES = "new_lines";
94 private static final String LANGUAGES = "languages";
96 private static final ComponentDto PROJECT1 = ComponentTesting.newPrivateProjectDto().setUuid("Project-1").setName("Project 1").setKey("key-1");
97 private static final ComponentDto PROJECT2 = ComponentTesting.newPrivateProjectDto().setUuid("Project-2").setName("Project 2").setKey("key-2");
98 private static final ComponentDto PROJECT3 = ComponentTesting.newPrivateProjectDto().setUuid("Project-3").setName("Project 3").setKey("key-3");
99 private static final ComponentDto APP1 = ComponentTesting.newApplication().setUuid("App-1").setName("App 1").setKey("app-key-1");
100 private static final ComponentDto APP2 = ComponentTesting.newApplication().setUuid("App-2").setName("App 2").setKey("app-key-2");
101 private static final ComponentDto APP3 = ComponentTesting.newApplication().setUuid("App-3").setName("App 3").setKey("app-key-3");
102 private static final UserDto USER1 = newUserDto();
103 private static final UserDto USER2 = newUserDto();
104 private static final GroupDto GROUP1 = newGroupDto();
105 private static final GroupDto GROUP2 = newGroupDto();
108 public EsTester es = EsTester.create();
110 public UserSessionRule userSession = UserSessionRule.standalone();
113 public static Object[][] rating_metric_keys() {
114 return new Object[][] {{MAINTAINABILITY_RATING}, {NEW_MAINTAINABILITY_RATING_KEY}, {RELIABILITY_RATING}, {NEW_RELIABILITY_RATING}, {SECURITY_RATING}, {NEW_SECURITY_RATING},
115 {SECURITY_REVIEW_RATING}, {NEW_SECURITY_REVIEW_RATING}};
118 private ProjectMeasuresIndexer projectMeasureIndexer = new ProjectMeasuresIndexer(null, es.client());
119 private PermissionIndexerTester authorizationIndexer = new PermissionIndexerTester(es, projectMeasureIndexer);
120 private ProjectMeasuresIndex underTest = new ProjectMeasuresIndex(es.client(), new WebAuthorizationTypeSupport(userSession), System2.INSTANCE);
123 public void return_empty_if_no_projects() {
124 assertNoResults(new ProjectMeasuresQuery());
128 public void default_sort_is_by_ascending_case_insensitive_name_then_by_key() {
129 ComponentDto windows = ComponentTesting.newPrivateProjectDto().setUuid("windows").setName("Windows").setKey("project1");
130 ComponentDto apachee = ComponentTesting.newPrivateProjectDto().setUuid("apachee").setName("apachee").setKey("project2");
131 ComponentDto apache1 = ComponentTesting.newPrivateProjectDto().setUuid("apache-1").setName("Apache").setKey("project3");
132 ComponentDto apache2 = ComponentTesting.newPrivateProjectDto().setUuid("apache-2").setName("Apache").setKey("project4");
133 index(newDoc(windows), newDoc(apachee), newDoc(apache1), newDoc(apache2));
135 assertResults(new ProjectMeasuresQuery(), apache1, apache2, apachee, windows);
139 public void sort_by_insensitive_name() {
140 ComponentDto windows = ComponentTesting.newPrivateProjectDto().setUuid("windows").setName("Windows");
141 ComponentDto apachee = ComponentTesting.newPrivateProjectDto().setUuid("apachee").setName("apachee");
142 ComponentDto apache = ComponentTesting.newPrivateProjectDto().setUuid("apache").setName("Apache");
143 index(newDoc(windows), newDoc(apachee), newDoc(apache));
145 assertResults(new ProjectMeasuresQuery().setSort("name").setAsc(true), apache, apachee, windows);
146 assertResults(new ProjectMeasuresQuery().setSort("name").setAsc(false), windows, apachee, apache);
150 public void sort_by_ncloc() {
152 newDoc(PROJECT1, NCLOC, 15_000d),
153 newDoc(PROJECT2, NCLOC, 30_000d),
154 newDoc(PROJECT3, NCLOC, 1_000d));
156 assertResults(new ProjectMeasuresQuery().setSort("ncloc").setAsc(true), PROJECT3, PROJECT1, PROJECT2);
157 assertResults(new ProjectMeasuresQuery().setSort("ncloc").setAsc(false), PROJECT2, PROJECT1, PROJECT3);
161 public void sort_by_a_metric_then_by_name_then_by_key() {
162 ComponentDto windows = ComponentTesting.newPrivateProjectDto().setUuid("windows").setName("Windows").setKey("project1");
163 ComponentDto apachee = ComponentTesting.newPrivateProjectDto().setUuid("apachee").setName("apachee").setKey("project2");
164 ComponentDto apache1 = ComponentTesting.newPrivateProjectDto().setUuid("apache-1").setName("Apache").setKey("project3");
165 ComponentDto apache2 = ComponentTesting.newPrivateProjectDto().setUuid("apache-2").setName("Apache").setKey("project4");
167 newDoc(windows, NCLOC, 10_000d),
168 newDoc(apachee, NCLOC, 5_000d),
169 newDoc(apache1, NCLOC, 5_000d),
170 newDoc(apache2, NCLOC, 5_000d));
172 assertResults(new ProjectMeasuresQuery().setSort("ncloc").setAsc(true), apache1, apache2, apachee, windows);
173 assertResults(new ProjectMeasuresQuery().setSort("ncloc").setAsc(false), windows, apache1, apache2, apachee);
177 public void sort_by_quality_gate_status() {
178 ComponentDto project4 = ComponentTesting.newPrivateProjectDto().setUuid("Project-4").setName("Project 4").setKey("key-4");
180 newDoc(PROJECT1).setQualityGateStatus(OK.name()),
181 newDoc(PROJECT2).setQualityGateStatus(ERROR.name()),
182 newDoc(project4).setQualityGateStatus(OK.name()));
184 assertResults(new ProjectMeasuresQuery().setSort("alert_status").setAsc(true), PROJECT1, project4, PROJECT2);
185 assertResults(new ProjectMeasuresQuery().setSort("alert_status").setAsc(false), PROJECT2, PROJECT1, project4);
189 public void sort_by_quality_gate_status_then_by_name_then_by_key() {
190 ComponentDto windows = ComponentTesting.newPrivateProjectDto().setUuid("windows").setName("Windows").setKey("project1");
191 ComponentDto apachee = ComponentTesting.newPrivateProjectDto().setUuid("apachee").setName("apachee").setKey("project2");
192 ComponentDto apache1 = ComponentTesting.newPrivateProjectDto().setUuid("apache-1").setName("Apache").setKey("project3");
193 ComponentDto apache2 = ComponentTesting.newPrivateProjectDto().setUuid("apache-2").setName("Apache").setKey("project4");
195 newDoc(windows).setQualityGateStatus(ERROR.name()),
196 newDoc(apachee).setQualityGateStatus(OK.name()),
197 newDoc(apache1).setQualityGateStatus(OK.name()),
198 newDoc(apache2).setQualityGateStatus(OK.name()));
200 assertResults(new ProjectMeasuresQuery().setSort("alert_status").setAsc(true), apache1, apache2, apachee, windows);
201 assertResults(new ProjectMeasuresQuery().setSort("alert_status").setAsc(false), windows, apache1, apache2, apachee);
205 public void paginate_results() {
206 IntStream.rangeClosed(1, 9)
207 .forEach(i -> index(newDoc(newPrivateProjectDto("P" + i))));
209 SearchIdResult<String> result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().setPage(2, 3));
211 assertThat(result.getUuids()).containsExactly("P4", "P5", "P6");
212 assertThat(result.getTotal()).isEqualTo(9);
216 public void filter_with_lower_than() {
218 newDoc(PROJECT1, COVERAGE, 79d, NCLOC, 10_000d),
219 newDoc(PROJECT2, COVERAGE, 80d, NCLOC, 10_000d),
220 newDoc(PROJECT3, COVERAGE, 81d, NCLOC, 10_000d));
222 ProjectMeasuresQuery query = new ProjectMeasuresQuery()
223 .addMetricCriterion(MetricCriterion.create(COVERAGE, Operator.LT, 80d));
225 assertResults(query, PROJECT1);
229 public void filter_with_lower_than_or_equals() {
231 newDoc(PROJECT1, COVERAGE, 79d, NCLOC, 10_000d),
232 newDoc(PROJECT2, COVERAGE, 80d, NCLOC, 10_000d),
233 newDoc(PROJECT3, COVERAGE, 81d, NCLOC, 10_000d));
235 ProjectMeasuresQuery query = new ProjectMeasuresQuery()
236 .addMetricCriterion(MetricCriterion.create(COVERAGE, Operator.LTE, 80d));
238 assertResults(query, PROJECT1, PROJECT2);
242 public void filter_with_greater_than() {
244 newDoc(PROJECT1, COVERAGE, 80d, NCLOC, 30_000d),
245 newDoc(PROJECT2, COVERAGE, 80d, NCLOC, 30_001d),
246 newDoc(PROJECT3, COVERAGE, 80d, NCLOC, 30_001d));
248 ProjectMeasuresQuery query = new ProjectMeasuresQuery().addMetricCriterion(MetricCriterion.create(NCLOC, Operator.GT, 30_000d));
249 assertResults(query, PROJECT2, PROJECT3);
251 query = new ProjectMeasuresQuery().addMetricCriterion(MetricCriterion.create(NCLOC, Operator.GT, 100_000d));
252 assertNoResults(query);
256 public void filter_with_greater_than_or_equals() {
258 newDoc(PROJECT1, COVERAGE, 80d, NCLOC, 30_000d),
259 newDoc(PROJECT2, COVERAGE, 80d, NCLOC, 30_001d),
260 newDoc(PROJECT3, COVERAGE, 80d, NCLOC, 30_001d));
262 ProjectMeasuresQuery query = new ProjectMeasuresQuery().addMetricCriterion(MetricCriterion.create(NCLOC, Operator.GTE, 30_001d));
263 assertResults(query, PROJECT2, PROJECT3);
265 query = new ProjectMeasuresQuery().addMetricCriterion(MetricCriterion.create(NCLOC, Operator.GTE, 100_000d));
266 assertNoResults(query);
270 public void filter_with_equals() {
272 newDoc(PROJECT1, COVERAGE, 79d, NCLOC, 10_000d),
273 newDoc(PROJECT2, COVERAGE, 80d, NCLOC, 10_000d),
274 newDoc(PROJECT3, COVERAGE, 81d, NCLOC, 10_000d));
276 ProjectMeasuresQuery query = new ProjectMeasuresQuery()
277 .addMetricCriterion(MetricCriterion.create(COVERAGE, Operator.EQ, 80d));
279 assertResults(query, PROJECT2);
283 public void filter_on_no_data_with_several_projects() {
285 newDoc(PROJECT1, NCLOC, 1d),
286 newDoc(PROJECT2, DUPLICATION, 80d));
288 ProjectMeasuresQuery query = new ProjectMeasuresQuery()
289 .addMetricCriterion(MetricCriterion.createNoData(DUPLICATION));
291 assertResults(query, PROJECT1);
295 public void filter_on_no_data_should_not_return_projects_with_data_and_other_measures() {
296 ComponentDto project = ComponentTesting.newPrivateProjectDto();
297 index(newDoc(project, DUPLICATION, 80d, NCLOC, 1d));
299 ProjectMeasuresQuery query = new ProjectMeasuresQuery().addMetricCriterion(MetricCriterion.createNoData(DUPLICATION));
301 assertNoResults(query);
305 public void filter_on_no_data_should_not_return_projects_with_data() {
306 ComponentDto project = ComponentTesting.newPrivateProjectDto();
307 index(newDoc(project, DUPLICATION, 80d));
309 ProjectMeasuresQuery query = new ProjectMeasuresQuery().addMetricCriterion(MetricCriterion.createNoData(DUPLICATION));
311 assertNoResults(query);
315 public void filter_on_no_data_should_return_projects_with_no_data() {
316 ComponentDto project = ComponentTesting.newPrivateProjectDto();
317 index(newDoc(project, NCLOC, 1d));
319 ProjectMeasuresQuery query = new ProjectMeasuresQuery().addMetricCriterion(MetricCriterion.createNoData(DUPLICATION));
321 assertResults(query, project);
325 public void filter_on_several_metrics() {
327 newDoc(PROJECT1, COVERAGE, 81d, NCLOC, 10_001d),
328 newDoc(PROJECT2, COVERAGE, 80d, NCLOC, 10_001d),
329 newDoc(PROJECT3, COVERAGE, 79d, NCLOC, 10_000d));
331 ProjectMeasuresQuery esQuery = new ProjectMeasuresQuery()
332 .addMetricCriterion(MetricCriterion.create(COVERAGE, Operator.LTE, 80d))
333 .addMetricCriterion(MetricCriterion.create(NCLOC, Operator.GT, 10_000d))
334 .addMetricCriterion(MetricCriterion.create(NCLOC, Operator.LT, 11_000d));
335 assertResults(esQuery, PROJECT2);
339 public void facet_security_hotspots_reviewed() {
341 // 2 docs with no measure
342 newDocWithNoMeasure(),
343 newDocWithNoMeasure(),
345 newDoc(SECURITY_HOTSPOTS_REVIEWED, 29),
346 newDoc(SECURITY_HOTSPOTS_REVIEWED, 28),
347 newDoc(SECURITY_HOTSPOTS_REVIEWED, 0),
348 // 2 docs with >=30% and <50%
349 newDoc(SECURITY_HOTSPOTS_REVIEWED, 30),
350 newDoc(SECURITY_HOTSPOTS_REVIEWED, 49),
351 // 4 docs with >=50% and <70%
352 newDoc(SECURITY_HOTSPOTS_REVIEWED, 50),
353 newDoc(SECURITY_HOTSPOTS_REVIEWED, 60),
354 newDoc(SECURITY_HOTSPOTS_REVIEWED, 61),
355 newDoc(SECURITY_HOTSPOTS_REVIEWED, 69),
356 // 2 docs with >=70% and <80%
357 newDoc(SECURITY_HOTSPOTS_REVIEWED, 70),
358 newDoc(SECURITY_HOTSPOTS_REVIEWED, 79),
359 // 5 docs with >= 80%
360 newDoc(SECURITY_HOTSPOTS_REVIEWED, 80),
361 newDoc(SECURITY_HOTSPOTS_REVIEWED, 90),
362 newDoc(SECURITY_HOTSPOTS_REVIEWED, 93),
363 newDoc(SECURITY_HOTSPOTS_REVIEWED, 99),
364 newDoc(SECURITY_HOTSPOTS_REVIEWED, 100));
366 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(SECURITY_HOTSPOTS_REVIEWED)).getFacets();
367 assertThat(facets.get(SECURITY_HOTSPOTS_REVIEWED)).containsExactly(
369 entry("30.0-50.0", 2L),
370 entry("50.0-70.0", 4L),
371 entry("70.0-80.0", 2L),
372 entry("80.0-*", 5L));
376 public void facet_new_security_hotspots_reviewed() {
378 // 2 docs with no measure
379 newDocWithNoMeasure(),
380 newDocWithNoMeasure(),
382 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 29),
383 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 28),
384 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 0),
385 // 2 docs with >=30% and <50%
386 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 30),
387 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 49),
388 // 4 docs with >=50% and <70%
389 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 50),
390 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 60),
391 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 61),
392 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 69),
393 // 2 docs with >=70% and <80%
394 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 70),
395 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 79),
396 // 5 docs with >= 80%
397 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 80),
398 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 90),
399 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 93),
400 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 99),
401 newDoc(NEW_SECURITY_HOTSPOTS_REVIEWED, 100));
403 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(NEW_SECURITY_HOTSPOTS_REVIEWED)).getFacets();
404 assertThat(facets.get(NEW_SECURITY_HOTSPOTS_REVIEWED)).containsExactly(
406 entry("30.0-50.0", 2L),
407 entry("50.0-70.0", 4L),
408 entry("70.0-80.0", 2L),
409 entry("80.0-*", 5L));
413 public void filter_on_quality_gate_status() {
415 newDoc(PROJECT1).setQualityGateStatus(OK.name()),
416 newDoc(PROJECT2).setQualityGateStatus(OK.name()),
417 newDoc(PROJECT3).setQualityGateStatus(ERROR.name()));
419 ProjectMeasuresQuery query = new ProjectMeasuresQuery().setQualityGateStatus(OK);
420 assertResults(query, PROJECT1, PROJECT2);
424 public void filter_on_languages() {
425 ComponentDto project4 = ComponentTesting.newPrivateProjectDto().setUuid("Project-4").setName("Project 4").setKey("key-4");
427 newDoc(PROJECT1).setLanguages(singletonList("java")),
428 newDoc(PROJECT2).setLanguages(singletonList("xoo")),
429 newDoc(PROJECT3).setLanguages(singletonList("xoo")),
430 newDoc(project4).setLanguages(asList("<null>", "java", "xoo")));
432 assertResults(new ProjectMeasuresQuery().setLanguages(newHashSet("java", "xoo")), PROJECT1, PROJECT2, PROJECT3, project4);
433 assertResults(new ProjectMeasuresQuery().setLanguages(newHashSet("java")), PROJECT1, project4);
434 assertResults(new ProjectMeasuresQuery().setLanguages(newHashSet("unknown")));
438 public void filter_on_query_text() {
439 ComponentDto windows = ComponentTesting.newPrivateProjectDto().setUuid("windows").setName("Windows").setKey("project1");
440 ComponentDto apachee = ComponentTesting.newPrivateProjectDto().setUuid("apachee").setName("apachee").setKey("project2");
441 ComponentDto apache1 = ComponentTesting.newPrivateProjectDto().setUuid("apache-1").setName("Apache").setKey("project3");
442 ComponentDto apache2 = ComponentTesting.newPrivateProjectDto().setUuid("apache-2").setName("Apache").setKey("project4");
443 index(newDoc(windows), newDoc(apachee), newDoc(apache1), newDoc(apache2));
445 assertResults(new ProjectMeasuresQuery().setQueryText("windows"), windows);
446 assertResults(new ProjectMeasuresQuery().setQueryText("project2"), apachee);
447 assertResults(new ProjectMeasuresQuery().setQueryText("pAch"), apache1, apache2, apachee);
451 public void filter_on_ids() {
457 ProjectMeasuresQuery query = new ProjectMeasuresQuery().setProjectUuids(newHashSet(PROJECT1.uuid(), PROJECT3.uuid()));
458 assertResults(query, PROJECT1, PROJECT3);
462 public void filter_on_tags() {
464 newDoc(PROJECT1).setTags(newArrayList("finance", "platform")),
465 newDoc(PROJECT2).setTags(newArrayList("marketing", "platform")),
466 newDoc(PROJECT3).setTags(newArrayList("finance", "language")));
468 assertResults(new ProjectMeasuresQuery().setTags(newHashSet("finance")), PROJECT1, PROJECT3);
469 assertResults(new ProjectMeasuresQuery().setTags(newHashSet("finance", "language")), PROJECT1, PROJECT3);
470 assertResults(new ProjectMeasuresQuery().setTags(newHashSet("finance", "marketing")), PROJECT1, PROJECT2, PROJECT3);
471 assertResults(new ProjectMeasuresQuery().setTags(newHashSet("marketing")), PROJECT2);
472 assertNoResults(new ProjectMeasuresQuery().setTags(newHashSet("tag 42")));
476 public void filter_on_qualifier() {
477 index(newDoc(PROJECT1), newDoc(PROJECT2), newDoc(PROJECT3),
478 newDoc(APP1), newDoc(APP2), newDoc(APP3));
480 assertResults(new ProjectMeasuresQuery(),
481 APP1, APP2, APP3, PROJECT1, PROJECT2, PROJECT3);
483 assertResults(new ProjectMeasuresQuery().setQualifiers(Sets.newHashSet(PROJECT, APP)),
484 APP1, APP2, APP3, PROJECT1, PROJECT2, PROJECT3);
486 assertResults(new ProjectMeasuresQuery().setQualifiers(Sets.newHashSet(PROJECT)),
487 PROJECT1, PROJECT2, PROJECT3);
489 assertResults(new ProjectMeasuresQuery().setQualifiers(Sets.newHashSet(APP)),
494 public void return_correct_number_of_total_if_exceeds_index_max_results() {
495 index(IntStream.range(0, 12_000)
496 .mapToObj(operand -> newDoc(ComponentTesting.newPrivateProjectDto()))
497 .toArray(ProjectMeasuresDoc[]::new));
499 ProjectMeasuresQuery query = new ProjectMeasuresQuery();
500 SearchIdResult<String> result = underTest.search(query, new SearchOptions());
501 assertThat(result.getTotal()).isEqualTo(12_000);
505 public void return_only_projects_and_applications_authorized_for_user() {
506 indexForUser(USER1, newDoc(PROJECT1), newDoc(PROJECT2),
507 newDoc(APP1), newDoc(APP2));
508 indexForUser(USER2, newDoc(PROJECT3), newDoc(APP3));
510 userSession.logIn(USER1);
511 assertResults(new ProjectMeasuresQuery(), APP1, APP2, PROJECT1, PROJECT2);
515 public void return_only_projects_and_applications_authorized_for_user_groups() {
516 indexForGroup(GROUP1, newDoc(PROJECT1), newDoc(PROJECT2),
517 newDoc(APP1), newDoc(APP2));
518 indexForGroup(GROUP2, newDoc(PROJECT3));
520 userSession.logIn().setGroups(GROUP1);
521 assertResults(new ProjectMeasuresQuery(), APP1, APP2, PROJECT1, PROJECT2);
525 public void return_only_projects_and_applications_authorized_for_user_and_groups() {
526 indexForUser(USER1, newDoc(PROJECT1), newDoc(PROJECT2),
527 newDoc(APP1), newDoc(APP2));
528 indexForGroup(GROUP1, newDoc(PROJECT3));
530 userSession.logIn(USER1).setGroups(GROUP1);
531 assertResults(new ProjectMeasuresQuery(), APP1, APP2, PROJECT1, PROJECT2, PROJECT3);
535 public void anonymous_user_can_only_access_projects_and_applications_authorized_for_anyone() {
536 index(newDoc(PROJECT1), newDoc(APP1));
537 indexForUser(USER1, newDoc(PROJECT2), newDoc(APP2));
539 userSession.anonymous();
540 assertResults(new ProjectMeasuresQuery(), APP1, PROJECT1);
544 public void return_all_projects_and_applications_when_setIgnoreAuthorization_is_true() {
545 indexForUser(USER1, newDoc(PROJECT1), newDoc(PROJECT2), newDoc(APP1), newDoc(APP2));
546 indexForUser(USER2, newDoc(PROJECT3), newDoc(APP3));
547 userSession.logIn(USER1);
549 assertResults(new ProjectMeasuresQuery().setIgnoreAuthorization(false), APP1, APP2, PROJECT1, PROJECT2);
550 assertResults(new ProjectMeasuresQuery().setIgnoreAuthorization(true), APP1, APP2, APP3, PROJECT1, PROJECT2, PROJECT3);
554 public void does_not_return_facet_when_no_facets_in_options() {
556 newDoc(PROJECT1, NCLOC, 10d, COVERAGE_KEY, 30d, MAINTAINABILITY_RATING, 3d)
557 .setQualityGateStatus(OK.name()));
559 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions()).getFacets();
561 assertThat(facets.getAll()).isEmpty();
565 public void facet_ncloc() {
567 // 3 docs with ncloc<1K
571 // 2 docs with ncloc>=1K and ncloc<10K
572 newDoc(NCLOC, 1_000d),
573 newDoc(NCLOC, 9_999d),
574 // 4 docs with ncloc>=10K and ncloc<100K
575 newDoc(NCLOC, 10_000d),
576 newDoc(NCLOC, 10_000d),
577 newDoc(NCLOC, 11_000d),
578 newDoc(NCLOC, 99_000d),
579 // 2 docs with ncloc>=100K and ncloc<500K
580 newDoc(NCLOC, 100_000d),
581 newDoc(NCLOC, 499_000d),
582 // 5 docs with ncloc>= 500K
583 newDoc(NCLOC, 500_000d),
584 newDoc(NCLOC, 100_000_000d),
585 newDoc(NCLOC, 500_000d),
586 newDoc(NCLOC, 1_000_000d),
587 newDoc(NCLOC, 100_000_000_000d));
589 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(NCLOC)).getFacets();
591 assertThat(facets.get(NCLOC)).containsExactly(
592 entry("*-1000.0", 3L),
593 entry("1000.0-10000.0", 2L),
594 entry("10000.0-100000.0", 4L),
595 entry("100000.0-500000.0", 2L),
596 entry("500000.0-*", 5L));
600 public void facet_ncloc_is_sticky() {
602 // 1 docs with ncloc<1K
603 newDoc(NCLOC, 999d, COVERAGE, 0d, DUPLICATION, 0d),
604 // 2 docs with ncloc>=1K and ncloc<10K
605 newDoc(NCLOC, 1_000d, COVERAGE, 10d, DUPLICATION, 0d),
606 newDoc(NCLOC, 9_999d, COVERAGE, 20d, DUPLICATION, 0d),
607 // 3 docs with ncloc>=10K and ncloc<100K
608 newDoc(NCLOC, 10_000d, COVERAGE, 31d, DUPLICATION, 0d),
609 newDoc(NCLOC, 11_000d, COVERAGE, 40d, DUPLICATION, 0d),
610 newDoc(NCLOC, 99_000d, COVERAGE, 50d, DUPLICATION, 0d),
611 // 2 docs with ncloc>=100K and ncloc<500K
612 newDoc(NCLOC, 100_000d, COVERAGE, 71d, DUPLICATION, 0d),
613 newDoc(NCLOC, 499_000d, COVERAGE, 80d, DUPLICATION, 0d),
614 // 1 docs with ncloc>= 500K
615 newDoc(NCLOC, 501_000d, COVERAGE, 81d, DUPLICATION, 20d));
617 Facets facets = underTest.search(new ProjectMeasuresQuery()
618 .addMetricCriterion(MetricCriterion.create(NCLOC, Operator.LT, 10_000d))
619 .addMetricCriterion(MetricCriterion.create(DUPLICATION, Operator.LT, 10d)),
620 new SearchOptions().addFacets(NCLOC, COVERAGE)).getFacets();
622 // Sticky facet on ncloc does not take into account ncloc filter
623 assertThat(facets.get(NCLOC)).containsExactly(
624 entry("*-1000.0", 1L),
625 entry("1000.0-10000.0", 2L),
626 entry("10000.0-100000.0", 3L),
627 entry("100000.0-500000.0", 2L),
628 entry("500000.0-*", 0L));
629 // But facet on coverage does well take into into filters
630 assertThat(facets.get(COVERAGE)).containsOnly(
631 entry("NO_DATA", 0L),
633 entry("30.0-50.0", 0L),
634 entry("50.0-70.0", 0L),
635 entry("70.0-80.0", 0L),
636 entry("80.0-*", 0L));
640 public void facet_ncloc_contains_only_projects_authorized_for_user() {
641 // User can see these projects
643 // docs with ncloc<1K
647 // docs with ncloc>=1K and ncloc<10K
648 newDoc(NCLOC, 1_000d),
649 newDoc(NCLOC, 9_999d));
651 // User cannot see these projects
653 // doc with ncloc>=10K and ncloc<100K
654 newDoc(NCLOC, 11_000d),
655 // doc with ncloc>=100K and ncloc<500K
656 newDoc(NCLOC, 499_000d),
657 // doc with ncloc>= 500K
658 newDoc(NCLOC, 501_000d));
660 userSession.logIn(USER1);
661 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(NCLOC)).getFacets();
663 assertThat(facets.get(NCLOC)).containsExactly(
664 entry("*-1000.0", 3L),
665 entry("1000.0-10000.0", 2L),
666 entry("10000.0-100000.0", 0L),
667 entry("100000.0-500000.0", 0L),
668 entry("500000.0-*", 0L));
672 public void facet_new_lines() {
674 // 3 docs with ncloc<1K
675 newDoc(NEW_LINES, 0d),
676 newDoc(NEW_LINES, 0d),
677 newDoc(NEW_LINES, 999d),
678 // 2 docs with ncloc>=1K and ncloc<10K
679 newDoc(NEW_LINES, 1_000d),
680 newDoc(NEW_LINES, 9_999d),
681 // 4 docs with ncloc>=10K and ncloc<100K
682 newDoc(NEW_LINES, 10_000d),
683 newDoc(NEW_LINES, 10_000d),
684 newDoc(NEW_LINES, 11_000d),
685 newDoc(NEW_LINES, 99_000d),
686 // 2 docs with ncloc>=100K and ncloc<500K
687 newDoc(NEW_LINES, 100_000d),
688 newDoc(NEW_LINES, 499_000d),
689 // 5 docs with ncloc>= 500K
690 newDoc(NEW_LINES, 500_000d),
691 newDoc(NEW_LINES, 100_000_000d),
692 newDoc(NEW_LINES, 500_000d),
693 newDoc(NEW_LINES, 1_000_000d),
694 newDoc(NEW_LINES, 100_000_000_000d));
696 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(NEW_LINES)).getFacets();
698 assertThat(facets.get(NEW_LINES)).containsExactly(
699 entry("*-1000.0", 3L),
700 entry("1000.0-10000.0", 2L),
701 entry("10000.0-100000.0", 4L),
702 entry("100000.0-500000.0", 2L),
703 entry("500000.0-*", 5L));
707 public void facet_coverage() {
709 // 1 doc with no coverage
710 newDocWithNoMeasure(),
711 // 3 docs with coverage<30%
712 newDoc(COVERAGE, 0d),
713 newDoc(COVERAGE, 0d),
714 newDoc(COVERAGE, 29d),
715 // 2 docs with coverage>=30% and coverage<50%
716 newDoc(COVERAGE, 30d),
717 newDoc(COVERAGE, 49d),
718 // 4 docs with coverage>=50% and coverage<70%
719 newDoc(COVERAGE, 50d),
720 newDoc(COVERAGE, 60d),
721 newDoc(COVERAGE, 60d),
722 newDoc(COVERAGE, 69d),
723 // 2 docs with coverage>=70% and coverage<80%
724 newDoc(COVERAGE, 70d),
725 newDoc(COVERAGE, 79d),
726 // 5 docs with coverage>= 80%
727 newDoc(COVERAGE, 80d),
728 newDoc(COVERAGE, 80d),
729 newDoc(COVERAGE, 90d),
730 newDoc(COVERAGE, 90.5d),
731 newDoc(COVERAGE, 100d));
733 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(COVERAGE)).getFacets();
735 assertThat(facets.get(COVERAGE)).containsOnly(
736 entry("NO_DATA", 1L),
738 entry("30.0-50.0", 2L),
739 entry("50.0-70.0", 4L),
740 entry("70.0-80.0", 2L),
741 entry("80.0-*", 5L));
745 public void facet_coverage_is_sticky() {
747 // docs with no coverage
748 newDoc(NCLOC, 999d, DUPLICATION, 0d),
749 newDoc(NCLOC, 999d, DUPLICATION, 1d),
750 newDoc(NCLOC, 999d, DUPLICATION, 20d),
751 // docs with coverage<30%
752 newDoc(NCLOC, 999d, COVERAGE, 0d, DUPLICATION, 0d),
753 newDoc(NCLOC, 1_000d, COVERAGE, 10d, DUPLICATION, 0d),
754 newDoc(NCLOC, 9_999d, COVERAGE, 20d, DUPLICATION, 0d),
755 // docs with coverage>=30% and coverage<50%
756 newDoc(NCLOC, 10_000d, COVERAGE, 31d, DUPLICATION, 0d),
757 newDoc(NCLOC, 11_000d, COVERAGE, 40d, DUPLICATION, 0d),
758 // docs with coverage>=50% and coverage<70%
759 newDoc(NCLOC, 99_000d, COVERAGE, 50d, DUPLICATION, 0d),
760 // docs with coverage>=70% and coverage<80%
761 newDoc(NCLOC, 100_000d, COVERAGE, 71d, DUPLICATION, 0d),
762 // docs with coverage>= 80%
763 newDoc(NCLOC, 499_000d, COVERAGE, 80d, DUPLICATION, 15d),
764 newDoc(NCLOC, 501_000d, COVERAGE, 810d, DUPLICATION, 20d));
766 Facets facets = underTest.search(new ProjectMeasuresQuery()
767 .addMetricCriterion(MetricCriterion.create(COVERAGE, Operator.LT, 30d))
768 .addMetricCriterion(MetricCriterion.create(DUPLICATION, Operator.LT, 10d)),
769 new SearchOptions().addFacets(COVERAGE, NCLOC)).getFacets();
771 // Sticky facet on coverage does not take into account coverage filter
772 assertThat(facets.get(COVERAGE)).containsExactly(
773 entry("NO_DATA", 2L),
775 entry("30.0-50.0", 2L),
776 entry("50.0-70.0", 1L),
777 entry("70.0-80.0", 1L),
778 entry("80.0-*", 0L));
779 // But facet on ncloc does well take into into filters
780 assertThat(facets.get(NCLOC)).containsExactly(
781 entry("*-1000.0", 1L),
782 entry("1000.0-10000.0", 2L),
783 entry("10000.0-100000.0", 0L),
784 entry("100000.0-500000.0", 0L),
785 entry("500000.0-*", 0L));
789 public void facet_coverage_contains_only_projects_authorized_for_user() {
790 // User can see these projects
792 // 1 doc with no coverage
793 newDocWithNoMeasure(),
794 // docs with coverage<30%
795 newDoc(COVERAGE, 0d),
796 newDoc(COVERAGE, 0d),
797 newDoc(COVERAGE, 29d),
798 // docs with coverage>=30% and coverage<50%
799 newDoc(COVERAGE, 30d),
800 newDoc(COVERAGE, 49d));
802 // User cannot see these projects
804 // 2 docs with no coverage
805 newDocWithNoMeasure(),
806 newDocWithNoMeasure(),
807 // docs with coverage>=50% and coverage<70%
808 newDoc(COVERAGE, 50d),
809 // docs with coverage>=70% and coverage<80%
810 newDoc(COVERAGE, 70d),
811 // docs with coverage>= 80%
812 newDoc(COVERAGE, 80d));
814 userSession.logIn(USER1);
815 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(COVERAGE)).getFacets();
817 assertThat(facets.get(COVERAGE)).containsExactly(
818 entry("NO_DATA", 1L),
820 entry("30.0-50.0", 2L),
821 entry("50.0-70.0", 0L),
822 entry("70.0-80.0", 0L),
823 entry("80.0-*", 0L));
827 public void facet_new_coverage() {
829 // 1 doc with no coverage
830 newDocWithNoMeasure(),
831 // 3 docs with coverage<30%
832 newDoc(NEW_COVERAGE, 0d),
833 newDoc(NEW_COVERAGE, 0d),
834 newDoc(NEW_COVERAGE, 29d),
835 // 2 docs with coverage>=30% and coverage<50%
836 newDoc(NEW_COVERAGE, 30d),
837 newDoc(NEW_COVERAGE, 49d),
838 // 4 docs with coverage>=50% and coverage<70%
839 newDoc(NEW_COVERAGE, 50d),
840 newDoc(NEW_COVERAGE, 60d),
841 newDoc(NEW_COVERAGE, 60d),
842 newDoc(NEW_COVERAGE, 69d),
843 // 2 docs with coverage>=70% and coverage<80%
844 newDoc(NEW_COVERAGE, 70d),
845 newDoc(NEW_COVERAGE, 79d),
846 // 5 docs with coverage>= 80%
847 newDoc(NEW_COVERAGE, 80d),
848 newDoc(NEW_COVERAGE, 80d),
849 newDoc(NEW_COVERAGE, 90d),
850 newDoc(NEW_COVERAGE, 90.5d),
851 newDoc(NEW_COVERAGE, 100d));
853 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(NEW_COVERAGE)).getFacets();
855 assertThat(facets.get(NEW_COVERAGE)).containsOnly(
856 entry("NO_DATA", 1L),
858 entry("30.0-50.0", 2L),
859 entry("50.0-70.0", 4L),
860 entry("70.0-80.0", 2L),
861 entry("80.0-*", 5L));
865 public void facet_duplicated_lines_density() {
867 // 1 doc with no duplication
868 newDocWithNoMeasure(),
869 // 3 docs with duplication<3%
870 newDoc(DUPLICATION, 0d),
871 newDoc(DUPLICATION, 0d),
872 newDoc(DUPLICATION, 2.9d),
873 // 2 docs with duplication>=3% and duplication<5%
874 newDoc(DUPLICATION, 3d),
875 newDoc(DUPLICATION, 4.9d),
876 // 4 docs with duplication>=5% and duplication<10%
877 newDoc(DUPLICATION, 5d),
878 newDoc(DUPLICATION, 6d),
879 newDoc(DUPLICATION, 6d),
880 newDoc(DUPLICATION, 9.9d),
881 // 2 docs with duplication>=10% and duplication<20%
882 newDoc(DUPLICATION, 10d),
883 newDoc(DUPLICATION, 19.9d),
884 // 5 docs with duplication>= 20%
885 newDoc(DUPLICATION, 20d),
886 newDoc(DUPLICATION, 20d),
887 newDoc(DUPLICATION, 50d),
888 newDoc(DUPLICATION, 80d),
889 newDoc(DUPLICATION, 100d));
891 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(DUPLICATION)).getFacets();
893 assertThat(facets.get(DUPLICATION)).containsOnly(
894 entry("NO_DATA", 1L),
896 entry("3.0-5.0", 2L),
897 entry("5.0-10.0", 4L),
898 entry("10.0-20.0", 2L),
899 entry("20.0-*", 5L));
903 public void facet_duplicated_lines_density_is_sticky() {
905 // docs with no duplication
906 newDoc(NCLOC, 50_001d, COVERAGE, 29d),
907 // docs with duplication<3%
908 newDoc(DUPLICATION, 0d, NCLOC, 999d, COVERAGE, 0d),
909 // docs with duplication>=3% and duplication<5%
910 newDoc(DUPLICATION, 3d, NCLOC, 5000d, COVERAGE, 0d),
911 newDoc(DUPLICATION, 4.9d, NCLOC, 6000d, COVERAGE, 0d),
912 // docs with duplication>=5% and duplication<10%
913 newDoc(DUPLICATION, 5d, NCLOC, 11000d, COVERAGE, 0d),
914 // docs with duplication>=10% and duplication<20%
915 newDoc(DUPLICATION, 10d, NCLOC, 120000d, COVERAGE, 10d),
916 newDoc(DUPLICATION, 19.9d, NCLOC, 130000d, COVERAGE, 20d),
917 // docs with duplication>= 20%
918 newDoc(DUPLICATION, 20d, NCLOC, 1000000d, COVERAGE, 40d));
920 Facets facets = underTest.search(new ProjectMeasuresQuery()
921 .addMetricCriterion(MetricCriterion.create(DUPLICATION, Operator.LT, 10d))
922 .addMetricCriterion(MetricCriterion.create(COVERAGE, Operator.LT, 30d)),
923 new SearchOptions().addFacets(DUPLICATION, NCLOC)).getFacets();
925 // Sticky facet on duplication does not take into account duplication filter
926 assertThat(facets.get(DUPLICATION)).containsOnly(
927 entry("NO_DATA", 1L),
929 entry("3.0-5.0", 2L),
930 entry("5.0-10.0", 1L),
931 entry("10.0-20.0", 2L),
932 entry("20.0-*", 0L));
933 // But facet on ncloc does well take into into filters
934 assertThat(facets.get(NCLOC)).containsOnly(
935 entry("*-1000.0", 1L),
936 entry("1000.0-10000.0", 2L),
937 entry("10000.0-100000.0", 1L),
938 entry("100000.0-500000.0", 0L),
939 entry("500000.0-*", 0L));
943 public void facet_duplicated_lines_density_contains_only_projects_authorized_for_user() {
944 // User can see these projects
946 // docs with no duplication
947 newDocWithNoMeasure(),
948 // docs with duplication<3%
949 newDoc(DUPLICATION, 0d),
950 newDoc(DUPLICATION, 0d),
951 newDoc(DUPLICATION, 2.9d),
952 // docs with duplication>=3% and duplication<5%
953 newDoc(DUPLICATION, 3d),
954 newDoc(DUPLICATION, 4.9d));
956 // User cannot see these projects
958 // docs with no duplication
959 newDocWithNoMeasure(),
960 newDocWithNoMeasure(),
961 // docs with duplication>=5% and duplication<10%
962 newDoc(DUPLICATION, 5d),
963 // docs with duplication>=10% and duplication<20%
964 newDoc(DUPLICATION, 10d),
965 // docs with duplication>= 20%
966 newDoc(DUPLICATION, 20d));
968 userSession.logIn(USER1);
969 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(DUPLICATION)).getFacets();
971 assertThat(facets.get(DUPLICATION)).containsOnly(
972 entry("NO_DATA", 1L),
974 entry("3.0-5.0", 2L),
975 entry("5.0-10.0", 0L),
976 entry("10.0-20.0", 0L),
977 entry("20.0-*", 0L));
981 public void facet_new_duplicated_lines_density() {
983 // 2 docs with no measure
984 newDocWithNoMeasure(),
985 newDocWithNoMeasure(),
986 // 3 docs with duplication<3%
987 newDoc(NEW_DUPLICATION, 0d),
988 newDoc(NEW_DUPLICATION, 0d),
989 newDoc(NEW_DUPLICATION, 2.9d),
990 // 2 docs with duplication>=3% and duplication<5%
991 newDoc(NEW_DUPLICATION, 3d),
992 newDoc(NEW_DUPLICATION, 4.9d),
993 // 4 docs with duplication>=5% and duplication<10%
994 newDoc(NEW_DUPLICATION, 5d),
995 newDoc(NEW_DUPLICATION, 6d),
996 newDoc(NEW_DUPLICATION, 6d),
997 newDoc(NEW_DUPLICATION, 9.9d),
998 // 2 docs with duplication>=10% and duplication<20%
999 newDoc(NEW_DUPLICATION, 10d),
1000 newDoc(NEW_DUPLICATION, 19.9d),
1001 // 5 docs with duplication>= 20%
1002 newDoc(NEW_DUPLICATION, 20d),
1003 newDoc(NEW_DUPLICATION, 20d),
1004 newDoc(NEW_DUPLICATION, 50d),
1005 newDoc(NEW_DUPLICATION, 80d),
1006 newDoc(NEW_DUPLICATION, 100d));
1008 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(NEW_DUPLICATION)).getFacets();
1010 assertThat(facets.get(NEW_DUPLICATION)).containsExactly(
1011 entry("NO_DATA", 2L),
1013 entry("3.0-5.0", 2L),
1014 entry("5.0-10.0", 4L),
1015 entry("10.0-20.0", 2L),
1016 entry("20.0-*", 5L));
1020 @UseDataProvider("rating_metric_keys")
1021 public void facet_on_rating(String metricKey) {
1023 // 3 docs with rating A
1024 newDoc(metricKey, 1d),
1025 newDoc(metricKey, 1d),
1026 newDoc(metricKey, 1d),
1027 // 2 docs with rating B
1028 newDoc(metricKey, 2d),
1029 newDoc(metricKey, 2d),
1030 // 4 docs with rating C
1031 newDoc(metricKey, 3d),
1032 newDoc(metricKey, 3d),
1033 newDoc(metricKey, 3d),
1034 newDoc(metricKey, 3d),
1035 // 2 docs with rating D
1036 newDoc(metricKey, 4d),
1037 newDoc(metricKey, 4d),
1038 // 5 docs with rating E
1039 newDoc(metricKey, 5d),
1040 newDoc(metricKey, 5d),
1041 newDoc(metricKey, 5d),
1042 newDoc(metricKey, 5d),
1043 newDoc(metricKey, 5d));
1045 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(metricKey)).getFacets();
1047 assertThat(facets.get(metricKey)).containsExactly(
1056 @UseDataProvider("rating_metric_keys")
1057 public void facet_on_rating_is_sticky(String metricKey) {
1059 // docs with rating A
1060 newDoc(metricKey, 1d, NCLOC, 100d, COVERAGE, 0d),
1061 newDoc(metricKey, 1d, NCLOC, 200d, COVERAGE, 0d),
1062 newDoc(metricKey, 1d, NCLOC, 999d, COVERAGE, 0d),
1063 // docs with rating B
1064 newDoc(metricKey, 2d, NCLOC, 2000d, COVERAGE, 0d),
1065 newDoc(metricKey, 2d, NCLOC, 5000d, COVERAGE, 0d),
1066 // docs with rating C
1067 newDoc(metricKey, 3d, NCLOC, 20000d, COVERAGE, 0d),
1068 newDoc(metricKey, 3d, NCLOC, 30000d, COVERAGE, 0d),
1069 newDoc(metricKey, 3d, NCLOC, 40000d, COVERAGE, 0d),
1070 newDoc(metricKey, 3d, NCLOC, 50000d, COVERAGE, 0d),
1071 // docs with rating D
1072 newDoc(metricKey, 4d, NCLOC, 120000d, COVERAGE, 0d),
1073 // docs with rating E
1074 newDoc(metricKey, 5d, NCLOC, 600000d, COVERAGE, 40d),
1075 newDoc(metricKey, 5d, NCLOC, 700000d, COVERAGE, 50d),
1076 newDoc(metricKey, 5d, NCLOC, 800000d, COVERAGE, 60d));
1078 Facets facets = underTest.search(new ProjectMeasuresQuery()
1079 .addMetricCriterion(MetricCriterion.create(metricKey, Operator.LT, 3d))
1080 .addMetricCriterion(MetricCriterion.create(COVERAGE, Operator.LT, 30d)),
1081 new SearchOptions().addFacets(metricKey, NCLOC)).getFacets();
1083 // Sticky facet on maintainability rating does not take into account maintainability rating filter
1084 assertThat(facets.get(metricKey)).containsExactly(
1090 // But facet on ncloc does well take into into filters
1091 assertThat(facets.get(NCLOC)).containsExactly(
1092 entry("*-1000.0", 3L),
1093 entry("1000.0-10000.0", 2L),
1094 entry("10000.0-100000.0", 0L),
1095 entry("100000.0-500000.0", 0L),
1096 entry("500000.0-*", 0L));
1100 @UseDataProvider("rating_metric_keys")
1101 public void facet_on_rating_contains_only_projects_authorized_for_user(String metricKey) {
1102 // User can see these projects
1104 // 3 docs with rating A
1105 newDoc(metricKey, 1d),
1106 newDoc(metricKey, 1d),
1107 newDoc(metricKey, 1d),
1108 // 2 docs with rating B
1109 newDoc(metricKey, 2d),
1110 newDoc(metricKey, 2d));
1112 // User cannot see these projects
1114 // docs with rating C
1115 newDoc(metricKey, 3d),
1116 // docs with rating D
1117 newDoc(metricKey, 4d),
1118 // docs with rating E
1119 newDoc(metricKey, 5d));
1121 userSession.logIn(USER1);
1122 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(metricKey)).getFacets();
1124 assertThat(facets.get(metricKey)).containsExactly(
1133 public void facet_quality_gate() {
1135 // 2 docs with QG OK
1136 newDoc().setQualityGateStatus(OK.name()),
1137 newDoc().setQualityGateStatus(OK.name()),
1138 // 4 docs with QG ERROR
1139 newDoc().setQualityGateStatus(ERROR.name()),
1140 newDoc().setQualityGateStatus(ERROR.name()),
1141 newDoc().setQualityGateStatus(ERROR.name()),
1142 newDoc().setQualityGateStatus(ERROR.name()));
1144 LinkedHashMap<String, Long> result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(ALERT_STATUS_KEY)).getFacets().get(ALERT_STATUS_KEY);
1146 assertThat(result).containsOnly(
1147 entry(ERROR.name(), 4L),
1148 entry(OK.name(), 2L),
1149 entry(WARN.name(), 0L));
1153 public void facet_quality_gate_is_sticky() {
1155 // 2 docs with QG OK
1156 newDoc(NCLOC, 10d, COVERAGE, 0d).setQualityGateStatus(OK.name()),
1157 newDoc(NCLOC, 10d, COVERAGE, 0d).setQualityGateStatus(OK.name()),
1158 // 4 docs with QG ERROR
1159 newDoc(NCLOC, 100d, COVERAGE, 0d).setQualityGateStatus(ERROR.name()),
1160 newDoc(NCLOC, 5000d, COVERAGE, 40d).setQualityGateStatus(ERROR.name()),
1161 newDoc(NCLOC, 12000d, COVERAGE, 50d).setQualityGateStatus(ERROR.name()),
1162 newDoc(NCLOC, 13000d, COVERAGE, 60d).setQualityGateStatus(ERROR.name()));
1164 Facets facets = underTest.search(new ProjectMeasuresQuery()
1165 .setQualityGateStatus(ERROR)
1166 .addMetricCriterion(MetricCriterion.create(COVERAGE, Operator.LT, 55d)),
1167 new SearchOptions().addFacets(ALERT_STATUS_KEY, NCLOC)).getFacets();
1169 // Sticky facet on quality gate does not take into account quality gate filter
1170 assertThat(facets.get(ALERT_STATUS_KEY)).containsOnly(
1171 entry(OK.name(), 2L),
1172 entry(ERROR.name(), 3L),
1173 entry(WARN.name(), 0L));
1174 // But facet on ncloc does well take into into filters
1175 assertThat(facets.get(NCLOC)).containsExactly(
1176 entry("*-1000.0", 1L),
1177 entry("1000.0-10000.0", 1L),
1178 entry("10000.0-100000.0", 1L),
1179 entry("100000.0-500000.0", 0L),
1180 entry("500000.0-*", 0L));
1184 public void facet_quality_gate_contains_only_projects_authorized_for_user() {
1185 // User can see these projects
1187 // 2 docs with QG OK
1188 newDoc().setQualityGateStatus(OK.name()),
1189 newDoc().setQualityGateStatus(OK.name()));
1191 // User cannot see these projects
1193 // 4 docs with QG ERROR
1194 newDoc().setQualityGateStatus(ERROR.name()),
1195 newDoc().setQualityGateStatus(ERROR.name()),
1196 newDoc().setQualityGateStatus(ERROR.name()),
1197 newDoc().setQualityGateStatus(ERROR.name()));
1199 userSession.logIn(USER1);
1200 LinkedHashMap<String, Long> result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(ALERT_STATUS_KEY)).getFacets().get(ALERT_STATUS_KEY);
1202 assertThat(result).containsOnly(
1203 entry(ERROR.name(), 0L),
1204 entry(OK.name(), 2L),
1205 entry(WARN.name(), 0L));
1209 public void facet_quality_gate_using_deprecated_warning() {
1211 // 2 docs with QG OK
1212 newDoc().setQualityGateStatus(OK.name()),
1213 newDoc().setQualityGateStatus(OK.name()),
1214 // 3 docs with QG WARN
1215 newDoc().setQualityGateStatus(WARN.name()),
1216 newDoc().setQualityGateStatus(WARN.name()),
1217 newDoc().setQualityGateStatus(WARN.name()),
1218 // 4 docs with QG ERROR
1219 newDoc().setQualityGateStatus(ERROR.name()),
1220 newDoc().setQualityGateStatus(ERROR.name()),
1221 newDoc().setQualityGateStatus(ERROR.name()),
1222 newDoc().setQualityGateStatus(ERROR.name()));
1224 LinkedHashMap<String, Long> result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(ALERT_STATUS_KEY)).getFacets().get(ALERT_STATUS_KEY);
1226 assertThat(result).containsOnly(
1227 entry(ERROR.name(), 4L),
1228 entry(WARN.name(), 3L),
1229 entry(OK.name(), 2L));
1233 public void facet_quality_gate_does_not_return_deprecated_warning_when_set_ignore_warning_is_true() {
1235 // 2 docs with QG OK
1236 newDoc().setQualityGateStatus(OK.name()),
1237 newDoc().setQualityGateStatus(OK.name()),
1238 // 4 docs with QG ERROR
1239 newDoc().setQualityGateStatus(ERROR.name()),
1240 newDoc().setQualityGateStatus(ERROR.name()),
1241 newDoc().setQualityGateStatus(ERROR.name()),
1242 newDoc().setQualityGateStatus(ERROR.name()));
1244 assertThat(underTest.search(new ProjectMeasuresQuery().setIgnoreWarning(true), new SearchOptions().addFacets(ALERT_STATUS_KEY)).getFacets().get(ALERT_STATUS_KEY)).containsOnly(
1245 entry(ERROR.name(), 4L),
1246 entry(OK.name(), 2L));
1247 assertThat(underTest.search(new ProjectMeasuresQuery().setIgnoreWarning(false), new SearchOptions().addFacets(ALERT_STATUS_KEY)).getFacets().get(ALERT_STATUS_KEY))
1249 entry(ERROR.name(), 4L),
1250 entry(WARN.name(), 0L),
1251 entry(OK.name(), 2L));
1255 public void facet_languages() {
1257 newDoc().setLanguages(singletonList("java")),
1258 newDoc().setLanguages(singletonList("java")),
1259 newDoc().setLanguages(singletonList("xoo")),
1260 newDoc().setLanguages(singletonList("xml")),
1261 newDoc().setLanguages(asList("<null>", "java")),
1262 newDoc().setLanguages(asList("<null>", "java", "xoo")));
1264 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(LANGUAGES)).getFacets();
1266 assertThat(facets.get(LANGUAGES)).containsOnly(
1267 entry("<null>", 2L),
1274 public void facet_languages_is_limited_to_10_languages() {
1276 newDoc().setLanguages(asList("<null>", "java", "xoo", "css", "cpp")),
1277 newDoc().setLanguages(asList("xml", "php", "python", "perl", "ruby")),
1278 newDoc().setLanguages(asList("js", "scala")));
1280 Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(LANGUAGES)).getFacets();
1282 assertThat(facets.get(LANGUAGES)).hasSize(10);
1286 public void facet_languages_is_sticky() {
1288 newDoc(NCLOC, 10d).setLanguages(singletonList("java")),
1289 newDoc(NCLOC, 10d).setLanguages(singletonList("java")),
1290 newDoc(NCLOC, 10d).setLanguages(singletonList("xoo")),
1291 newDoc(NCLOC, 100d).setLanguages(singletonList("xml")),
1292 newDoc(NCLOC, 100d).setLanguages(asList("<null>", "java")),
1293 newDoc(NCLOC, 5000d).setLanguages(asList("<null>", "java", "xoo")));
1295 Facets facets = underTest.search(
1296 new ProjectMeasuresQuery().setLanguages(ImmutableSet.of("java")),
1297 new SearchOptions().addFacets(LANGUAGES, NCLOC)).getFacets();
1299 // Sticky facet on language does not take into account language filter
1300 assertThat(facets.get(LANGUAGES)).containsOnly(
1301 entry("<null>", 2L),
1305 // But facet on ncloc does well take account into filters
1306 assertThat(facets.get(NCLOC)).containsExactly(
1307 entry("*-1000.0", 3L),
1308 entry("1000.0-10000.0", 1L),
1309 entry("10000.0-100000.0", 0L),
1310 entry("100000.0-500000.0", 0L),
1311 entry("500000.0-*", 0L));
1315 public void facet_languages_returns_more_than_10_languages_when_languages_filter_contains_value_not_in_top_10() {
1317 newDoc().setLanguages(asList("<null>", "java", "xoo", "css", "cpp")),
1318 newDoc().setLanguages(asList("xml", "php", "python", "perl", "ruby")),
1319 newDoc().setLanguages(asList("js", "scala")));
1321 Facets facets = underTest.search(new ProjectMeasuresQuery().setLanguages(ImmutableSet.of("xoo", "xml")), new SearchOptions().addFacets(LANGUAGES)).getFacets();
1323 assertThat(facets.get(LANGUAGES)).containsOnly(
1324 entry("<null>", 1L),
1331 entry("python", 1L),
1339 public void facet_languages_contains_only_projects_authorized_for_user() {
1340 // User can see these projects
1342 newDoc().setLanguages(singletonList("java")),
1343 newDoc().setLanguages(asList("java", "xoo")));
1345 // User cannot see these projects
1347 newDoc().setLanguages(singletonList("java")),
1348 newDoc().setLanguages(asList("java", "xoo")));
1350 userSession.logIn(USER1);
1351 LinkedHashMap<String, Long> result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(LANGUAGES)).getFacets().get(LANGUAGES);
1353 assertThat(result).containsOnly(
1359 public void facet_qualifier() {
1361 // 2 docs with qualifier APP
1362 newDoc().setQualifier(APP),
1363 newDoc().setQualifier(APP),
1364 // 4 docs with qualifier TRK
1365 newDoc().setQualifier(PROJECT),
1366 newDoc().setQualifier(PROJECT),
1367 newDoc().setQualifier(PROJECT),
1368 newDoc().setQualifier(PROJECT));
1370 LinkedHashMap<String, Long> result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(FILTER_QUALIFIER)).getFacets().get(FILTER_QUALIFIER);
1372 assertThat(result).containsOnly(
1374 entry(PROJECT, 4L));
1378 public void facet_qualifier_is_sticky() {
1380 // 2 docs with qualifier APP
1381 newDoc(NCLOC, 10d, COVERAGE, 0d).setQualifier(APP),
1382 newDoc(NCLOC, 10d, COVERAGE, 0d).setQualifier(APP),
1383 // 4 docs with qualifier TRK
1384 newDoc(NCLOC, 100d, COVERAGE, 0d).setQualifier(PROJECT),
1385 newDoc(NCLOC, 5000d, COVERAGE, 40d).setQualifier(PROJECT),
1386 newDoc(NCLOC, 12000d, COVERAGE, 50d).setQualifier(PROJECT),
1387 newDoc(NCLOC, 13000d, COVERAGE, 60d).setQualifier(PROJECT));
1389 Facets facets = underTest.search(new ProjectMeasuresQuery()
1390 .setQualifiers(Sets.newHashSet(PROJECT))
1391 .addMetricCriterion(MetricCriterion.create(COVERAGE, Operator.LT, 55d)),
1392 new SearchOptions().addFacets(FILTER_QUALIFIER, NCLOC)).getFacets();
1394 // Sticky facet on qualifier does not take into account qualifier filter
1395 assertThat(facets.get(FILTER_QUALIFIER)).containsOnly(
1397 entry(PROJECT, 3L));
1398 // But facet on ncloc does well take into into filters
1399 assertThat(facets.get(NCLOC)).containsExactly(
1400 entry("*-1000.0", 1L),
1401 entry("1000.0-10000.0", 1L),
1402 entry("10000.0-100000.0", 1L),
1403 entry("100000.0-500000.0", 0L),
1404 entry("500000.0-*", 0L));
1408 public void facet_qualifier_contains_only_app_and_projects_authorized_for_user() {
1409 // User can see these projects
1411 // 3 docs with qualifier APP, PROJECT
1412 newDoc().setQualifier(APP),
1413 newDoc().setQualifier(APP),
1414 newDoc().setQualifier(PROJECT));
1416 // User cannot see these projects
1418 // 4 docs with qualifier PROJECT
1419 newDoc().setQualifier(PROJECT),
1420 newDoc().setQualifier(PROJECT),
1421 newDoc().setQualifier(PROJECT),
1422 newDoc().setQualifier(PROJECT));
1424 userSession.logIn(USER1);
1425 LinkedHashMap<String, Long> result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(FILTER_QUALIFIER)).getFacets().get(FILTER_QUALIFIER);
1427 assertThat(result).containsOnly(
1429 entry(PROJECT, 1L));
1433 public void facet_tags() {
1435 newDoc().setTags(newArrayList("finance", "offshore", "java")),
1436 newDoc().setTags(newArrayList("finance", "javascript")),
1437 newDoc().setTags(newArrayList("marketing", "finance")),
1438 newDoc().setTags(newArrayList("marketing", "offshore")),
1439 newDoc().setTags(newArrayList("finance", "marketing")),
1440 newDoc().setTags(newArrayList("finance")));
1442 Map<String, Long> result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(FIELD_TAGS)).getFacets().get(FIELD_TAGS);
1444 assertThat(result).containsOnly(
1445 entry("finance", 5L),
1446 entry("marketing", 3L),
1447 entry("offshore", 2L),
1449 entry("javascript", 1L));
1453 public void facet_tags_is_sticky() {
1455 newDoc().setTags(newArrayList("finance")).setQualityGateStatus(OK.name()),
1456 newDoc().setTags(newArrayList("finance")).setQualityGateStatus(ERROR.name()),
1457 newDoc().setTags(newArrayList("cpp")).setQualityGateStatus(ERROR.name()));
1459 Facets facets = underTest.search(
1460 new ProjectMeasuresQuery().setTags(newHashSet("cpp")),
1461 new SearchOptions().addFacets(FIELD_TAGS).addFacets(ALERT_STATUS_KEY))
1464 assertThat(facets.get(FIELD_TAGS)).containsOnly(
1465 entry("finance", 2L),
1467 assertThat(facets.get(ALERT_STATUS_KEY)).containsOnly(
1468 entry(OK.name(), 0L),
1469 entry(ERROR.name(), 1L),
1470 entry(WARN.name(), 0L));
1474 public void facet_tags_returns_10_elements_by_default() {
1476 newDoc().setTags(newArrayList("finance1", "finance2", "finance3", "finance4", "finance5", "finance6", "finance7", "finance8", "finance9", "finance10")),
1477 newDoc().setTags(newArrayList("finance1", "finance2", "finance3", "finance4", "finance5", "finance6", "finance7", "finance8", "finance9", "finance10")),
1478 newDoc().setTags(newArrayList("solo")));
1480 Map<String, Long> result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(FIELD_TAGS)).getFacets().get(FIELD_TAGS);
1482 assertThat(result).hasSize(10).containsOnlyKeys("finance1", "finance2", "finance3", "finance4", "finance5", "finance6", "finance7", "finance8", "finance9", "finance10");
1486 public void facet_tags_returns_more_than_10_tags_when_tags_filter_contains_value_not_in_top_10() {
1488 newDoc().setTags(newArrayList("finance1", "finance2", "finance3", "finance4", "finance5", "finance6", "finance7", "finance8", "finance9", "finance10")),
1489 newDoc().setTags(newArrayList("finance1", "finance2", "finance3", "finance4", "finance5", "finance6", "finance7", "finance8", "finance9", "finance10")),
1490 newDoc().setTags(newArrayList("solo", "solo2")));
1492 Map<String, Long> result = underTest.search(new ProjectMeasuresQuery().setTags(ImmutableSet.of("solo", "solo2")), new SearchOptions().addFacets(FIELD_TAGS)).getFacets()
1495 assertThat(result).hasSize(12).containsOnlyKeys("finance1", "finance2", "finance3", "finance4", "finance5", "finance6", "finance7", "finance8", "finance9", "finance10", "solo",
1500 public void search_tags() {
1502 newDoc().setTags(newArrayList("finance", "offshore", "java")),
1503 newDoc().setTags(newArrayList("official", "javascript")),
1504 newDoc().setTags(newArrayList("marketing", "official")),
1505 newDoc().setTags(newArrayList("marketing", "Madhoff")),
1506 newDoc().setTags(newArrayList("finance", "offshore")),
1507 newDoc().setTags(newArrayList("offshore")));
1509 List<String> result = underTest.searchTags("off", 1,10);
1511 assertThat(result).containsOnly("offshore", "official", "Madhoff");
1515 public void search_tags_return_all_tags() {
1517 newDoc().setTags(newArrayList("finance", "offshore", "java")),
1518 newDoc().setTags(newArrayList("official", "javascript")),
1519 newDoc().setTags(newArrayList("marketing", "official")),
1520 newDoc().setTags(newArrayList("marketing", "Madhoff")),
1521 newDoc().setTags(newArrayList("finance", "offshore")),
1522 newDoc().setTags(newArrayList("offshore")));
1524 List<String> result = underTest.searchTags(null, 1, 10);
1526 assertThat(result).containsOnly("offshore", "official", "Madhoff", "finance", "marketing", "java", "javascript");
1530 public void search_tags_in_lexical_order() {
1532 newDoc().setTags(newArrayList("finance", "offshore", "java")),
1533 newDoc().setTags(newArrayList("official", "javascript")),
1534 newDoc().setTags(newArrayList("marketing", "official")),
1535 newDoc().setTags(newArrayList("marketing", "Madhoff")),
1536 newDoc().setTags(newArrayList("finance", "offshore")),
1537 newDoc().setTags(newArrayList("offshore")));
1539 List<String> result = underTest.searchTags(null, 1,10);
1541 assertThat(result).containsExactly("Madhoff", "finance", "java", "javascript", "marketing", "official", "offshore");
1545 public void search_tags_follows_paging() {
1547 newDoc().setTags(newArrayList("finance", "offshore", "java")),
1548 newDoc().setTags(newArrayList("official", "javascript")),
1549 newDoc().setTags(newArrayList("marketing", "official")),
1550 newDoc().setTags(newArrayList("marketing", "Madhoff")),
1551 newDoc().setTags(newArrayList("finance", "offshore")),
1552 newDoc().setTags(newArrayList("offshore")));
1554 List<String> result = underTest.searchTags(null, 1,3);
1555 assertThat(result).containsExactly("Madhoff", "finance", "java");
1557 result = underTest.searchTags(null, 2,3);
1558 assertThat(result).containsExactly("javascript", "marketing", "official");
1560 result = underTest.searchTags(null, 3,3);
1561 assertThat(result).containsExactly("offshore");
1563 result = underTest.searchTags(null, 3,4);
1564 assertThat(result).isEmpty();
1568 public void search_tags_returns_nothing_if_page_too_large() {
1570 newDoc().setTags(newArrayList("finance", "offshore", "java")),
1571 newDoc().setTags(newArrayList("official", "javascript")),
1572 newDoc().setTags(newArrayList("marketing", "official")),
1573 newDoc().setTags(newArrayList("marketing", "Madhoff")),
1574 newDoc().setTags(newArrayList("finance", "offshore")),
1575 newDoc().setTags(newArrayList("offshore")));
1577 List<String> result = underTest.searchTags(null, 10,2);
1579 assertThat(result).isEmpty();
1583 public void search_tags_only_of_authorized_projects() {
1585 newDoc(PROJECT1).setTags(singletonList("finance")),
1586 newDoc(PROJECT2).setTags(singletonList("marketing")));
1588 newDoc(PROJECT3).setTags(singletonList("offshore")));
1590 userSession.logIn(USER1);
1592 List<String> result = underTest.searchTags(null, 1,10);
1594 assertThat(result).containsOnly("finance", "marketing");
1598 public void search_tags_with_no_tags() {
1599 List<String> result = underTest.searchTags("whatever", 1,10);
1601 assertThat(result).isEmpty();
1605 public void search_tags_with_page_size_at_0() {
1606 index(newDoc().setTags(newArrayList("offshore")));
1608 List<String> result = underTest.searchTags(null, 1,0);
1610 assertThat(result).isEmpty();
1614 public void search_statistics() {
1615 es.putDocuments(TYPE_PROJECT_MEASURES,
1616 newDoc("lines", 10, "coverage", 80)
1617 .setLanguages(Arrays.asList("java", "cs", "js"))
1618 .setNclocLanguageDistributionFromMap(ImmutableMap.of("java", 200, "cs", 250, "js", 50)),
1619 newDoc("lines", 20, "coverage", 80)
1620 .setLanguages(Arrays.asList("java", "python", "kotlin"))
1621 .setNclocLanguageDistributionFromMap(ImmutableMap.of("java", 300, "python", 100, "kotlin", 404)));
1623 ProjectMeasuresStatistics result = underTest.searchSupportStatistics();
1625 assertThat(result.getProjectCount()).isEqualTo(2);
1626 assertThat(result.getProjectCountByLanguage()).containsOnly(
1627 entry("java", 2L), entry("cs", 1L), entry("js", 1L), entry("python", 1L), entry("kotlin", 1L));
1628 assertThat(result.getNclocByLanguage()).containsOnly(
1629 entry("java", 500L), entry("cs", 250L), entry("js", 50L), entry("python", 100L), entry("kotlin", 404L));
1633 public void search_statistics_for_large_instances() {
1634 int nbProjects = 25000;
1635 int javaLocByProjects = 100;
1636 int jsLocByProjects = 900;
1637 int csLocByProjects = 2;
1639 ProjectMeasuresDoc[] documents = IntStream.range(0, nbProjects).mapToObj(i ->
1640 newDoc("lines", 10, "coverage", 80)
1641 .setLanguages(asList("java", "cs", "js"))
1642 .setNclocLanguageDistributionFromMap(ImmutableMap.of("java", javaLocByProjects, "cs", csLocByProjects, "js", jsLocByProjects))).toArray(ProjectMeasuresDoc[]::new);
1644 es.putDocuments(TYPE_PROJECT_MEASURES, documents);
1646 ProjectMeasuresStatistics result = underTest.searchSupportStatistics();
1648 assertThat(result.getProjectCount()).isEqualTo(nbProjects);
1649 assertThat(result.getProjectCountByLanguage())
1651 .containsEntry("java", (long) nbProjects)
1652 .containsEntry("cs", (long) nbProjects)
1653 .containsEntry("js", (long) nbProjects);
1655 assertThat(result.getNclocByLanguage())
1657 .containsEntry("java",(long) nbProjects * javaLocByProjects)
1658 .containsEntry("cs",(long) nbProjects * csLocByProjects)
1659 .containsEntry("js",(long) nbProjects * jsLocByProjects);
1663 public void search_statistics_should_ignore_applications() {
1664 es.putDocuments(TYPE_PROJECT_MEASURES,
1666 newDoc(ComponentTesting.newPrivateProjectDto(), "lines", 10, "coverage", 80)
1667 .setLanguages(Arrays.asList("java", "cs", "js"))
1668 .setNclocLanguageDistributionFromMap(ImmutableMap.of("java", 200, "cs", 250, "js", 50)),
1669 newDoc(ComponentTesting.newPrivateProjectDto(), "lines", 20, "coverage", 80)
1670 .setLanguages(Arrays.asList("java", "python", "kotlin"))
1671 .setNclocLanguageDistributionFromMap(ImmutableMap.of("java", 300, "python", 100, "kotlin", 404)),
1673 // insert applications
1674 newDoc(ComponentTesting.newApplication(), "lines", 1000, "coverage", 70)
1675 .setLanguages(Arrays.asList("java", "python", "kotlin"))
1676 .setNclocLanguageDistributionFromMap(ImmutableMap.of("java", 300, "python", 100, "kotlin", 404)),
1677 newDoc(ComponentTesting.newApplication(), "lines", 20, "coverage", 80)
1678 .setLanguages(Arrays.asList("java", "python", "kotlin"))
1679 .setNclocLanguageDistributionFromMap(ImmutableMap.of("java", 300, "python", 100, "kotlin", 404)));
1681 ProjectMeasuresStatistics result = underTest.searchSupportStatistics();
1683 assertThat(result.getProjectCount()).isEqualTo(2);
1684 assertThat(result.getProjectCountByLanguage()).containsOnly(
1685 entry("java", 2L), entry("cs", 1L), entry("js", 1L), entry("python", 1L), entry("kotlin", 1L));
1686 assertThat(result.getNclocByLanguage()).containsOnly(
1687 entry("java", 500L), entry("cs", 250L), entry("js", 50L), entry("python", 100L), entry("kotlin", 404L));
1691 public void search_statistics_should_count_0_if_no_projects() {
1692 es.putDocuments(TYPE_PROJECT_MEASURES,
1693 // insert applications
1694 newDoc(ComponentTesting.newApplication(), "lines", 1000, "coverage", 70)
1695 .setLanguages(Arrays.asList("java", "python", "kotlin"))
1696 .setNclocLanguageDistributionFromMap(ImmutableMap.of("java", 300, "python", 100, "kotlin", 404)),
1697 newDoc(ComponentTesting.newApplication(), "lines", 20, "coverage", 80)
1698 .setLanguages(Arrays.asList("java", "python", "kotlin"))
1699 .setNclocLanguageDistributionFromMap(ImmutableMap.of("java", 300, "python", 100, "kotlin", 404)));
1701 ProjectMeasuresStatistics result = underTest.searchSupportStatistics();
1703 assertThat(result.getProjectCount()).isZero();
1704 assertThat(result.getProjectCountByLanguage()).isEmpty();
1708 public void fail_if_page_size_greater_than_100() {
1709 assertThatThrownBy(() -> underTest.searchTags("whatever", 1, 101))
1710 .isInstanceOf(IllegalArgumentException.class)
1711 .hasMessageContaining("Page size must be lower than or equals to 100");
1715 public void fail_if_page_greater_than_20() {
1716 assertThatThrownBy(() -> underTest.searchTags("whatever", 21, 100))
1717 .isInstanceOf(IllegalArgumentException.class)
1718 .hasMessageContaining("Page must be between 0 and 20");
1721 private void index(ProjectMeasuresDoc... docs) {
1722 es.putDocuments(TYPE_PROJECT_MEASURES, docs);
1723 authorizationIndexer.allow(stream(docs).map(doc -> new IndexPermissions(doc.getId(), PROJECT).allowAnyone()).collect(toList()));
1726 private void indexForUser(UserDto user, ProjectMeasuresDoc... docs) {
1727 es.putDocuments(TYPE_PROJECT_MEASURES, docs);
1728 authorizationIndexer.allow(stream(docs).map(doc -> new IndexPermissions(doc.getId(), PROJECT).addUserUuid(user.getUuid())).collect(toList()));
1731 private void indexForGroup(GroupDto group, ProjectMeasuresDoc... docs) {
1732 es.putDocuments(TYPE_PROJECT_MEASURES, docs);
1733 authorizationIndexer.allow(stream(docs).map(doc -> new IndexPermissions(doc.getId(), PROJECT).addGroupUuid(group.getUuid())).collect(toList()));
1736 private static ProjectMeasuresDoc newDoc(ComponentDto project) {
1737 return new ProjectMeasuresDoc()
1738 .setId(project.uuid())
1739 .setKey(project.getKey())
1740 .setName(project.name())
1741 .setQualifier(project.qualifier());
1744 private static ProjectMeasuresDoc newDoc() {
1745 return newDoc(ComponentTesting.newPrivateProjectDto());
1748 private static ProjectMeasuresDoc newDoc(ComponentDto project, String metric1, Object value1) {
1749 return newDoc(project).setMeasures(newArrayList(newMeasure(metric1, value1)));
1752 private static ProjectMeasuresDoc newDoc(ComponentDto project, String metric1, Object value1, String metric2, Object value2) {
1753 return newDoc(project).setMeasures(newArrayList(newMeasure(metric1, value1), newMeasure(metric2, value2)));
1756 private static ProjectMeasuresDoc newDoc(ComponentDto project, String metric1, Object value1, String metric2, Object value2, String metric3, Object value3) {
1757 return newDoc(project).setMeasures(newArrayList(newMeasure(metric1, value1), newMeasure(metric2, value2), newMeasure(metric3, value3)));
1760 private static Map<String, Object> newMeasure(String key, Object value) {
1761 return ImmutableMap.of("key", key, "value", value);
1764 private static ProjectMeasuresDoc newDocWithNoMeasure() {
1765 return newDoc(ComponentTesting.newPrivateProjectDto());
1768 private static ProjectMeasuresDoc newDoc(String metric1, Object value1) {
1769 return newDoc(ComponentTesting.newPrivateProjectDto(), metric1, value1);
1772 private static ProjectMeasuresDoc newDoc(String metric1, Object value1, String metric2, Object value2) {
1773 return newDoc(ComponentTesting.newPrivateProjectDto(), metric1, value1, metric2, value2);
1776 private static ProjectMeasuresDoc newDoc(String metric1, Object value1, String metric2, Object value2, String metric3, Object value3) {
1777 return newDoc(ComponentTesting.newPrivateProjectDto(), metric1, value1, metric2, value2, metric3, value3);
1780 private void assertResults(ProjectMeasuresQuery query, ComponentDto... expectedProjects) {
1781 List<String> result = underTest.search(query, new SearchOptions()).getUuids();
1782 assertThat(result).containsExactly(Arrays.stream(expectedProjects).map(ComponentDto::uuid).toArray(String[]::new));
1785 private void assertNoResults(ProjectMeasuresQuery query) {
1786 assertResults(query);