From 4afbe622115f89d933ae77842d75754a3bf4522d Mon Sep 17 00:00:00 2001 From: Eric Hartmann Date: Fri, 26 Jan 2018 10:22:50 +0100 Subject: [PATCH] SONAR-10313 Use issue ID for ES ISSUES.ISSUE Previously RuleKey was used, in order to allow renaming of the key we must store the ID of the rule. --- .../main/java/org/sonar/db/rule/RuleDao.java | 2 +- .../org/sonar/server/issue/IssueQuery.java | 9 +- .../sonar/server/issue/IssueQueryFactory.java | 30 +-- .../sonar/server/issue/index/IssueDoc.java | 9 +- .../sonar/server/issue/index/IssueIndex.java | 5 +- .../issue/index/IssueIndexDefinition.java | 4 +- .../index/IssueIteratorForSingleChunk.java | 29 +-- .../sonar/server/issue/ws/SearchAction.java | 46 +++- .../server/issue/ws/SearchResponseLoader.java | 4 +- .../sonar/server/issue/IssueDocTesting.java | 6 +- .../server/issue/IssueQueryFactoryTest.java | 19 +- .../sonar/server/issue/IssueQueryTest.java | 7 +- .../issue/index/IssueIndexDebtTest.java | 2 +- .../server/issue/index/IssueIndexTest.java | 230 +++++++++--------- .../issue/index/IssueIteratorFactoryTest.java | 3 +- .../issue/ws/SearchActionComponentsTest.java | 4 +- .../server/issue/ws/SearchActionTest.java | 72 ++++-- .../result_for_rule_search.json | 45 ++++ 18 files changed, 308 insertions(+), 218 deletions(-) create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/result_for_rule_search.json diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java index bd02532869b..7989e98e3b8 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java @@ -87,7 +87,7 @@ public class RuleDao implements Dao { executeLargeInputs(ids, chunk -> mapper(session).selectByIds(organizationUuid, chunk))); } - public List selectDefinitionByIds(DbSession session, List ids) { + public List selectDefinitionByIds(DbSession session, Collection ids) { return executeLargeInputs(ids, mapper(session)::selectDefinitionByIds); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java index b8379edacd3..fd3508f252d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java @@ -28,7 +28,6 @@ import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.apache.commons.lang.builder.ReflectionToStringBuilder; -import org.sonar.api.rule.RuleKey; import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.server.es.SearchOptions.MAX_LIMIT; @@ -64,7 +63,7 @@ public class IssueQuery { private final Collection directories; private final Collection files; private final Collection views; - private final Collection rules; + private final Collection rules; private final Collection assignees; private final Collection authors; private final Collection languages; @@ -163,7 +162,7 @@ public class IssueQuery { return views; } - public Collection rules() { + public Collection rules() { return rules; } @@ -274,7 +273,7 @@ public class IssueQuery { private Collection directories; private Collection files; private Collection views; - private Collection rules; + private Collection rules; private Collection assignees; private Collection authors; private Collection languages; @@ -354,7 +353,7 @@ public class IssueQuery { return this; } - public Builder rules(@Nullable Collection rules) { + public Builder rules(@Nullable Collection rules) { this.rules = rules; return this; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryFactory.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryFactory.java index 8af0aff307a..5eea597845c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryFactory.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryFactory.java @@ -19,11 +19,8 @@ */ package org.sonar.server.issue; -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner; -import com.google.common.base.Splitter; import com.google.common.base.Strings; -import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import java.time.Clock; import java.time.OffsetDateTime; @@ -47,16 +44,18 @@ import org.sonar.api.resources.Qualifiers; import org.sonar.api.rule.RuleKey; import org.sonar.api.server.ServerSide; import org.sonar.api.web.UserRole; +import org.sonar.core.util.stream.MoreCollectors; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.SnapshotDto; import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.server.issue.IssueQuery.PeriodStart; import org.sonar.server.user.UserSession; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Collections2.transform; import static java.lang.String.format; import static java.util.Collections.singleton; import static java.util.Collections.singletonList; @@ -107,7 +106,7 @@ public class IssueQueryFactory { .statuses(request.getStatuses()) .resolutions(request.getResolutions()) .resolved(request.getResolved()) - .rules(stringsToRules(request.getRules())) + .rules(ruleKeysToRuleId(dbSession, request.getRules())) .assignees(buildAssignees(request.getAssignees())) .languages(request.getLanguages()) .tags(request.getTags()) @@ -364,24 +363,13 @@ public class IssueQueryFactory { return componentDtos; } - @VisibleForTesting - static Collection toRules(@Nullable Object o) { - Collection result = null; - if (o != null) { - if (o instanceof List) { - // assume that it contains only strings - result = stringsToRules((List) o); - } else if (o instanceof String) { - result = stringsToRules(newArrayList(Splitter.on(',').omitEmptyStrings().split((String) o))); - } - } - return result; - } - @CheckForNull - private static Collection stringsToRules(@Nullable Collection rules) { + private Collection ruleKeysToRuleId(DbSession dbSession, @Nullable Collection rules) { if (rules != null) { - return Collections2.transform(rules, RuleKey::parse); + return dbClient.ruleDao().selectDefinitionByKeys(dbSession, transform(rules, RuleKey::parse)) + .stream() + .map(RuleDefinitionDto::getId) + .collect(MoreCollectors.toList()); } return null; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueDoc.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueDoc.java index 4d617040d6d..69f45aff434 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueDoc.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueDoc.java @@ -25,7 +25,6 @@ import java.util.Date; import java.util.Map; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; import org.sonar.api.rules.RuleType; import org.sonar.api.utils.Duration; @@ -85,8 +84,8 @@ public class IssueDoc extends BaseDoc { return getField(IssueIndexDefinition.FIELD_ISSUE_IS_MAIN_BRANCH); } - public RuleKey ruleKey() { - return RuleKey.parse(getField(IssueIndexDefinition.FIELD_ISSUE_RULE_KEY)); + public Integer ruleId() { + return getField(IssueIndexDefinition.FIELD_ISSUE_RULE_ID); } public String language() { @@ -195,8 +194,8 @@ public class IssueDoc extends BaseDoc { return this; } - public IssueDoc setRuleKey(@Nullable String s) { - setField(IssueIndexDefinition.FIELD_ISSUE_RULE_KEY, s); + public IssueDoc setRuleId(Integer s) { + setField(IssueIndexDefinition.FIELD_ISSUE_RULE_ID, s); return this; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java index 2b23343f6dd..eba5e6f4c33 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java @@ -409,8 +409,7 @@ public class IssueIndex { filters.put(IssueIndexDefinition.FIELD_ISSUE_TYPE, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_TYPE, query.types())); filters.put(IssueIndexDefinition.FIELD_ISSUE_RESOLUTION, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_RESOLUTION, query.resolutions())); filters.put(IssueIndexDefinition.FIELD_ISSUE_AUTHOR_LOGIN, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_AUTHOR_LOGIN, query.authors())); - filters.put(IssueIndexDefinition.FIELD_ISSUE_RULE_KEY, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_RULE_KEY, - query.rules().stream().map(String::valueOf).collect(MoreCollectors.toList(query.rules().size())))); + filters.put(IssueIndexDefinition.FIELD_ISSUE_RULE_ID, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_RULE_ID, query.rules())); filters.put(IssueIndexDefinition.FIELD_ISSUE_SEVERITY, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_SEVERITY, query.severities())); filters.put(IssueIndexDefinition.FIELD_ISSUE_STATUS, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_STATUS, query.statuses())); filters.put(IssueIndexDefinition.FIELD_ISSUE_ORGANIZATION_UUID, createTermFilter(IssueIndexDefinition.FIELD_ISSUE_ORGANIZATION_UUID, query.organizationUuid())); @@ -484,7 +483,7 @@ public class IssueIndex { addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch, PARAM_LANGUAGES, IssueIndexDefinition.FIELD_ISSUE_LANGUAGE, query.languages().toArray()); addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch, - PARAM_RULES, IssueIndexDefinition.FIELD_ISSUE_RULE_KEY, query.rules().toArray()); + PARAM_RULES, IssueIndexDefinition.FIELD_ISSUE_RULE_ID, query.rules().toArray()); addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch, PARAM_AUTHORS, IssueIndexDefinition.FIELD_ISSUE_AUTHOR_LOGIN, query.authors().toArray()); diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java index 6a59e2f2751..3521b705672 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java @@ -86,7 +86,7 @@ public class IssueIndexDefinition implements IndexDefinition { public static final String FIELD_ISSUE_DIRECTORY_PATH = "dirPath"; public static final String FIELD_ISSUE_RESOLUTION = "resolution"; - public static final String FIELD_ISSUE_RULE_KEY = "ruleKey"; + public static final String FIELD_ISSUE_RULE_ID = "ruleId"; public static final String FIELD_ISSUE_SEVERITY = "severity"; public static final String FIELD_ISSUE_SEVERITY_VALUE = "severityValue"; public static final String FIELD_ISSUE_STATUS = "status"; @@ -146,7 +146,7 @@ public class IssueIndexDefinition implements IndexDefinition { type.createBooleanField(FIELD_ISSUE_IS_MAIN_BRANCH); type.keywordFieldBuilder(FIELD_ISSUE_DIRECTORY_PATH).disableNorms().build(); type.keywordFieldBuilder(FIELD_ISSUE_RESOLUTION).disableNorms().build(); - type.keywordFieldBuilder(FIELD_ISSUE_RULE_KEY).disableNorms().build(); + type.keywordFieldBuilder(FIELD_ISSUE_RULE_ID).disableNorms().build(); type.keywordFieldBuilder(FIELD_ISSUE_SEVERITY).disableNorms().build(); type.createByteField(FIELD_ISSUE_SEVERITY_VALUE); type.keywordFieldBuilder(FIELD_ISSUE_STATUS).disableNorms().addSubFields(SORTABLE_ANALYZER).build(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java index e9c5df9e18d..ee1ec7950a9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java @@ -34,7 +34,6 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.apache.commons.lang.StringUtils; import org.sonar.api.resources.Scopes; -import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.RuleType; import org.sonar.db.DatabaseUtils; import org.sonar.db.DbClient; @@ -66,8 +65,7 @@ class IssueIteratorForSingleChunk implements IssueIterator { // column 11 "i.issue_update_date", - "r.plugin_name", - "r.plugin_rule_key", + "r.id", "r.language", "c.uuid", "c.module_uuid_path", @@ -200,21 +198,20 @@ class IssueIteratorForSingleChunk implements IssueIterator { doc.setFuncCloseDate(longToDate(getLong(rs, 9))); doc.setFuncCreationDate(longToDate(getLong(rs, 10))); doc.setFuncUpdateDate(longToDate(getLong(rs, 11))); - String ruleRepo = rs.getString(12); - String ruleKey = rs.getString(13); - doc.setRuleKey(RuleKey.of(ruleRepo, ruleKey).toString()); - doc.setLanguage(rs.getString(14)); - doc.setComponentUuid(rs.getString(15)); - String moduleUuidPath = rs.getString(16); + Integer ruleId = rs.getInt(12); + doc.setRuleId(ruleId); + doc.setLanguage(rs.getString(13)); + doc.setComponentUuid(rs.getString(14)); + String moduleUuidPath = rs.getString(15); doc.setModuleUuid(extractModule(moduleUuidPath)); doc.setModuleUuidPath(moduleUuidPath); - String scope = rs.getString(18); - String filePath = extractFilePath(rs.getString(17), scope); + String scope = rs.getString(17); + String filePath = extractFilePath(rs.getString(16), scope); doc.setFilePath(filePath); doc.setDirectoryPath(extractDirPath(doc.filePath(), scope)); - doc.setOrganizationUuid(rs.getString(19)); - String branchUuid = rs.getString(20); - String mainBranchProjectUuid = DatabaseUtils.getString(rs, 21); + doc.setOrganizationUuid(rs.getString(18)); + String branchUuid = rs.getString(19); + String mainBranchProjectUuid = DatabaseUtils.getString(rs, 20); doc.setBranchUuid(branchUuid); if (mainBranchProjectUuid == null) { doc.setProjectUuid(branchUuid); @@ -223,9 +220,9 @@ class IssueIteratorForSingleChunk implements IssueIterator { doc.setProjectUuid(mainBranchProjectUuid); doc.setIsMainBranch(false); } - String tags = rs.getString(22); + String tags = rs.getString(21); doc.setTags(ImmutableList.copyOf(IssueIteratorForSingleChunk.TAGS_SPLITTER.split(tags == null ? "" : tags))); - doc.setType(RuleType.valueOf(rs.getInt(23))); + doc.setType(RuleType.valueOf(rs.getInt(22))); return doc; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java index 7b74faaf2d4..a0a9b33a0ab 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java @@ -29,6 +29,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import javax.annotation.Nullable; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.search.SearchHit; @@ -43,15 +44,20 @@ import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.Paging; import org.sonar.api.utils.System2; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; import org.sonar.core.util.stream.MoreCollectors; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.server.es.Facets; import org.sonar.server.es.SearchOptions; import org.sonar.server.issue.IssueQuery; import org.sonar.server.issue.IssueQueryFactory; +import org.sonar.server.issue.SearchRequest; import org.sonar.server.issue.index.IssueIndex; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Issues.SearchWsResponse; -import org.sonar.server.issue.SearchRequest; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Iterables.concat; @@ -112,6 +118,7 @@ public class SearchAction implements IssuesWsAction { private static final Set IGNORED_FACETS = newHashSet(PARAM_PLANNED, DEPRECATED_PARAM_ACTION_PLANS, PARAM_REPORTERS); private static final Set FACETS_REQUIRING_PROJECT_OR_ORGANIZATION = newHashSet(PARAM_FILE_UUIDS, PARAM_DIRECTORIES, PARAM_MODULE_UUIDS); private static final Joiner COMA_JOINER = Joiner.on(","); + private static final Logger LOGGER = Loggers.get(SearchAction.class); private final UserSession userSession; private final IssueIndex issueIndex; @@ -119,15 +126,18 @@ public class SearchAction implements IssuesWsAction { private final SearchResponseLoader searchResponseLoader; private final SearchResponseFormat searchResponseFormat; private final System2 system2; + private final DbClient dbClient; public SearchAction(UserSession userSession, IssueIndex issueIndex, IssueQueryFactory issueQueryFactory, - SearchResponseLoader searchResponseLoader, SearchResponseFormat searchResponseFormat, System2 system2) { + SearchResponseLoader searchResponseLoader, SearchResponseFormat searchResponseFormat, System2 system2, + DbClient dbClient) { this.userSession = userSession; this.issueIndex = issueIndex; this.issueQueryFactory = issueQueryFactory; this.searchResponseLoader = searchResponseLoader; this.searchResponseFormat = searchResponseFormat; this.system2 = system2; + this.dbClient = dbClient; } @Override @@ -359,6 +369,7 @@ public class SearchAction implements IssuesWsAction { // Must be done after loading of data as the "hidden" facet "debt" // can be used to get total debt. facets = reorderFacets(facets, options.getFacets()); + replaceRuleIdsByRuleKeys(facets); // FIXME allow long in Paging Paging paging = forPageIndex(options.getPage()).withPageSize(options.getLimit()).andTotal((int) result.getHits().getTotalHits()); @@ -366,6 +377,35 @@ public class SearchAction implements IssuesWsAction { return searchResponseFormat.formatSearch(additionalFields, data, paging, facets); } + private void replaceRuleIdsByRuleKeys(@Nullable Facets facets) { + if (facets == null || facets.get(PARAM_RULES) == null) { + return; + } + // The facet for PARAM_RULES contains the id of the rule as the key + // We need to update the key to be a RuleKey + LinkedHashMap rulesFacet = facets.get(PARAM_RULES); + + try (DbSession dbSession = dbClient.openSession(false)) { + Map idToRuleKey = dbClient.ruleDao() + .selectDefinitionByIds(dbSession, Collections2.transform(rulesFacet.keySet(), Integer::parseInt)) + .stream() + .collect(Collectors.toMap(RuleDefinitionDto::getId, RuleDefinitionDto::getKey)); + + LinkedHashMap newRulesFacet = new LinkedHashMap<>(); + rulesFacet.forEach((k, v) -> { + RuleKey ruleKey = idToRuleKey.get(Integer.parseInt(k)); + if (ruleKey != null) { + newRulesFacet.put(ruleKey.toString(), v); + } else { + // RuleKey not found ES/DB incorrect? + LOGGER.error("Rule with id {} is not available in database", k); + } + }); + rulesFacet.clear(); + rulesFacet.putAll(newRulesFacet); + } + } + private static SearchOptions createSearchOptionsFromRequest(SearchRequest request) { SearchOptions options = new SearchOptions(); options.setPage(request.getPage(), request.getPageSize()); @@ -448,7 +488,7 @@ public class SearchAction implements IssuesWsAction { private static void collectFacets(SearchResponseLoader.Collector collector, Facets facets) { Set facetRules = facets.getBucketKeys(PARAM_RULES); if (facetRules != null) { - collector.addAll(SearchAdditionalField.RULES, Collections2.transform(facetRules, RuleKey::parse)); + collector.addAll(SearchAdditionalField.RULES, facetRules); } collector.addProjectUuids(facets.getBucketKeys(PARAM_PROJECT_UUIDS)); collector.addComponentUuids(facets.getBucketKeys(PARAM_COMPONENT_UUIDS)); diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchResponseLoader.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchResponseLoader.java index 440e2a00beb..7647b198edb 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchResponseLoader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchResponseLoader.java @@ -222,7 +222,7 @@ public class SearchResponseLoader { private void loadRules(Collector collector, DbSession dbSession, SearchResponseData result) { if (collector.contains(RULES)) { - result.setRules(dbClient.ruleDao().selectDefinitionByKeys(dbSession, collector.getList(RULES))); + result.setRules(dbClient.ruleDao().selectDefinitionByIds(dbSession, collector.getList(RULES))); } } @@ -311,7 +311,7 @@ public class SearchResponseLoader { for (IssueDto issue : issues) { componentUuids.add(issue.getComponentUuid()); projectUuids.add(issue.getProjectUuid()); - add(RULES, issue.getRuleKey()); + add(RULES, issue.getRuleId()); add(USERS, issue.getAssignee()); collectComponentsFromIssueLocations(issue); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueDocTesting.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueDocTesting.java index 2af1ac4b4d6..a7a02a3b744 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueDocTesting.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueDocTesting.java @@ -21,13 +21,11 @@ package org.sonar.server.issue; import com.google.common.collect.Maps; import java.util.Date; -import org.apache.commons.lang.math.RandomUtils; import org.sonar.api.resources.Scopes; import org.sonar.api.rule.Severity; import org.sonar.api.rules.RuleType; import org.sonar.core.util.Uuids; import org.sonar.db.component.ComponentDto; -import org.sonar.db.rule.RuleTesting; import org.sonar.server.issue.index.IssueDoc; import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; @@ -58,7 +56,7 @@ public class IssueDocTesting { public static IssueDoc newDoc() { IssueDoc doc = new IssueDoc(Maps.newHashMap()); doc.setKey(Uuids.createFast()); - doc.setRuleKey(RuleTesting.XOO_X1.toString()); + doc.setRuleId(nextInt(1000)); doc.setType(RuleType.CODE_SMELL); doc.setAssignee("assignee_" + randomAlphabetic(5)); doc.setAuthorLogin("author_" + randomAlphabetic(5)); @@ -73,7 +71,7 @@ public class IssueDocTesting { doc.setStatus(STATUS_OPEN); doc.setResolution(null); doc.setSeverity(Severity.ALL.get(nextInt(Severity.ALL.size()))); - doc.setEffort((long) RandomUtils.nextInt(10)); + doc.setEffort((long) nextInt(10)); doc.setFuncCreationDate(new Date(System.currentTimeMillis() - 2_000)); doc.setFuncUpdateDate(new Date(System.currentTimeMillis() - 1_000)); doc.setFuncCloseDate(null); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryFactoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryFactoryTest.java index 04e8edffc61..a7886ab7fd9 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryFactoryTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryFactoryTest.java @@ -34,6 +34,8 @@ import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.SnapshotDto; import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.rule.RuleDbTester; +import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.tester.UserSessionRule; @@ -50,6 +52,7 @@ import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newModuleDto; import static org.sonar.db.component.ComponentTesting.newProjectCopy; import static org.sonar.db.component.ComponentTesting.newSubView; +import static org.sonar.db.rule.RuleTesting.newRule; public class IssueQueryFactoryTest { @@ -60,6 +63,8 @@ public class IssueQueryFactoryTest { @Rule public DbTester db = DbTester.create(); + private RuleDbTester ruleDbTester = new RuleDbTester(db); + private Clock clock = mock(Clock.class); private IssueQueryFactory underTest = new IssueQueryFactory(db.getDbClient(), clock, userSession); @@ -70,6 +75,9 @@ public class IssueQueryFactoryTest { ComponentDto module = db.components().insertComponent(newModuleDto(project)); ComponentDto file = db.components().insertComponent(newFileDto(project)); + RuleDefinitionDto rule1 = ruleDbTester.insert(); + RuleDefinitionDto rule2 = ruleDbTester.insert(); + newRule(RuleKey.of("findbugs", "NullReference")); SearchRequest request = new SearchRequest() .setIssues(asList("anIssueKey")) .setSeverities(asList("MAJOR", "MINOR")) @@ -87,7 +95,7 @@ public class IssueQueryFactoryTest { .setAssigned(true) .setCreatedAfter("2013-04-16T09:08:24+0200") .setCreatedBefore("2013-04-17T09:08:24+0200") - .setRules(asList("squid:AvoidCycle", "findbugs:NullReference")) + .setRules(asList(rule1.getKey().toString(), rule2.getKey().toString())) .setSort("CREATION_DATE") .setAsc(true); @@ -198,15 +206,6 @@ public class IssueQueryFactoryTest { assertThat(query.branchUuid()).isNull(); } - @Test - public void parse_list_of_rules() { - assertThat(IssueQueryFactory.toRules(null)).isNull(); - assertThat(IssueQueryFactory.toRules("")).isEmpty(); - assertThat(IssueQueryFactory.toRules("squid:AvoidCycle")).containsOnly(RuleKey.of("squid", "AvoidCycle")); - assertThat(IssueQueryFactory.toRules("squid:AvoidCycle,findbugs:NullRef")).containsOnly(RuleKey.of("squid", "AvoidCycle"), RuleKey.of("findbugs", "NullRef")); - assertThat(IssueQueryFactory.toRules(asList("squid:AvoidCycle", "findbugs:NullRef"))).containsOnly(RuleKey.of("squid", "AvoidCycle"), RuleKey.of("findbugs", "NullRef")); - } - @Test public void fail_if_components_and_components_uuid_params_are_set_at_the_same_time() { SearchRequest request = new SearchRequest() diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryTest.java index ab5d9d6f0c9..8c89d26a8a9 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryTest.java @@ -24,11 +24,11 @@ import com.google.common.collect.Lists; import java.util.Date; import org.junit.Test; import org.sonar.api.issue.Issue; -import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; import org.sonar.server.issue.IssueQuery.PeriodStart; import static com.google.common.collect.Lists.newArrayList; +import static org.apache.commons.lang.math.RandomUtils.nextInt; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; @@ -36,6 +36,7 @@ public class IssueQueryTest { @Test public void build_query() { + int ruleId = nextInt(1000); PeriodStart filterDate = new IssueQuery.PeriodStart(new Date(10_000_000_000L),false); IssueQuery query = IssueQuery.builder() .issueKeys(newArrayList("ABCDE")) @@ -45,7 +46,7 @@ public class IssueQueryTest { .projectUuids(newArrayList("PROJECT")) .componentUuids(newArrayList("org/struts/Action.java")) .moduleUuids(newArrayList("org.struts:core")) - .rules(newArrayList(RuleKey.of("squid", "AvoidCycle"))) + .rules(newArrayList(ruleId)) .assignees(newArrayList("gargantua")) .languages(newArrayList("xoo")) .tags(newArrayList("tag1", "tag2")) @@ -76,7 +77,7 @@ public class IssueQueryTest { assertThat(query.branchUuid()).isEqualTo("my_branch"); assertThat(query.createdAfterByProjectUuids()).containsOnly(entry("PROJECT", filterDate)); assertThat(query.assigned()).isTrue(); - assertThat(query.rules()).containsOnly(RuleKey.of("squid", "AvoidCycle")); + assertThat(query.rules()).containsOnly(ruleId); assertThat(query.createdAfter()).isNotNull(); assertThat(query.createdBefore()).isNotNull(); assertThat(query.createdAt()).isNotNull(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java index c0e18939468..d518666c823 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java @@ -183,7 +183,7 @@ public class IssueIndexDebtTest { ComponentDto file = ComponentTesting.newFileDto(project, null); RuleKey ruleKey = RuleKey.of("repo", "X1"); - indexIssues(IssueDocTesting.newDoc("I1", file).setRuleKey(ruleKey.toString()).setLanguage("xoo").setEffort(10L)); + indexIssues(IssueDocTesting.newDoc("I1", file).setLanguage("xoo").setEffort(10L)); Facets facets = search("languages"); assertThat(facets.getNames()).containsOnly("languages", FACET_MODE_EFFORT); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java index 3f4f70dc8a3..70767cbf405 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java @@ -39,13 +39,11 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.issue.Issue; -import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; import org.sonar.api.utils.System2; import org.sonar.api.utils.internal.TestSystem2; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; import org.sonar.db.organization.OrganizationDto; import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.db.user.GroupDto; @@ -82,6 +80,7 @@ import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newModuleDto; import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto; +import static org.sonar.db.rule.RuleTesting.newRule; import static org.sonar.db.user.GroupTesting.newGroupDto; import static org.sonar.db.user.UserTesting.newUserDto; import static org.sonar.server.issue.IssueDocTesting.newDoc; @@ -111,20 +110,20 @@ public class IssueIndexTest { @Test public void filter_by_keys() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); indexIssues( newDoc("I1", newFileDto(project, null)), newDoc("I2", newFileDto(project, null))); assertThatSearchReturnsOnly(IssueQuery.builder().issueKeys(asList("I1", "I2")), "I1", "I2"); - assertThatSearchReturnsOnly(IssueQuery.builder().issueKeys(asList("I1")), "I1"); + assertThatSearchReturnsOnly(IssueQuery.builder().issueKeys(singletonList("I1")), "I1"); assertThatSearchReturnsEmpty(IssueQuery.builder().issueKeys(asList("I3", "I4"))); } @Test public void filter_by_projects() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto module = newModuleDto(project); ComponentDto subModule = newModuleDto(module); @@ -136,8 +135,8 @@ public class IssueIndexTest { newDoc("I5", subModule), newDoc("I6", newFileDto(subModule, null))); - assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(asList(project.uuid())), "I1", "I2", "I3", "I4", "I5", "I6"); - assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(asList("unknown"))); + assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(singletonList(project.uuid())), "I1", "I2", "I3", "I4", "I5", "I6"); + assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(singletonList("unknown"))); } @Test @@ -156,7 +155,7 @@ public class IssueIndexTest { @Test public void filter_by_modules() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto module = newModuleDto(project); ComponentDto subModule = newModuleDto(module); ComponentDto file = newFileDto(subModule, null); @@ -166,16 +165,16 @@ public class IssueIndexTest { newDoc("I5", subModule), newDoc("I2", file)); - assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(asList(project.uuid())).moduleUuids(asList(file.uuid()))); - assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(asList(project.uuid())).moduleUuids(asList(module.uuid())), "I3"); - assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(asList(project.uuid())).moduleUuids(asList(subModule.uuid())), "I2", "I5"); - assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(asList(project.uuid())).moduleUuids(asList(project.uuid()))); - assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(asList(project.uuid())).moduleUuids(asList("unknown"))); + assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(singletonList(project.uuid())).moduleUuids(singletonList(file.uuid()))); + assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(singletonList(project.uuid())).moduleUuids(singletonList(module.uuid())), "I3"); + assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(singletonList(project.uuid())).moduleUuids(singletonList(subModule.uuid())), "I2", "I5"); + assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(singletonList(project.uuid())).moduleUuids(singletonList(project.uuid()))); + assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(singletonList(project.uuid())).moduleUuids(singletonList("unknown"))); } @Test public void filter_by_components_on_contextualized_search() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto module = newModuleDto(project); ComponentDto subModule = newModuleDto(module); ComponentDto file1 = newFileDto(project, null); @@ -193,12 +192,12 @@ public class IssueIndexTest { newDoc("I6", file3)); assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(asList(file1.uuid(), file2.uuid(), file3.uuid())), "I2", "I4", "I6"); - assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(asList(file1.uuid())), "I2"); - assertThatSearchReturnsOnly(IssueQuery.builder().moduleRootUuids(asList(subModule.uuid())), "I5", "I6"); - assertThatSearchReturnsOnly(IssueQuery.builder().moduleRootUuids(asList(module.uuid())), "I3", "I4", "I5", "I6"); - assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(asList(project.uuid())), "I1", "I2", "I3", "I4", "I5", "I6"); - assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(asList(view)), "I1", "I2", "I3", "I4", "I5", "I6"); - assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(asList("unknown"))); + assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(singletonList(file1.uuid())), "I2"); + assertThatSearchReturnsOnly(IssueQuery.builder().moduleRootUuids(singletonList(subModule.uuid())), "I5", "I6"); + assertThatSearchReturnsOnly(IssueQuery.builder().moduleRootUuids(singletonList(module.uuid())), "I3", "I4", "I5", "I6"); + assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(singletonList(project.uuid())), "I1", "I2", "I3", "I4", "I5", "I6"); + assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(view)), "I1", "I2", "I3", "I4", "I5", "I6"); + assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(singletonList("unknown"))); } @Test @@ -220,12 +219,12 @@ public class IssueIndexTest { newDoc("I5", subModule), newDoc("I6", file3)); - assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(asList("unknown"))); - assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(asList(project.uuid())), "I1", "I2", "I3", "I4", "I5", "I6"); - assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(asList(view)), "I1", "I2", "I3", "I4", "I5", "I6"); - assertThatSearchReturnsOnly(IssueQuery.builder().moduleUuids(asList(module.uuid())), "I3", "I4"); - assertThatSearchReturnsOnly(IssueQuery.builder().moduleUuids(asList(subModule.uuid())), "I5", "I6"); - assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(asList(file1.uuid())), "I2"); + assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(singletonList("unknown"))); + assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(singletonList(project.uuid())), "I1", "I2", "I3", "I4", "I5", "I6"); + assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(view)), "I1", "I2", "I3", "I4", "I5", "I6"); + assertThatSearchReturnsOnly(IssueQuery.builder().moduleUuids(singletonList(module.uuid())), "I3", "I4"); + assertThatSearchReturnsOnly(IssueQuery.builder().moduleUuids(singletonList(subModule.uuid())), "I5", "I6"); + assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(singletonList(file1.uuid())), "I2"); assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(asList(file1.uuid(), file2.uuid(), file3.uuid())), "I2", "I4", "I6"); } @@ -248,7 +247,7 @@ public class IssueIndexTest { @Test public void filter_by_directories() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file1 = newFileDto(project, null).setPath("src/main/xoo/F1.xoo"); ComponentDto file2 = newFileDto(project, null).setPath("F2.xoo"); @@ -256,14 +255,14 @@ public class IssueIndexTest { newDoc("I1", file1).setDirectoryPath("/src/main/xoo"), newDoc("I2", file2).setDirectoryPath("/")); - assertThatSearchReturnsOnly(IssueQuery.builder().directories(asList("/src/main/xoo")), "I1"); - assertThatSearchReturnsOnly(IssueQuery.builder().directories(asList("/")), "I2"); - assertThatSearchReturnsEmpty(IssueQuery.builder().directories(asList("unknown"))); + assertThatSearchReturnsOnly(IssueQuery.builder().directories(singletonList("/src/main/xoo")), "I1"); + assertThatSearchReturnsOnly(IssueQuery.builder().directories(singletonList("/")), "I2"); + assertThatSearchReturnsEmpty(IssueQuery.builder().directories(singletonList("unknown"))); } @Test public void facets_on_directories() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file1 = newFileDto(project, null).setPath("src/main/xoo/F1.xoo"); ComponentDto file2 = newFileDto(project, null).setPath("F2.xoo"); @@ -277,9 +276,9 @@ public class IssueIndexTest { @Test public void filter_by_views() { OrganizationDto organizationDto = newOrganizationDto(); - ComponentDto project1 = ComponentTesting.newPrivateProjectDto(organizationDto); + ComponentDto project1 = newPrivateProjectDto(organizationDto); ComponentDto file1 = newFileDto(project1, null); - ComponentDto project2 = ComponentTesting.newPrivateProjectDto(organizationDto); + ComponentDto project2 = newPrivateProjectDto(organizationDto); indexIssues( // Project1 has 2 issues (one on a file and one on the project itself) newDoc("I1", project1), @@ -295,16 +294,16 @@ public class IssueIndexTest { String view2 = "CDEF"; indexView(view2, asList(project2.uuid())); - assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(asList(view1)), "I1", "I2"); - assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(asList(view2)), "I3"); + assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(view1)), "I1", "I2"); + assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(view2)), "I3"); assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(asList(view1, view2)), "I1", "I2", "I3"); - assertThatSearchReturnsEmpty(IssueQuery.builder().viewUuids(asList("unknown"))); + assertThatSearchReturnsEmpty(IssueQuery.builder().viewUuids(singletonList("unknown"))); } @Test public void filter_by_views_not_having_projects() { OrganizationDto organizationDto = newOrganizationDto(); - ComponentDto project1 = ComponentTesting.newPrivateProjectDto(organizationDto); + ComponentDto project1 = newPrivateProjectDto(organizationDto); ComponentDto file1 = newFileDto(project1, null); indexIssues(newDoc("I2", file1)); String view1 = "ABCD"; @@ -424,7 +423,7 @@ public class IssueIndexTest { @Test public void filter_by_severities() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -432,13 +431,13 @@ public class IssueIndexTest { newDoc("I2", file).setSeverity(Severity.MAJOR)); assertThatSearchReturnsOnly(IssueQuery.builder().severities(asList(Severity.INFO, Severity.MAJOR)), "I1", "I2"); - assertThatSearchReturnsOnly(IssueQuery.builder().severities(asList(Severity.INFO)), "I1"); - assertThatSearchReturnsEmpty(IssueQuery.builder().severities(asList(Severity.BLOCKER))); + assertThatSearchReturnsOnly(IssueQuery.builder().severities(singletonList(Severity.INFO)), "I1"); + assertThatSearchReturnsEmpty(IssueQuery.builder().severities(singletonList(Severity.BLOCKER))); } @Test public void facets_on_severities() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -451,7 +450,7 @@ public class IssueIndexTest { @Test public void filter_by_statuses() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -459,13 +458,13 @@ public class IssueIndexTest { newDoc("I2", file).setStatus(Issue.STATUS_OPEN)); assertThatSearchReturnsOnly(IssueQuery.builder().statuses(asList(Issue.STATUS_CLOSED, Issue.STATUS_OPEN)), "I1", "I2"); - assertThatSearchReturnsOnly(IssueQuery.builder().statuses(asList(Issue.STATUS_CLOSED)), "I1"); - assertThatSearchReturnsEmpty(IssueQuery.builder().statuses(asList(Issue.STATUS_CONFIRMED))); + assertThatSearchReturnsOnly(IssueQuery.builder().statuses(singletonList(Issue.STATUS_CLOSED)), "I1"); + assertThatSearchReturnsEmpty(IssueQuery.builder().statuses(singletonList(Issue.STATUS_CONFIRMED))); } @Test public void facets_on_statuses() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -478,7 +477,7 @@ public class IssueIndexTest { @Test public void filter_by_resolutions() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -486,13 +485,13 @@ public class IssueIndexTest { newDoc("I2", file).setResolution(Issue.RESOLUTION_FIXED)); assertThatSearchReturnsOnly(IssueQuery.builder().resolutions(asList(Issue.RESOLUTION_FALSE_POSITIVE, Issue.RESOLUTION_FIXED)), "I1", "I2"); - assertThatSearchReturnsOnly(IssueQuery.builder().resolutions(asList(Issue.RESOLUTION_FALSE_POSITIVE)), "I1"); - assertThatSearchReturnsEmpty(IssueQuery.builder().resolutions(asList(Issue.RESOLUTION_REMOVED))); + assertThatSearchReturnsOnly(IssueQuery.builder().resolutions(singletonList(Issue.RESOLUTION_FALSE_POSITIVE)), "I1"); + assertThatSearchReturnsEmpty(IssueQuery.builder().resolutions(singletonList(Issue.RESOLUTION_REMOVED))); } @Test public void facets_on_resolutions() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -505,7 +504,7 @@ public class IssueIndexTest { @Test public void filter_by_resolved() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -520,42 +519,45 @@ public class IssueIndexTest { @Test public void filter_by_rules() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); - RuleKey ruleKey = RuleKey.of("repo", "X1"); + RuleDefinitionDto ruleDefinitionDto = newRule(); + db.rules().insert(ruleDefinitionDto); - indexIssues(newDoc("I1", file).setRuleKey(ruleKey.toString())); + indexIssues(newDoc("I1", file).setRuleId(ruleDefinitionDto.getId())); - assertThatSearchReturnsOnly(IssueQuery.builder().rules(asList(ruleKey)), "I1"); - assertThatSearchReturnsEmpty(IssueQuery.builder().rules(asList(RuleKey.of("rule", "without issue")))); + assertThatSearchReturnsOnly(IssueQuery.builder().rules(singletonList(ruleDefinitionDto.getId())), "I1"); + assertThatSearchReturnsEmpty(IssueQuery.builder().rules(singletonList(-1))); } @Test public void filter_by_languages() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); - RuleKey ruleKey = RuleKey.of("repo", "X1"); + RuleDefinitionDto ruleDefinitionDto = newRule(); + db.rules().insert(ruleDefinitionDto); - indexIssues(newDoc("I1", file).setRuleKey(ruleKey.toString()).setLanguage("xoo")); + indexIssues(newDoc("I1", file).setRuleId(ruleDefinitionDto.getId()).setLanguage("xoo")); - assertThatSearchReturnsOnly(IssueQuery.builder().languages(asList("xoo")), "I1"); - assertThatSearchReturnsEmpty(IssueQuery.builder().languages(asList("unknown"))); + assertThatSearchReturnsOnly(IssueQuery.builder().languages(singletonList("xoo")), "I1"); + assertThatSearchReturnsEmpty(IssueQuery.builder().languages(singletonList("unknown"))); } @Test public void facets_on_languages() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); - RuleKey ruleKey = RuleKey.of("repo", "X1"); + RuleDefinitionDto ruleDefinitionDto = newRule(); + db.rules().insert(ruleDefinitionDto); - indexIssues(newDoc("I1", file).setRuleKey(ruleKey.toString()).setLanguage("xoo")); + indexIssues(newDoc("I1", file).setRuleId(ruleDefinitionDto.getId()).setLanguage("xoo")); assertThatFacetHasOnly(IssueQuery.builder(), "languages", entry("xoo", 1L)); } @Test public void filter_by_assignees() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -563,14 +565,14 @@ public class IssueIndexTest { newDoc("I2", file).setAssignee("marcel"), newDoc("I3", file).setAssignee(null)); - assertThatSearchReturnsOnly(IssueQuery.builder().assignees(asList("steph")), "I1"); + assertThatSearchReturnsOnly(IssueQuery.builder().assignees(singletonList("steph")), "I1"); assertThatSearchReturnsOnly(IssueQuery.builder().assignees(asList("steph", "marcel")), "I1", "I2"); - assertThatSearchReturnsEmpty(IssueQuery.builder().assignees(asList("unknown"))); + assertThatSearchReturnsEmpty(IssueQuery.builder().assignees(singletonList("unknown"))); } @Test public void facets_on_assignees() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -584,7 +586,7 @@ public class IssueIndexTest { @Test public void facets_on_assignees_supports_dashes() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -593,12 +595,12 @@ public class IssueIndexTest { newDoc("I3", file).setAssignee("marcel"), newDoc("I4", file).setAssignee(null)); - assertThatFacetHasOnly(IssueQuery.builder().assignees(asList("j-b")), "assignees", entry("j-b", 1L), entry("marcel", 2L), entry("", 1L)); + assertThatFacetHasOnly(IssueQuery.builder().assignees(singletonList("j-b")), "assignees", entry("j-b", 1L), entry("marcel", 2L), entry("", 1L)); } @Test public void filter_by_assigned() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -613,7 +615,7 @@ public class IssueIndexTest { @Test public void filter_by_authors() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -621,14 +623,14 @@ public class IssueIndexTest { newDoc("I2", file).setAuthorLogin("marcel"), newDoc("I3", file).setAssignee(null)); - assertThatSearchReturnsOnly(IssueQuery.builder().authors(asList("steph")), "I1"); + assertThatSearchReturnsOnly(IssueQuery.builder().authors(singletonList("steph")), "I1"); assertThatSearchReturnsOnly(IssueQuery.builder().authors(asList("steph", "marcel")), "I1", "I2"); - assertThatSearchReturnsEmpty(IssueQuery.builder().authors(asList("unknown"))); + assertThatSearchReturnsEmpty(IssueQuery.builder().authors(singletonList("unknown"))); } @Test public void facets_on_authors() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -642,7 +644,7 @@ public class IssueIndexTest { @Test public void filter_by_created_after() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -658,7 +660,7 @@ public class IssueIndexTest { @Test public void filter_by_created_before() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -674,7 +676,7 @@ public class IssueIndexTest { @Test public void filter_by_created_after_and_before() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -714,7 +716,7 @@ public class IssueIndexTest { @Test public void filter_by_create_after_and_before_take_into_account_timezone() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -758,7 +760,7 @@ public class IssueIndexTest { @Test public void filter_by_created_at() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues(newDoc("I1", file).setFuncCreationDate(parseDate("2014-09-20"))); @@ -900,7 +902,7 @@ public class IssueIndexTest { } private SearchOptions fixtureForCreatedAtFacet() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); IssueDoc issue0 = newDoc("ISSUE0", file).setFuncCreationDate(parseDateTime("2011-04-25T00:05:13+0000")); @@ -918,7 +920,7 @@ public class IssueIndexTest { @Test public void paging() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); for (int i = 0; i < 12; i++) { indexIssues(newDoc("I" + i, file)); @@ -941,7 +943,7 @@ public class IssueIndexTest { @Test public void search_with_max_limit() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); List issues = new ArrayList<>(); for (int i = 0; i < 500; i++) { @@ -957,7 +959,7 @@ public class IssueIndexTest { @Test public void sort_by_status() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -974,7 +976,7 @@ public class IssueIndexTest { @Test public void sort_by_severity() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -993,7 +995,7 @@ public class IssueIndexTest { @Test public void sort_by_assignee() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -1009,7 +1011,7 @@ public class IssueIndexTest { @Test public void sort_by_creation_date() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -1026,7 +1028,7 @@ public class IssueIndexTest { @Test public void sort_by_update_date() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -1043,7 +1045,7 @@ public class IssueIndexTest { @Test public void sort_by_close_date() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( @@ -1061,7 +1063,7 @@ public class IssueIndexTest { @Test public void sort_by_file_and_line() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file1 = newFileDto(project, null, "F1").setPath("src/main/xoo/org/sonar/samples/File.xoo"); ComponentDto file2 = newFileDto(project, null, "F2").setPath("src/main/xoo/org/sonar/samples/File2.xoo"); @@ -1118,9 +1120,9 @@ public class IssueIndexTest { @Test public void authorized_issues_on_groups() { OrganizationDto org = newOrganizationDto(); - ComponentDto project1 = ComponentTesting.newPrivateProjectDto(org); - ComponentDto project2 = ComponentTesting.newPrivateProjectDto(org); - ComponentDto project3 = ComponentTesting.newPrivateProjectDto(org); + ComponentDto project1 = newPrivateProjectDto(org); + ComponentDto project2 = newPrivateProjectDto(org); + ComponentDto project3 = newPrivateProjectDto(org); ComponentDto file1 = newFileDto(project1, null); ComponentDto file2 = newFileDto(project2, null); ComponentDto file3 = newFileDto(project3, null); @@ -1150,15 +1152,15 @@ public class IssueIndexTest { assertThatSearchReturnsEmpty(IssueQuery.builder()); userSessionRule.logIn().setGroups(group1, group2); - assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(asList(project3.uuid()))); + assertThatSearchReturnsEmpty(IssueQuery.builder().projectUuids(singletonList(project3.uuid()))); } @Test public void authorized_issues_on_user() { OrganizationDto org = newOrganizationDto(); - ComponentDto project1 = ComponentTesting.newPrivateProjectDto(org); - ComponentDto project2 = ComponentTesting.newPrivateProjectDto(org); - ComponentDto project3 = ComponentTesting.newPrivateProjectDto(org); + ComponentDto project1 = newPrivateProjectDto(org); + ComponentDto project2 = newPrivateProjectDto(org); + ComponentDto project3 = newPrivateProjectDto(org); ComponentDto file1 = newFileDto(project1, null); ComponentDto file2 = newFileDto(project2, null); ComponentDto file3 = newFileDto(project3, null); @@ -1186,7 +1188,7 @@ public class IssueIndexTest { @Test public void root_user_is_authorized_to_access_all_issues() { - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); indexIssue(newDoc("I1", project)); userSessionRule.logIn().setRoot(); @@ -1201,14 +1203,14 @@ public class IssueIndexTest { OrganizationDto org = db.organizations().insert(); OrganizationDto anotherOrg = db.organizations().insert(); - ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto()); + ComponentDto project = newPrivateProjectDto(newOrganizationDto()); ComponentDto file = newFileDto(project, null); indexIssues( - newDoc("I42", file).setOrganizationUuid(anotherOrg.getUuid()).setRuleKey(r1.getKey().toString()).setTags(of("another")), - newDoc("I1", file).setOrganizationUuid(org.getUuid()).setRuleKey(r1.getKey().toString()).setTags(of("convention", "java8", "bug")), - newDoc("I2", file).setOrganizationUuid(org.getUuid()).setRuleKey(r1.getKey().toString()).setTags(of("convention", "bug")), - newDoc("I3", file).setOrganizationUuid(org.getUuid()).setRuleKey(r2.getKey().toString()), - newDoc("I4", file).setOrganizationUuid(org.getUuid()).setRuleKey(r1.getKey().toString()).setTags(of("convention"))); + newDoc("I42", file).setOrganizationUuid(anotherOrg.getUuid()).setRuleId(r1.getId()).setTags(of("another")), + newDoc("I1", file).setOrganizationUuid(org.getUuid()).setRuleId(r1.getId()).setTags(of("convention", "java8", "bug")), + newDoc("I2", file).setOrganizationUuid(org.getUuid()).setRuleId(r1.getId()).setTags(of("convention", "bug")), + newDoc("I3", file).setOrganizationUuid(org.getUuid()).setRuleId(r2.getId()), + newDoc("I4", file).setOrganizationUuid(org.getUuid()).setRuleId(r1.getId()).setTags(of("convention"))); assertThat(underTest.listTags(org, null, 100)).containsOnly("convention", "java8", "bug"); assertThat(underTest.listTags(org, null, 2)).containsOnly("bug", "convention"); @@ -1232,7 +1234,7 @@ public class IssueIndexTest { @Test public void test_listAuthors() { OrganizationDto org = newOrganizationDto(); - ComponentDto project = ComponentTesting.newPrivateProjectDto(org); + ComponentDto project = newPrivateProjectDto(org); indexIssues( newDoc("issue1", project).setAuthorLogin("luke.skywalker"), newDoc("issue2", project).setAuthorLogin("luke@skywalker.name"), @@ -1252,7 +1254,7 @@ public class IssueIndexTest { @Test public void listAuthors_escapes_regexp_special_characters() { OrganizationDto org = newOrganizationDto(); - ComponentDto project = ComponentTesting.newPrivateProjectDto(org); + ComponentDto project = newPrivateProjectDto(org); indexIssues( newDoc("issue1", project).setAuthorLogin("name++")); IssueQuery query = IssueQuery.builder() @@ -1268,9 +1270,9 @@ public class IssueIndexTest { @Test public void filter_by_organization() { OrganizationDto org1 = newOrganizationDto(); - ComponentDto projectInOrg1 = ComponentTesting.newPrivateProjectDto(org1); + ComponentDto projectInOrg1 = newPrivateProjectDto(org1); OrganizationDto org2 = newOrganizationDto(); - ComponentDto projectInOrg2 = ComponentTesting.newPrivateProjectDto(org2); + ComponentDto projectInOrg2 = newPrivateProjectDto(org2); indexIssues(newDoc("issueInOrg1", projectInOrg1), newDoc("issue1InOrg2", projectInOrg2), newDoc("issue2InOrg2", projectInOrg2)); @@ -1282,25 +1284,25 @@ public class IssueIndexTest { @Test public void filter_by_organization_and_project() { OrganizationDto org1 = newOrganizationDto(); - ComponentDto projectInOrg1 = ComponentTesting.newPrivateProjectDto(org1); + ComponentDto projectInOrg1 = newPrivateProjectDto(org1); OrganizationDto org2 = newOrganizationDto(); - ComponentDto projectInOrg2 = ComponentTesting.newPrivateProjectDto(org2); + ComponentDto projectInOrg2 = newPrivateProjectDto(org2); indexIssues(newDoc("issueInOrg1", projectInOrg1), newDoc("issue1InOrg2", projectInOrg2), newDoc("issue2InOrg2", projectInOrg2)); // no conflict - IssueQuery.Builder query = IssueQuery.builder().organizationUuid(org1.getUuid()).projectUuids(asList(projectInOrg1.uuid())); + IssueQuery.Builder query = IssueQuery.builder().organizationUuid(org1.getUuid()).projectUuids(singletonList(projectInOrg1.uuid())); assertThatSearchReturnsOnly(query, "issueInOrg1"); // conflict - query = IssueQuery.builder().organizationUuid(org1.getUuid()).projectUuids(asList(projectInOrg2.uuid())); + query = IssueQuery.builder().organizationUuid(org1.getUuid()).projectUuids(singletonList(projectInOrg2.uuid())); assertThatSearchReturnsEmpty(query); } @Test public void countTags() { OrganizationDto org = newOrganizationDto(); - ComponentDto project = ComponentTesting.newPrivateProjectDto(org); + ComponentDto project = newPrivateProjectDto(org); indexIssues( newDoc("issue1", project).setTags(ImmutableSet.of("convention", "java8", "bug")), newDoc("issue2", project).setTags(ImmutableSet.of("convention", "bug")), @@ -1416,14 +1418,14 @@ public class IssueIndexTest { } private void assertThatFacetHasExactly(IssueQuery.Builder query, String facet, Map.Entry... expectedEntries) { - SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(asList(facet))); + SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(singletonList(facet))); Facets facets = new Facets(result, system2.getDefaultTimeZone()); assertThat(facets.getNames()).containsOnly(facet); assertThat(facets.get(facet)).containsExactly(expectedEntries); } private void assertThatFacetHasOnly(IssueQuery.Builder query, String facet, Map.Entry... expectedEntries) { - SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(asList(facet))); + SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(singletonList(facet))); Facets facets = new Facets(result, system2.getDefaultTimeZone()); assertThat(facets.getNames()).containsOnly(facet); assertThat(facets.get(facet)).containsOnly(expectedEntries); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIteratorFactoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIteratorFactoryTest.java index 633b0ab4f3c..a4dce3409d1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIteratorFactoryTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIteratorFactoryTest.java @@ -24,7 +24,6 @@ import com.google.common.collect.Maps; import java.util.Map; import org.junit.Rule; import org.junit.Test; -import org.sonar.api.rule.RuleKey; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; @@ -50,7 +49,7 @@ public class IssueIteratorFactoryTest { assertThat(issue.assignee()).isEqualTo("guy1"); assertThat(issue.authorLogin()).isEqualTo("guy2"); assertThat(issue.line()).isEqualTo(444); - assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("squid", "AvoidCycles")); + assertThat(issue.ruleId()).isEqualTo(200); assertThat(issue.componentUuid()).isEqualTo("FILE1"); assertThat(issue.projectUuid()).isEqualTo("PROJECT1"); assertThat(issue.moduleUuid()).isEqualTo("PROJECT1"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java index 1a64aa3a1ce..3b7f3fdce8d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java @@ -19,7 +19,6 @@ */ package org.sonar.server.issue.ws; -import java.io.IOException; import java.time.Clock; import java.util.Arrays; import java.util.Date; @@ -104,7 +103,8 @@ public class SearchActionComponentsTest { private SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), new WsResponseCommonFormat(languages), languages, new AvatarResolverImpl()); private PermissionIndexerTester permissionIndexer = new PermissionIndexerTester(es, issueIndexer); - private WsActionTester ws = new WsActionTester(new SearchAction(userSession, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat, System2.INSTANCE)); + private WsActionTester ws = new WsActionTester(new SearchAction(userSession, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat, System2.INSTANCE, + dbClient)); @Test public void search_all_issues_when_no_parameter() { diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java index 65abaa4ba0a..cf8cc73604a 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java @@ -80,6 +80,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_AFT import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_HIDE_COMMENTS; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PAGE_INDEX; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PAGE_SIZE; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_RULES; public class SearchActionTest { @@ -102,7 +103,8 @@ public class SearchActionTest { private SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSessionRule, dbClient, new TransitionService(userSessionRule, issueWorkflow)); private Languages languages = new Languages(); private SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), new WsResponseCommonFormat(languages), languages, new AvatarResolverImpl()); - private WsActionTester ws = new WsActionTester(new SearchAction(userSessionRule, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat, System2.INSTANCE)); + private WsActionTester ws = new WsActionTester(new SearchAction(userSessionRule, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat, System2.INSTANCE, + dbClient)); private OrganizationDto defaultOrganization; private OrganizationDto otherOrganization1; private OrganizationDto otherOrganization2; @@ -153,7 +155,7 @@ public class SearchActionTest { //SONAR-10217 @Test - public void empty_search_with_unknown_branch() throws Exception { + public void empty_search_with_unknown_branch() { TestResponse result = ws.newRequest() .setParam("onComponentOnly", "true") .setParam("componentKeys", "foo") @@ -165,7 +167,7 @@ public class SearchActionTest { } @Test - public void empty_search() throws Exception { + public void empty_search() { TestResponse result = ws.newRequest() .execute(); @@ -174,7 +176,7 @@ public class SearchActionTest { } @Test - public void response_contains_all_fields_except_additional_fields() throws Exception { + public void response_contains_all_fields_except_additional_fields() { dbClient.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com")); dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); @@ -203,7 +205,7 @@ public class SearchActionTest { } @Test - public void issue_with_comments() throws Exception { + public void issue_with_comments() { dbClient.userDao().insert(session, new UserDto().setLogin("john").setName("John")); dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); @@ -239,7 +241,7 @@ public class SearchActionTest { } @Test - public void issue_with_comment_hidden() throws Exception { + public void issue_with_comment_hidden() { dbClient.userDao().insert(session, new UserDto().setLogin("john").setName("John").setEmail("john@email.com")); dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); @@ -274,7 +276,7 @@ public class SearchActionTest { } @Test - public void load_additional_fields() throws Exception { + public void load_additional_fields() { dbClient.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com")); dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY").setLanguage("java")); @@ -296,7 +298,7 @@ public class SearchActionTest { } @Test - public void load_additional_fields_with_issue_admin_permission() throws Exception { + public void load_additional_fields_with_issue_admin_permission() { dbClient.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com")); dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY").setLanguage("java")); @@ -320,7 +322,29 @@ public class SearchActionTest { } @Test - public void issue_on_removed_file() throws Exception { + public void search_by_rule_key() { + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY").setLanguage("java")); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY").setLanguage("java")); + + IssueDto issue = IssueTesting.newIssue(rule.getDefinition(), project, file); + dbClient.issueDao().insert(session, issue); + session.commit(); + indexIssues(); + + userSessionRule.logIn("john") + .addProjectPermission(ISSUE_ADMIN, project); // granted by Anyone + indexPermissions(); + + TestResponse execute = ws.newRequest() + .setParam(PARAM_RULES, rule.getKey().toString()) + .setParam("additionalFields", "_all") + .execute(); + execute.assertJson(this.getClass(), "result_for_rule_search.json"); + } + + @Test + public void issue_on_removed_file() { RuleDto rule = newRule(); ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); indexPermissions(); @@ -345,7 +369,7 @@ public class SearchActionTest { } @Test - public void apply_paging_with_one_component() throws Exception { + public void apply_paging_with_one_component() { RuleDto rule = newRule(); ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); indexPermissions(); @@ -362,7 +386,7 @@ public class SearchActionTest { } @Test - public void components_contains_sub_projects() throws Exception { + public void components_contains_sub_projects() { ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("ProjectHavingModule")); indexPermissions(); ComponentDto module = insertComponent(ComponentTesting.newModuleDto(project).setDbKey("ModuleHavingFile")); @@ -377,7 +401,7 @@ public class SearchActionTest { } @Test - public void display_facets() throws Exception { + public void display_facets() { ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); indexPermissions(); ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); @@ -402,7 +426,7 @@ public class SearchActionTest { } @Test - public void display_facets_in_effort_mode() throws Exception { + public void display_facets_in_effort_mode() { ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); indexPermissions(); ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); @@ -428,7 +452,7 @@ public class SearchActionTest { } @Test - public void display_zero_valued_facets_for_selected_items() throws Exception { + public void display_zero_valued_facets_for_selected_items() { ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); indexPermissions(); ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); @@ -455,7 +479,7 @@ public class SearchActionTest { } @Test - public void assignedToMe_facet_must_escape_login_of_authenticated_user() throws Exception { + public void assignedToMe_facet_must_escape_login_of_authenticated_user() { // login looks like an invalid regexp userSessionRule.logIn("foo["); @@ -468,7 +492,7 @@ public class SearchActionTest { } @Test - public void filter_by_assigned_to_me() throws Exception { + public void filter_by_assigned_to_me() { dbClient.userDao().insert(session, new UserDto().setLogin("john").setName("John").setEmail("john@email.com")); ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "PROJECT_ID").setDbKey("PROJECT_KEY")); @@ -512,7 +536,7 @@ public class SearchActionTest { } @Test - public void filter_by_assigned_to_me_unauthenticated() throws Exception { + public void filter_by_assigned_to_me_unauthenticated() { userSessionRule.logIn(); ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); @@ -542,7 +566,7 @@ public class SearchActionTest { } @Test - public void assigned_to_me_facet_is_sticky_relative_to_assignees() throws Exception { + public void assigned_to_me_facet_is_sticky_relative_to_assignees() { dbClient.userDao().insert(session, new UserDto().setLogin("alice").setName("Alice").setEmail("alice@email.com")); ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); @@ -586,7 +610,7 @@ public class SearchActionTest { } @Test - public void sort_by_updated_at() throws Exception { + public void sort_by_updated_at() { RuleDto rule = newRule(); ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); indexPermissions(); @@ -611,7 +635,7 @@ public class SearchActionTest { } @Test - public void paging() throws Exception { + public void paging() { RuleDto rule = newRule(); ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); indexPermissions(); @@ -631,7 +655,7 @@ public class SearchActionTest { } @Test - public void paging_with_page_size_to_minus_one() throws Exception { + public void paging_with_page_size_to_minus_one() { RuleDto rule = newRule(); ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); indexPermissions(); @@ -651,7 +675,7 @@ public class SearchActionTest { } @Test - public void deprecated_paging() throws Exception { + public void deprecated_paging() { RuleDto rule = newRule(); ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "PROJECT_ID").setDbKey("PROJECT_KEY")); indexPermissions(); @@ -671,14 +695,14 @@ public class SearchActionTest { } @Test - public void default_page_size_is_100() throws Exception { + public void default_page_size_is_100() { ws.newRequest() .execute() .assertJson(this.getClass(), "default_page_size_is_100.json"); } @Test - public void display_deprecated_debt_fields() throws Exception { + public void display_deprecated_debt_fields() { ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); indexPermissions(); ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/result_for_rule_search.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/result_for_rule_search.json new file mode 100644 index 00000000000..fc0bc4ef013 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/result_for_rule_search.json @@ -0,0 +1,45 @@ +{ + "total": 1, + "p": 1, + "ps": 100, + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 1 + }, + "issues": [ { + "rule": "xoo:x1", + "component": "FILE_KEY", + "project": "PROJECT_KEY", + "flows": [], + "status": "OPEN", + "organization": "my-org-1" + }], + "components": [ { + "organization": "my-org-1", + "key": "FILE_KEY", + "uuid": "FILE_ID", + "enabled": true, + "qualifier": "FIL", + "name": "NAME_FILE_ID", + "longName": "null/NAME_FILE_ID", + "path": "null/NAME_FILE_ID" + }, + { + "organization": "my-org-1", + "key": "PROJECT_KEY", + "uuid": "PROJECT_ID", + "enabled": true, + "qualifier": "TRK", + "name": "NAME_PROJECT_ID", + "longName": "LONG_NAME_PROJECT_ID" + }], + "rules": [ + { + "key": "xoo:x1", + "name": "Rule name", + "lang": "xoo", + "status": "READY" + } + ] +} -- 2.39.5