1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078 |
- /*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
- package org.sonar.server.rule.ws;
-
- import java.time.Clock;
- import java.time.Instant;
- import java.time.OffsetDateTime;
- import java.time.ZoneId;
- import java.time.format.DateTimeFormatter;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Optional;
- import java.util.Set;
- import java.util.function.Consumer;
- import java.util.function.Function;
- import java.util.stream.Collectors;
- import javax.annotation.Nullable;
- import org.junit.Before;
- import org.junit.Test;
- import org.sonar.api.impl.utils.AlwaysIncreasingSystem2;
- import org.sonar.api.resources.Languages;
- import org.sonar.api.rule.RuleKey;
- import org.sonar.api.rule.RuleStatus;
- import org.sonar.api.rules.RuleType;
- import org.sonar.api.server.debt.DebtRemediationFunction;
- import org.sonar.api.server.ws.WebService;
- import org.sonar.api.utils.System2;
- import org.sonar.core.util.UuidFactory;
- import org.sonar.core.util.UuidFactoryFast;
- import org.sonar.db.DbTester;
- import org.sonar.db.qualityprofile.ActiveRuleParamDto;
- import org.sonar.db.qualityprofile.QProfileDto;
- import org.sonar.db.rule.RuleDescriptionSectionContextDto;
- import org.sonar.db.rule.RuleDescriptionSectionDto;
- import org.sonar.db.rule.RuleDto;
- import org.sonar.db.rule.RuleParamDto;
- import org.sonar.db.user.UserDto;
- import org.sonar.server.es.EsTester;
- import org.sonar.server.exceptions.NotFoundException;
- import org.sonar.server.language.LanguageTesting;
- import org.sonar.server.pushapi.qualityprofile.QualityProfileChangeEventService;
- import org.sonar.server.qualityprofile.ActiveRuleChange;
- import org.sonar.server.qualityprofile.QProfileRules;
- import org.sonar.server.qualityprofile.QProfileRulesImpl;
- import org.sonar.server.qualityprofile.RuleActivation;
- import org.sonar.server.qualityprofile.builtin.RuleActivator;
- import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
- import org.sonar.server.rule.RuleDescriptionFormatter;
- import org.sonar.server.rule.index.RuleIndex;
- import org.sonar.server.rule.index.RuleIndexer;
- import org.sonar.server.tester.UserSessionRule;
- import org.sonar.server.text.MacroInterpreter;
- import org.sonar.server.util.IntegerTypeValidation;
- import org.sonar.server.util.StringTypeValidation;
- import org.sonar.server.util.TypeValidations;
- import org.sonar.server.ws.TestRequest;
- import org.sonar.server.ws.WsActionTester;
- import org.sonarqube.ws.Common;
- import org.sonarqube.ws.Rules;
- import org.sonarqube.ws.Rules.Rule;
- import org.sonarqube.ws.Rules.SearchResponse;
-
- import static java.util.Arrays.asList;
- import static java.util.Arrays.stream;
- import static java.util.Collections.emptySet;
- import static java.util.Collections.singleton;
- import static java.util.Collections.singletonList;
- import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
- import static org.assertj.core.api.Assertions.assertThat;
- import static org.assertj.core.api.Assertions.assertThatThrownBy;
- import static org.assertj.core.api.Assertions.tuple;
- import static org.assertj.guava.api.Assertions.entry;
- import static org.mockito.ArgumentMatchers.anyString;
- import static org.mockito.Mockito.doReturn;
- import static org.mockito.Mockito.mock;
- import static org.mockito.Mockito.when;
- import static org.sonar.api.rule.Severity.BLOCKER;
- import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.RESOURCES_SECTION_KEY;
- import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection;
- import static org.sonar.db.rule.RuleTesting.newRule;
- import static org.sonar.db.rule.RuleTesting.newRuleWithoutDescriptionSection;
- import static org.sonar.db.rule.RuleTesting.setSystemTags;
- import static org.sonar.db.rule.RuleTesting.setTags;
- import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVATION;
- import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_COMPARE_TO_PROFILE;
- import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_QPROFILE;
- import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_RULE_KEY;
- import static org.sonarqube.ws.Rules.Rule.DescriptionSection.Context.newBuilder;
-
- public class SearchActionIT {
-
- private static final String JAVA = "java";
-
- @org.junit.Rule
- public UserSessionRule userSession = UserSessionRule.standalone();
-
- private final System2 system2 = new AlwaysIncreasingSystem2();
- @org.junit.Rule
- public DbTester db = DbTester.create(system2);
- @org.junit.Rule
- public EsTester es = EsTester.create();
-
- private final RuleIndex ruleIndex = new RuleIndex(es.client(), system2);
- private final RuleIndexer ruleIndexer = new RuleIndexer(es.client(), db.getDbClient());
- private final ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(db.getDbClient(), es.client());
- private final Languages languages = LanguageTesting.newLanguages(JAVA, "js");
- private final ActiveRuleCompleter activeRuleCompleter = new ActiveRuleCompleter(db.getDbClient(), languages);
- private final RuleQueryFactory ruleQueryFactory = new RuleQueryFactory(db.getDbClient());
- private final MacroInterpreter macroInterpreter = mock(MacroInterpreter.class);
- private final QualityProfileChangeEventService qualityProfileChangeEventService = mock(QualityProfileChangeEventService.class);
- private final RuleMapper ruleMapper = new RuleMapper(languages, macroInterpreter, new RuleDescriptionFormatter());
- private final SearchAction underTest = new SearchAction(ruleIndex, activeRuleCompleter, ruleQueryFactory, db.getDbClient(), ruleMapper,
- new RuleWsSupport(db.getDbClient(), userSession));
- private final TypeValidations typeValidations = new TypeValidations(asList(new StringTypeValidation(), new IntegerTypeValidation()));
- private final RuleActivator ruleActivator = new RuleActivator(System2.INSTANCE, db.getDbClient(), typeValidations, userSession);
- private final QProfileRules qProfileRules = new QProfileRulesImpl(db.getDbClient(), ruleActivator, ruleIndex, activeRuleIndexer,
- qualityProfileChangeEventService);
- private final WsActionTester ws = new WsActionTester(underTest);
- private final UuidFactory uuidFactory = UuidFactoryFast.getInstance();
-
- @Before
- public void before() {
- doReturn("interpreted").when(macroInterpreter).interpret(anyString());
- }
-
- @Test
- public void test_definition() {
- WebService.Action def = ws.getDef();
-
- assertThat(def.isPost()).isFalse();
- assertThat(def.since()).isEqualTo("4.4");
- assertThat(def.isInternal()).isFalse();
- assertThat(def.responseExampleAsString()).isNotEmpty();
- assertThat(def.params()).hasSize(28);
-
- WebService.Param compareToProfile = def.param("compareToProfile");
- assertThat(compareToProfile.since()).isEqualTo("6.5");
- assertThat(compareToProfile.isRequired()).isFalse();
- assertThat(compareToProfile.isInternal()).isTrue();
- assertThat(compareToProfile.description()).isEqualTo("Quality profile key to filter rules that are activated. Meant to compare easily to profile set in 'qprofile'");
- }
-
- @Test
- public void return_empty_result() {
- Rules.SearchResponse response = ws.newRequest()
- .setParam(WebService.Param.FIELDS, "actives")
- .executeProtobuf(Rules.SearchResponse.class);
-
- assertThat(response.getPaging().getTotal()).isZero();
- assertThat(response.getPaging().getPageIndex()).isOne();
- assertThat(response.getPaging().getPageSize()).isNotZero();
- assertThat(response.getRulesCount()).isZero();
- }
-
- @Test
- public void return_all_rules() {
- RuleDto rule1 = db.rules().insert(r1 -> r1.setLanguage("java").setNoteUserUuid(null));
- RuleDto rule2 = db.rules().insert(r1 -> r1.setLanguage("java").setNoteUserUuid(null));
- indexRules();
-
- verify(r -> {
- }, rule1, rule2);
- }
-
- @Test
- public void return_note_login() {
- UserDto user1 = db.users().insertUser();
- RuleDto rule1 = db.rules().insert(r -> r.setNoteUserUuid(user1.getUuid()));
- UserDto disableUser = db.users().insertDisabledUser();
- RuleDto rule2 = db.rules().insert(r -> r.setNoteUserUuid(disableUser.getUuid()));
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("f", "noteLogin")
- .executeProtobuf(SearchResponse.class);
-
- assertThat(result.getRulesList())
- .extracting(Rule::getKey, Rule::getNoteLogin)
- .containsExactlyInAnyOrder(
- tuple(rule1.getKey().toString(), user1.getLogin()),
- tuple(rule2.getKey().toString(), disableUser.getLogin()));
- }
-
- @Test
- public void dont_fail_if_note_author_no_longer_exists() {
- // note: this can only happen due to DB corruption (user deleted)
- RuleDto rule1 = db.rules().insert(r -> r.setNoteUserUuid("non-existent"));
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("f", "noteLogin")
- .executeProtobuf(SearchResponse.class);
-
- assertThat(result.getRulesList())
- .extracting(Rule::getKey, Rule::getNoteLogin)
- .containsExactlyInAnyOrder(
- tuple(rule1.getKey().toString(), ""));
- }
-
- @Test
- public void filter_by_rule_key() {
- RuleDto rule1 = db.rules().insert(r1 -> r1.setLanguage("java").setNoteUserUuid(null));
- db.rules().insert(r1 -> r1.setLanguage("java").setNoteUserUuid(null));
- indexRules();
-
- verify(r -> r.setParam(PARAM_RULE_KEY, rule1.getKey().toString()), rule1);
- verifyNoResults(r -> r.setParam(PARAM_RULE_KEY, "missing"));
- }
-
- @Test
- public void filter_by_rule_name() {
- RuleDto rule1 = db.rules().insert(r1 -> r1.setName("Best rule ever").setNoteUserUuid(null));
- RuleDto rule2 = db.rules().insert(r1 -> r1.setName("Some other stuff").setNoteUserUuid(null));
- indexRules();
-
- verify(r -> r.setParam("q", "Be"), rule1);
- verify(r -> r.setParam("q", "Bes"), rule1);
- verify(r -> r.setParam("q", "Best"), rule1);
- verify(r -> r.setParam("q", "Best "), rule1);
- verify(r -> r.setParam("q", "Best rule"), rule1);
- verify(r -> r.setParam("q", "Best rule eve"), rule1);
- verify(r -> r.setParam("q", "Best rule ever"), rule1);
- verify(r -> r.setParam("q", "ru ev"), rule1);
- verify(r -> r.setParam("q", "ru ever"), rule1);
- verify(r -> r.setParam("q", "ev ve ver ru le"), rule1);
- verify(r -> r.setParam("q", "other"), rule2);
- }
-
- @Test
- public void filter_by_rule_name_requires_all_words_to_match() {
- RuleDto rule1 = db.rules().insert(r1 -> r1.setName("Best rule ever").setNoteUserUuid(null));
- RuleDto rule2 = db.rules().insert(r1 -> r1.setName("Some other stuff").setNoteUserUuid(null));
- indexRules();
-
- verify(r -> r.setParam("q", "Best other"));
- verify(r -> r.setParam("q", "Best rule"), rule1);
- verify(r -> r.setParam("q", "rule ever"), rule1);
- }
-
- @Test
- public void filter_by_rule_name_does_not_interpret_query() {
- RuleDto rule1 = db.rules().insert(r1 -> r1.setName("Best rule for-ever").setNoteUserUuid(null));
- RuleDto rule2 = db.rules().insert(r1 -> r1.setName("Some other stuff").setNoteUserUuid(null));
- indexRules();
-
- // do not interpret "-" as a "not"
- verify(r -> r.setParam("q", "-ever"), rule1);
- }
-
- @Test
- public void filter_by_rule_description() {
- RuleDto rule1 = db.rules().insert(
- newRule(createDefaultRuleDescriptionSection(uuidFactory.create(), "This is the <bold>best</bold> rule now&for<b>ever</b>"))
- .setNoteUserUuid(null));
- db.rules().insert(r1 -> r1.setName("Some other stuff").setNoteUserUuid(null));
- indexRules();
-
- verify(r -> r.setParam("q", "Best "), rule1);
- verify(r -> r.setParam("q", "bold"));
- verify(r -> r.setParam("q", "now&forever"), rule1);
- }
-
- @Test
- public void filter_with_context_specific_rule_description() {
- RuleDescriptionSectionDto section1context1 = createRuleDescriptionSectionWithContext(RESOURCES_SECTION_KEY, "<div>I want to fix with Spring</div>", "ctx1");
- RuleDescriptionSectionDto section1context2 = createRuleDescriptionSectionWithContext(RESOURCES_SECTION_KEY, "<div>Another context</div>", "ctx2");
-
- RuleDto ruleDto = newRuleWithoutDescriptionSection()
- .setNoteUserUuid(null)
- .addRuleDescriptionSectionDto(section1context1)
- .addRuleDescriptionSectionDto(section1context2);
- db.rules().insert(ruleDto);
- indexRules();
-
- verify(r -> r.setParam("q", "Spring "), ruleDto);
- verify(r -> r.setParam("q", "bold"));
- verify(r -> r.setParam("q", "context"), ruleDto);
- }
-
- @Test
- public void filter_by_rule_name_or_descriptions_requires_all_words_to_match_anywhere() {
- RuleDto rule1 = db.rules().insert(newRuleWithoutDescriptionSection().setName("Best rule ever").setNoteUserUuid(null)
- .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "This is a good rule")));
- db.rules().insert(newRuleWithoutDescriptionSection().setName("Another thing").setNoteUserUuid(null)
- .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Another thing")));
- indexRules();
-
- verify(r -> r.setParam("q", "Best good"), rule1);
- verify(r -> r.setParam("q", "Best Another"));
- }
-
- @Test
- public void return_all_rule_fields_by_default() {
- OffsetDateTime dateTime = OffsetDateTime.now(Clock.fixed(Instant.ofEpochMilli(1687816800000L), ZoneId.systemDefault()));
-
- RuleDto rule = db.rules().insert(
- r -> r.setCreatedAt(dateTime.toInstant().toEpochMilli()),
- r -> r.setUpdatedAt(dateTime.toInstant().toEpochMilli()),
- r -> r.setGapDescription("Gap Description"),
- r -> r.setIsTemplate(true),
- r -> r.setName("Name"),
- r -> r.setRepositoryKey("repo_key"),
- r -> r.setSeverity("MINOR"),
- r -> r.setLanguage("java")
- );
- indexRules();
-
- Rules.SearchResponse response = ws.newRequest().executeProtobuf(Rules.SearchResponse.class);
- Rules.Rule result = response.getRules(0);
- assertThat(result.getCreatedAt()).isEqualTo(dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ")));
- assertThat(result.getUpdatedAt()).isEqualTo(dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ")));
- assertThat(result.getGapDescription()).isEqualTo("Gap Description");
- assertThat(result.hasIsTemplate()).isTrue();
- assertThat(result.getName()).isEqualTo("Name");
- assertThat(result.getRepo()).isEqualTo("repo_key");
- assertThat(result.getSeverity()).isEqualTo("MINOR");
- assertThat(result.getType().name()).isEqualTo(RuleType.valueOf(rule.getType()).name());
- assertThat(result.getLang()).isEqualTo("java");
- }
-
- @Test
- public void return_subset_of_fields() {
- RuleDto rule = db.rules().insert(r -> r.setLanguage("java"));
- indexRules();
-
- Rules.SearchResponse response = ws.newRequest()
- .setParam(WebService.Param.FIELDS, "createdAt,langName,educationPrinciples")
- .executeProtobuf(Rules.SearchResponse.class);
- Rules.Rule result = response.getRules(0);
-
- // mandatory fields
- assertThat(result.getKey()).isEqualTo(rule.getKey().toString());
- assertThat(result.getType().getNumber()).isEqualTo(rule.getType());
-
- // selected fields
- assertThat(result.getCreatedAt()).isNotEmpty();
- assertThat(result.getLangName()).isNotEmpty();
- assertThat(result.getEducationPrinciples().getEducationPrinciplesList()).containsExactlyElementsOf(rule.getEducationPrinciples());
-
- // not returned fields
- assertThat(result.hasGapDescription()).isFalse();
- assertThat(result.hasHtmlDesc()).isFalse();
- assertThat(result.hasIsTemplate()).isFalse();
- assertThat(result.hasLang()).isFalse();
- assertThat(result.hasName()).isFalse();
- assertThat(result.hasSeverity()).isFalse();
- assertThat(result.hasRepo()).isFalse();
- assertThat(result.hasUpdatedAt()).isFalse();
- }
-
- @Test
- public void return_deprecatedKeys_in_response_on_demand() {
- RuleDto rule1 = db.rules().insert(r -> r.setLanguage("java"));
- db.rules().insertDeprecatedKey(r -> r.setRuleUuid(rule1.getUuid()).setOldRuleKey("oldrulekey").setOldRepositoryKey("oldrepositorykey"));
- db.rules().insertDeprecatedKey(r -> r.setRuleUuid(rule1.getUuid()).setOldRuleKey("oldrulekey2").setOldRepositoryKey("oldrepositorykey2"));
- RuleDto rule2 = db.rules().insert(r -> r.setLanguage("javascript"));
-
- indexRules();
-
- Rules.SearchResponse response = ws.newRequest()
- .setParam(WebService.Param.FIELDS, "deprecatedKeys")
- .executeProtobuf(Rules.SearchResponse.class);
-
- System.err.println(response.getRulesList());
-
- assertThat(response.getRulesList()).satisfies(l -> {
- assertThat(l).hasSize(2);
-
- assertThat(l).anySatisfy(e -> {
- assertThat(e.getKey()).isEqualTo(rule1.getKey().toString());
- assertThat(e.getType().getNumber()).isEqualTo(rule1.getType());
- assertThat(e.getDeprecatedKeys()).isNotNull();
- assertThat(e.getDeprecatedKeys().getDeprecatedKeyList()).contains("oldrepositorykey:oldrulekey", "oldrepositorykey2:oldrulekey2");
- });
- assertThat(l).anySatisfy(e -> {
- assertThat(e.getKey()).isEqualTo(rule2.getKey().toString());
- assertThat(e.getType().getNumber()).isEqualTo(rule2.getType());
- assertThat(e.getDeprecatedKeys()).isNotNull();
- assertThat(e.getDeprecatedKeys().getDeprecatedKeyList()).isEmpty();
- });
- });
- }
-
- @Test
- public void should_filter_on_specific_tags() {
- RuleDto rule1 = db.rules().insert(r -> r.setLanguage("java").setTags(Set.of("tag1", "tag2")));
- db.rules().insert(r -> r.setLanguage("java"));
- indexRules();
-
- Consumer<TestRequest> request = r -> r
- .setParam("f", "repo,name")
- .setParam("tags", rule1.getTags().stream().collect(Collectors.joining(",")));
- verify(request, rule1);
- }
-
- @Test
- public void when_searching_for_several_tags_combine_them_with_OR() {
- RuleDto bothTagsRule = db.rules().insert(r -> r.setLanguage("java"), setTags("tag1", "tag2"));
- RuleDto oneTagRule = db.rules().insert(r -> r.setLanguage("java"), setTags("tag1"));
- RuleDto otherTagRule = db.rules().insert(r -> r.setLanguage("java"), setTags("tag2"));
- db.rules().insert(r -> r.setLanguage("java"), setTags());
- indexRules();
-
- Consumer<TestRequest> request = r -> r
- .setParam("f", "repo,name")
- .setParam("tags", "tag1,tag2");
- verify(request, bothTagsRule, oneTagRule, otherTagRule);
- }
-
- @Test
- public void should_list_tags_in_tags_facet() {
- String[] tags = get101Tags();
- db.rules().insert(setSystemTags("x"), setTags(tags));
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("f", "repo,name")
- .setParam("facets", "tags")
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getFacets().getFacets(0).getValuesList()).extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
- .contains(tuple("tag0", 1L), tuple("tag25", 1L), tuple("tag99", 1L))
- .doesNotContain(tuple("x", 1L));
- }
-
- @Test
- public void should_list_tags_ordered_by_count_then_by_name_in_tags_facet() {
- db.rules().insert(setSystemTags("tag7", "tag5", "tag3", "tag1", "tag9"), setTags("tag2", "tag4", "tag6", "tag8", "tagA"));
- db.rules().insert(setSystemTags("tag2"), setTags());
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("f", "repo,name")
- .setParam("facets", "tags")
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getFacets().getFacets(0).getValuesList()).extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
- .containsExactly(tuple("tag2", 2L), tuple("tag1", 1L), tuple("tag3", 1L), tuple("tag4", 1L), tuple("tag5", 1L), tuple("tag6", 1L), tuple("tag7", 1L), tuple("tag8", 1L),
- tuple("tag9", 1L), tuple("tagA", 1L));
- }
-
- @Test
- public void should_include_selected_matching_tag_in_facet() {
- db.rules().insert(
- setSystemTags("tag1", "tag2", "tag3", "tag4", "tag5", "tag6", "tag7", "tag8", "tag9", "tagA", "x"),
- r -> r.setNoteUserUuid(null));
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("facets", "tags")
- .setParam("tags", "x")
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getFacets().getFacets(0).getValuesList()).extracting(v -> entry(v.getVal(), v.getCount())).contains(entry("x", 1L));
- }
-
- @Test
- public void should_included_selected_non_matching_tag_in_facet() {
- RuleDto rule = db.rules().insert(setSystemTags("tag1", "tag2", "tag3", "tag4", "tag5", "tag6", "tag7", "tag8", "tag9", "tagA"));
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("facets", "tags")
- .setParam("tags", "x")
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getFacets().getFacets(0).getValuesList()).extracting(v -> entry(v.getVal(), v.getCount())).contains(entry("x", 0L));
- }
-
- @Test
- public void should_return_specific_tags() {
- RuleDto rule = db.rules().insert(r -> r.setLanguage("java"), setTags("tag1", "tag2"));
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("f", "tags")
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getRulesList()).extracting(Rule::getKey).containsExactly(rule.getKey().toString());
- assertThat(result.getRulesList())
- .extracting(Rule::getTags).flatExtracting(Rules.Tags::getTagsList)
- .containsExactly(rule.getTags().toArray(new String[0]));
- }
-
- @Test
- public void should_return_specified_fields() {
- when(macroInterpreter.interpret(anyString())).thenAnswer(invocation -> invocation.getArgument(0));
-
- RuleDescriptionSectionDto section1context1 = createRuleDescriptionSectionWithContext(RESOURCES_SECTION_KEY, "<div>I want to fix with Spring</div>", "ctx1");
- RuleDescriptionSectionDto section1context2 = createRuleDescriptionSectionWithContext(RESOURCES_SECTION_KEY, "<div>Another context</div>", "ctx2");
- RuleDto rule = newRuleWithoutDescriptionSection()
- .setLanguage("java")
- .addRuleDescriptionSectionDto(section1context1)
- .addRuleDescriptionSectionDto(section1context2);
- db.rules().insert(rule);
- indexRules();
-
- checkField(rule, "repo", Rule::getRepo, rule.getRepositoryKey());
- checkField(rule, "name", Rule::getName, rule.getName());
- checkField(rule, "severity", Rule::getSeverity, rule.getSeverityString());
- checkField(rule, "status", r -> r.getStatus().toString(), rule.getStatus().toString());
- checkField(rule, "internalKey", Rule::getInternalKey, rule.getConfigKey());
- checkField(rule, "isTemplate", Rule::getIsTemplate, rule.isTemplate());
- checkField(rule, "sysTags",
- r -> r.getSysTags().getSysTagsList().stream().collect(Collectors.joining(",")),
- rule.getSystemTags().stream().collect(Collectors.joining(",")));
- checkField(rule, "lang", Rule::getLang, rule.getLanguage());
- checkField(rule, "langName", Rule::getLangName, languages.get(rule.getLanguage()).getName());
- checkField(rule, "gapDescription", Rule::getGapDescription, rule.getGapDescription());
- checkDescriptionSections(rule, rule.getRuleDescriptionSectionDtos().stream()
- .map(SearchActionIT::toProtobufDto)
- .collect(Collectors.toSet())
- );
- }
-
- private RuleDescriptionSectionDto createRuleDescriptionSectionWithContext(String key, String content, @Nullable String contextKey) {
- RuleDescriptionSectionContextDto contextDto = Optional.ofNullable(contextKey)
- .map(c -> RuleDescriptionSectionContextDto.of(contextKey, contextKey + " display name"))
- .orElse(null);
- return RuleDescriptionSectionDto.builder()
- .uuid(uuidFactory.create())
- .key(key)
- .content(content)
- .context(contextDto)
- .build();
- }
-
- private static Rule.DescriptionSection toProtobufDto(RuleDescriptionSectionDto section) {
- Rule.DescriptionSection.Builder builder = Rule.DescriptionSection.newBuilder().setKey(section.getKey()).setContent(section.getContent());
- if (section.getContext() != null) {
- RuleDescriptionSectionContextDto context = section.getContext();
- builder.setContext(newBuilder().setKey(context.getKey()).setDisplayName(context.getDisplayName()).build());
- }
- return builder.build();
- }
-
- @Test
- public void return_lang_key_field_when_language_name_is_not_available() {
- String unknownLanguage = "unknown_" + randomAlphanumeric(5);
- RuleDto rule = db.rules().insert(r -> r.setLanguage(unknownLanguage));
-
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("f", "langName")
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getPaging().getTotal()).isOne();
- assertThat(result.getPaging().getPageIndex()).isOne();
- assertThat(result.getRulesCount()).isOne();
-
- Rule searchedRule = result.getRules(0);
- assertThat(searchedRule).isNotNull();
- assertThat(searchedRule.getLangName()).isEqualTo(unknownLanguage);
- }
-
- @Test
- public void search_debt_rules_with_default_and_overridden_debt_values() {
- db.rules().insert(r -> r.setLanguage("java")
- .setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name())
- .setDefRemediationGapMultiplier("1h")
- .setDefRemediationBaseEffort("15min")
- .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name())
- .setRemediationGapMultiplier("2h")
- .setRemediationBaseEffort("25min"));
-
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("f", "debtRemFn,remFnOverloaded,defaultDebtRemFn")
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getPaging().getTotal()).isOne();
- assertThat(result.getPaging().getPageIndex()).isOne();
- assertThat(result.getRulesCount()).isOne();
-
- Rule searchedRule = result.getRules(0);
- assertThat(searchedRule).isNotNull();
- assertThat(searchedRule.getDefaultRemFnGapMultiplier()).isEqualTo("1h");
- assertThat(searchedRule.getDefaultRemFnBaseEffort()).isEqualTo("15min");
- assertThat(searchedRule.getDefaultDebtRemFnType()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET.name());
- assertThat(searchedRule.getDefaultRemFnBaseEffort()).isEqualTo("15min");
- assertThat(searchedRule.getDefaultRemFnGapMultiplier()).isEqualTo("1h");
- assertThat(searchedRule.getDefaultRemFnType()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET.name());
- assertThat(searchedRule.getRemFnOverloaded()).isTrue();
- assertThat(searchedRule.getRemFnGapMultiplier()).isEqualTo("2h");
- assertThat(searchedRule.getRemFnBaseEffort()).isEqualTo("25min");
- assertThat(searchedRule.getDebtRemFnType()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET.name());
- }
-
- @Test
- public void search_debt_rules_with_default_linear_offset_and_overridden_constant_debt() {
- db.rules().insert(r -> r.setLanguage("java")
- .setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name())
- .setDefRemediationGapMultiplier("1h")
- .setDefRemediationBaseEffort("15min")
- .setRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE.name())
- .setRemediationGapMultiplier(null)
- .setRemediationBaseEffort("5min"));
-
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("f", "debtRemFn,remFnOverloaded,defaultDebtRemFn")
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getPaging().getTotal()).isOne();
- assertThat(result.getPaging().getPageIndex()).isOne();
- assertThat(result.getRulesCount()).isOne();
-
- Rule searchedRule = result.getRules(0);
- assertThat(searchedRule).isNotNull();
- assertThat(searchedRule.getDefaultRemFnGapMultiplier()).isEqualTo("1h");
- assertThat(searchedRule.getDefaultRemFnBaseEffort()).isEqualTo("15min");
- assertThat(searchedRule.getDefaultDebtRemFnType()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET.name());
- assertThat(searchedRule.getDefaultRemFnBaseEffort()).isEqualTo("15min");
- assertThat(searchedRule.getDefaultRemFnGapMultiplier()).isEqualTo("1h");
- assertThat(searchedRule.getDefaultRemFnType()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET.name());
- assertThat(searchedRule.getRemFnOverloaded()).isTrue();
- assertThat(searchedRule.getRemFnGapMultiplier()).isEmpty();
- assertThat(searchedRule.getRemFnBaseEffort()).isEqualTo("5min");
- assertThat(searchedRule.getDebtRemFnType()).isEqualTo(DebtRemediationFunction.Type.CONSTANT_ISSUE.name());
- }
-
- @Test
- public void search_debt_rules_with_default_linear_offset_and_overridden_linear_debt() {
- db.rules().insert(r -> r.setLanguage("java")
- .setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name())
- .setDefRemediationGapMultiplier("1h")
- .setDefRemediationBaseEffort("15min")
- .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.name())
- .setRemediationGapMultiplier("1h")
- .setRemediationBaseEffort(null));
-
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("f", "debtRemFn,remFnOverloaded,defaultDebtRemFn")
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getPaging().getTotal()).isOne();
- assertThat(result.getPaging().getPageIndex()).isOne();
- assertThat(result.getRulesCount()).isOne();
-
- Rule searchedRule = result.getRules(0);
- assertThat(searchedRule).isNotNull();
- assertThat(searchedRule.getDefaultRemFnGapMultiplier()).isEqualTo("1h");
- assertThat(searchedRule.getDefaultRemFnBaseEffort()).isEqualTo("15min");
- assertThat(searchedRule.getDefaultDebtRemFnType()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET.name());
- assertThat(searchedRule.getDefaultRemFnBaseEffort()).isEqualTo("15min");
- assertThat(searchedRule.getDefaultRemFnGapMultiplier()).isEqualTo("1h");
- assertThat(searchedRule.getDefaultRemFnType()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET.name());
- assertThat(searchedRule.getRemFnOverloaded()).isTrue();
- assertThat(searchedRule.getRemFnGapMultiplier()).isEqualTo("1h");
- assertThat(searchedRule.getRemFnBaseEffort()).isEmpty();
- assertThat(searchedRule.getDebtRemFnType()).isEqualTo(DebtRemediationFunction.Type.LINEAR.name());
- }
-
- @Test
- public void search_template_rules() {
- RuleDto templateRule = db.rules().insert(r -> r.setLanguage("java")
- .setIsTemplate(true));
- RuleDto rule = db.rules().insert(r -> r.setLanguage("java")
- .setTemplateUuid(templateRule.getUuid()));
-
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("f", "isTemplate")
- .setParam("is_template", "true")
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getPaging().getTotal()).isOne();
- assertThat(result.getPaging().getPageIndex()).isOne();
- assertThat(result.getRulesCount()).isOne();
-
- Rule searchedRule = result.getRules(0);
- assertThat(searchedRule).isNotNull();
- assertThat(searchedRule.getIsTemplate()).isTrue();
- assertThat(searchedRule.getKey()).isEqualTo(templateRule.getRepositoryKey() + ":" + templateRule.getRuleKey());
- }
-
- @Test
- public void search_custom_rules_from_template_key() {
- RuleDto templateRule = db.rules().insert(r -> r.setLanguage("java")
- .setIsTemplate(true));
- RuleDto rule = db.rules().insert(r -> r.setLanguage("java")
- .setTemplateUuid(templateRule.getUuid()));
-
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("f", "templateKey")
- .setParam("template_key", templateRule.getRepositoryKey() + ":" + templateRule.getRuleKey())
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getPaging().getTotal()).isOne();
- assertThat(result.getPaging().getPageIndex()).isOne();
- assertThat(result.getRulesCount()).isOne();
-
- Rule searchedRule = result.getRules(0);
- assertThat(searchedRule).isNotNull();
- assertThat(searchedRule.getKey()).isEqualTo(rule.getRepositoryKey() + ":" + rule.getRuleKey());
- assertThat(searchedRule.getTemplateKey()).isEqualTo(templateRule.getRepositoryKey() + ":" + templateRule.getRuleKey());
- }
-
- @Test
- public void do_not_return_external_rule() {
- db.rules().insert(r -> r.setIsExternal(true));
- indexRules();
-
- SearchResponse result = ws.newRequest().executeProtobuf(SearchResponse.class);
-
- assertThat(result.getPaging().getTotal()).isZero();
- assertThat(result.getPaging().getPageIndex()).isOne();
- assertThat(result.getRulesCount()).isZero();
- }
-
- @Test
- public void search_all_active_rules() {
- QProfileDto profile = db.qualityProfiles().insert(p -> p.setLanguage("java"));
- RuleDto rule = db.rules().insert(r -> r.setLanguage("java").setNoteUserUuid(null));
- RuleActivation activation = RuleActivation.create(rule.getUuid(), BLOCKER, null);
- qProfileRules.activateAndCommit(db.getSession(), profile, singleton(activation));
-
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("q", rule.getName())
- .setParam("activation", "true")
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getPaging().getTotal()).isOne();
- assertThat(result.getPaging().getPageIndex()).isOne();
- assertThat(result.getRulesCount()).isOne();
-
- Rule searchedRule = result.getRules(0);
- assertThat(searchedRule).isNotNull();
- assertThat(searchedRule.getKey()).isEqualTo(rule.getRepositoryKey() + ":" + rule.getRuleKey());
- assertThat(searchedRule.getName()).isEqualTo(rule.getName());
- }
-
- @Test
- public void search_profile_active_rules() {
- QProfileDto profile = db.qualityProfiles().insert(p -> p.setLanguage("java"));
- QProfileDto waterproofProfile = db.qualityProfiles().insert(p -> p.setLanguage("java"));
- RuleDto rule = db.rules().insert(r -> r.setLanguage("java"));
- RuleParamDto ruleParam1 = db.rules().insertRuleParam(rule, p -> p.setDefaultValue("some value")
- .setType("STRING")
- .setDescription("My small description")
- .setName("my_var"));
-
- RuleParamDto ruleParam2 = db.rules().insertRuleParam(rule, p -> p.setDefaultValue("1")
- .setType("INTEGER")
- .setDescription("My small description")
- .setName("the_var"));
-
- // SONAR-7083
- RuleParamDto ruleParam3 = db.rules().insertRuleParam(rule, p -> p.setDefaultValue(null)
- .setType("STRING")
- .setDescription("Empty Param")
- .setName("empty_var"));
-
- RuleActivation activation = RuleActivation.create(rule.getUuid());
- List<ActiveRuleChange> activeRuleChanges1 = qProfileRules.activateAndCommit(db.getSession(), profile, singleton(activation));
- qProfileRules.activateAndCommit(db.getSession(), waterproofProfile, singleton(activation));
- assertThat(activeRuleChanges1).hasSize(1);
- indexRules();
- indexActiveRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("f", "actives")
- .setParam("q", rule.getName())
- .setParam("activation", "true")
- .setParam("qprofile", profile.getKee())
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getPaging().getTotal()).isOne();
- assertThat(result.getPaging().getPageIndex()).isOne();
- assertThat(result.getRulesCount()).isOne();
- assertThat(result.getActives()).isNotNull();
- assertThat(result.getActives().getActives().get(rule.getKey().toString())).isNotNull();
- assertThat(result.getActives().getActives().get(rule.getKey().toString()).getActiveListList()).hasSize(1);
-
- // The rule without value is not inserted
- Rules.Active activeList = result.getActives().getActives().get(rule.getKey().toString()).getActiveList(0);
- assertThat(activeList.getParamsCount()).isEqualTo(2);
- assertThat(activeList.getParamsList()).extracting("key", "value").containsExactlyInAnyOrder(
- tuple(ruleParam1.getName(), ruleParam1.getDefaultValue()),
- tuple(ruleParam2.getName(), ruleParam2.getDefaultValue()));
-
- String unknownProfile = "unknown_profile" + randomAlphanumeric(5);
-
- assertThatThrownBy(() -> {
- ws.newRequest()
- .setParam("activation", "true")
- .setParam("qprofile", unknownProfile)
- .executeProtobuf(SearchResponse.class);
- })
- .isInstanceOf(NotFoundException.class)
- .hasMessage("The specified qualityProfile '" + unknownProfile + "' does not exist");
- }
-
- @Test
- public void search_for_active_rules_when_parameter_value_is_null() {
- QProfileDto profile = db.qualityProfiles().insert(p -> p.setLanguage("java"));
-
- RuleDto rule = db.rules().insert(r -> r.setLanguage("java"));
-
- RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setDefaultValue("some value")
- .setType("STRING")
- .setDescription("My small description")
- .setName("my_var"));
-
- RuleActivation activation = RuleActivation.create(rule.getUuid());
- List<ActiveRuleChange> activeRuleChanges = qProfileRules.activateAndCommit(db.getSession(), profile, singleton(activation));
-
- // Insert directly in database a rule parameter with a null value
- ActiveRuleParamDto activeRuleParam = ActiveRuleParamDto.createFor(ruleParam).setValue(null);
- db.getDbClient().activeRuleDao().insertParam(db.getSession(), activeRuleChanges.get(0).getActiveRule(), activeRuleParam);
-
- db.commit();
-
- indexRules();
- indexActiveRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("f", "actives")
- .setParam("q", rule.getName())
- .setParam("activation", "true")
- .setParam("qprofile", profile.getKee())
- .executeProtobuf(SearchResponse.class);
-
- assertThat(result.getPaging().getTotal()).isOne();
- assertThat(result.getPaging().getPageIndex()).isOne();
- assertThat(result.getRulesCount()).isOne();
- assertThat(result.getActives()).isNotNull();
- assertThat(result.getActives().getActives().get(rule.getKey().toString())).isNotNull();
- assertThat(result.getActives().getActives().get(rule.getKey().toString()).getActiveListList()).hasSize(1);
-
- Rules.Active activeList = result.getActives().getActives().get(rule.getKey().toString()).getActiveList(0);
- assertThat(activeList.getParamsCount()).isEqualTo(2);
- assertThat(activeList.getParamsList()).extracting("key", "value").containsExactlyInAnyOrder(
- tuple(ruleParam.getName(), ruleParam.getDefaultValue()),
- tuple(activeRuleParam.getKey(), ""));
- }
-
- /**
- * When the user searches for inactive rules (for example for to "activate more"), then
- * only rules of the quality profiles' language are relevant
- */
- @Test
- public void facet_filtering_when_searching_for_inactive_rules() {
- QProfileDto profile = db.qualityProfiles().insert(q -> q.setLanguage("language1"));
-
- // on same language, not activated => match
- RuleDto rule1 = db.rules().insert(r -> r
- .setLanguage(profile.getLanguage())
- .setRepositoryKey("repositoryKey1")
- .setSystemTags(new HashSet<>(singletonList("tag1")))
- .setTags(emptySet())
- .setSeverity("CRITICAL")
- .setNoteUserUuid(null)
- .setStatus(RuleStatus.BETA)
- .setType(RuleType.CODE_SMELL));
-
- // on same language, activated => no match
- RuleDto rule2 = db.rules().insert(r -> r
- .setLanguage(profile.getLanguage())
- .setRepositoryKey("repositoryKey2")
- .setSystemTags(new HashSet<>(singletonList("tag2")))
- .setTags(emptySet())
- .setSeverity("MAJOR")
- .setNoteUserUuid(null)
- .setStatus(RuleStatus.DEPRECATED)
- .setType(RuleType.VULNERABILITY));
- RuleActivation activation = RuleActivation.create(rule2.getUuid(), null, null);
- qProfileRules.activateAndCommit(db.getSession(), profile, singleton(activation));
-
- // on other language, not activated => no match
- RuleDto rule3 = db.rules().insert(r -> r
- .setLanguage("language3")
- .setRepositoryKey("repositoryKey3")
- .setSystemTags(new HashSet<>(singletonList("tag3")))
- .setTags(emptySet())
- .setNoteUserUuid(null)
- .setSeverity("BLOCKER")
- .setStatus(RuleStatus.READY)
- .setType(RuleType.BUG));
-
- indexRules();
- indexActiveRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("facets", "languages,repositories,tags,severities,statuses,types")
- .setParam("activation", "false")
- .setParam("qprofile", profile.getKee())
- .executeProtobuf(SearchResponse.class);
-
- assertThat(result.getRulesList())
- .extracting(Rule::getKey)
- .containsExactlyInAnyOrder(
- rule1.getKey().toString());
-
- assertThat(result.getFacets().getFacetsList().stream().filter(f -> "languages".equals(f.getProperty())).findAny().get().getValuesList())
- .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
- .as("Facet languages")
- .containsExactlyInAnyOrder(
- tuple(rule1.getLanguage(), 1L),
-
- // known limitation: irrelevant languages are shown in this case (SONAR-9683)
- tuple(rule3.getLanguage(), 1L));
-
- assertThat(result.getFacets().getFacetsList().stream().filter(f -> "tags".equals(f.getProperty())).findAny().get().getValuesList())
- .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
- .as("Facet tags")
- .containsExactlyInAnyOrder(
- tuple(rule1.getSystemTags().iterator().next(), 1L));
-
- assertThat(result.getFacets().getFacetsList().stream().filter(f -> "repositories".equals(f.getProperty())).findAny().get().getValuesList())
- .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
- .as("Facet repositories")
- .containsExactlyInAnyOrder(
- tuple(rule1.getRepositoryKey(), 1L));
-
- assertThat(result.getFacets().getFacetsList().stream().filter(f -> "severities".equals(f.getProperty())).findAny().get().getValuesList())
- .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
- .as("Facet severities")
- .containsExactlyInAnyOrder(
- tuple("BLOCKER" /* rule2 */, 0L),
- tuple("CRITICAL"/* rule1 */, 1L),
- tuple("MAJOR", 0L),
- tuple("MINOR", 0L),
- tuple("INFO", 0L));
-
- assertThat(result.getFacets().getFacetsList().stream().filter(f -> "statuses".equals(f.getProperty())).findAny().get().getValuesList())
- .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
- .as("Facet statuses")
- .containsExactlyInAnyOrder(
- tuple("READY"/* rule2 */, 0L),
- tuple("BETA" /* rule1 */, 1L),
- tuple("DEPRECATED", 0L));
-
- assertThat(result.getFacets().getFacetsList().stream().filter(f -> "types".equals(f.getProperty())).findAny().get().getValuesList())
- .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
- .as("Facet types")
- .containsExactlyInAnyOrder(
- tuple("BUG" /* rule2 */, 0L),
- tuple("CODE_SMELL"/* rule1 */, 1L),
- tuple("VULNERABILITY", 0L),
- tuple("SECURITY_HOTSPOT", 0L));
- }
-
- @Test
- public void statuses_facet_should_be_sticky() {
- RuleDto rule1 = db.rules().insert(r -> r.setLanguage("java"));
- RuleDto rule2 = db.rules().insert(r -> r.setLanguage("java").setStatus(RuleStatus.BETA));
- RuleDto rule3 = db.rules().insert(r -> r.setLanguage("java").setStatus(RuleStatus.DEPRECATED));
-
- indexRules();
-
- SearchResponse result = ws.newRequest()
- .setParam("f", "status")
- .setParam("status", "DEPRECATED")
- .executeProtobuf(SearchResponse.class);
-
- assertThat(result.getRulesCount()).isEqualTo(3);
- assertThat(result.getRulesList()).extracting(Rule::getKey, r -> r.getStatus().name()).containsExactlyInAnyOrder(
- tuple(rule1.getKey().toString(), rule1.getStatus().name()),
- tuple(rule2.getKey().toString(), rule2.getStatus().name()),
- tuple(rule3.getKey().toString(), rule3.getStatus().name()));
- }
-
- @Test
- public void paging() {
- for (int i = 0; i < 12; i++) {
- db.rules().insert(r -> r.setLanguage("java"));
- }
- indexRules();
-
- ws.newRequest()
- .setParam(WebService.Param.PAGE, "2")
- .setParam(WebService.Param.PAGE_SIZE, "9")
- .execute()
- .assertJson(this.getClass(), "paging.json");
- }
-
- @Test
- public void compare_to_another_profile() {
- QProfileDto profile = db.qualityProfiles().insert(p -> p.setLanguage(JAVA));
- QProfileDto anotherProfile = db.qualityProfiles().insert(p -> p.setLanguage(JAVA));
- RuleDto commonRule = db.rules().insertRule(r -> r.setLanguage(JAVA));
- RuleDto profileRule1 = db.rules().insertRule(r -> r.setLanguage(JAVA));
- RuleDto profileRule2 = db.rules().insertRule(r -> r.setLanguage(JAVA));
- RuleDto profileRule3 = db.rules().insertRule(r -> r.setLanguage(JAVA));
- RuleDto anotherProfileRule1 = db.rules().insertRule(r -> r.setLanguage(JAVA));
- RuleDto anotherProfileRule2 = db.rules().insertRule(r -> r.setLanguage(JAVA));
- db.qualityProfiles().activateRule(profile, commonRule);
- db.qualityProfiles().activateRule(profile, profileRule1);
- db.qualityProfiles().activateRule(profile, profileRule2);
- db.qualityProfiles().activateRule(profile, profileRule3);
- db.qualityProfiles().activateRule(anotherProfile, commonRule);
- db.qualityProfiles().activateRule(anotherProfile, anotherProfileRule1);
- db.qualityProfiles().activateRule(anotherProfile, anotherProfileRule2);
- indexRules();
- indexActiveRules();
-
- SearchResponse result = ws.newRequest()
- .setParam(PARAM_QPROFILE, profile.getKee())
- .setParam(PARAM_ACTIVATION, "false")
- .setParam(PARAM_COMPARE_TO_PROFILE, anotherProfile.getKee())
- .executeProtobuf(SearchResponse.class);
-
- assertThat(result.getRulesList())
- .extracting(Rule::getKey)
- .containsExactlyInAnyOrder(anotherProfileRule1.getKey().toString(), anotherProfileRule2.getKey().toString());
- }
-
- @SafeVarargs
- private <T> void checkField(RuleDto rule, String fieldName, Function<Rule, T> responseExtractor, T... expected) {
- SearchResponse result = ws.newRequest()
- .setParam("f", fieldName)
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getRulesList()).extracting(Rule::getKey).containsExactly(rule.getKey().toString());
- assertThat(result.getRulesList()).extracting(responseExtractor).containsExactly(expected);
- }
-
- private void checkDescriptionSections(RuleDto rule, Set<Rule.DescriptionSection> expected) {
- SearchResponse result = ws.newRequest()
- .setParam("f", "descriptionSections")
- .executeProtobuf(SearchResponse.class);
- assertThat(result.getRulesList()).extracting(Rule::getKey).containsExactly(rule.getKey().toString());
- List<Rule.DescriptionSection> actualSections = result.getRules(0).getDescriptionSections().getDescriptionSectionsList();
- assertThat(actualSections).hasSameElementsAs(expected);
- }
-
-
- private void verifyNoResults(Consumer<TestRequest> requestPopulator) {
- verify(requestPopulator);
- }
-
- private void verify(Consumer<TestRequest> requestPopulator, RuleDto... expectedRules) {
- TestRequest request = ws.newRequest();
- requestPopulator.accept(request);
- Rules.SearchResponse response = request.executeProtobuf(Rules.SearchResponse.class);
-
- assertThat(response.getPaging().getPageIndex()).isOne();
- assertThat(response.getPaging().getPageSize()).isNotZero();
- RuleKey[] expectedRuleKeys = stream(expectedRules).map(RuleDto::getKey).toList().toArray(new RuleKey[0]);
- assertThat(response.getRulesList())
- .extracting(r -> RuleKey.parse(r.getKey()))
- .containsExactlyInAnyOrder(expectedRuleKeys);
- assertThat(response.getPaging().getTotal()).isEqualTo(expectedRules.length);
- assertThat(response.getRulesCount()).isEqualTo(expectedRules.length);
- }
-
- private void indexRules() {
- ruleIndexer.indexAll();
- }
-
- private void indexActiveRules() {
- activeRuleIndexer.indexAll();
- }
-
- private String[] get101Tags() {
- String[] tags = new String[101];
- for (int i = 0; i < 100; i++) {
- tags[i] = "tag" + i;
- }
- tags[100] = "tagA";
- return tags;
- }
-
- }
|