From c7c5597fcdc30c7d887582e53be1067183aea886 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Thu, 22 Jan 2015 11:14:28 +0100 Subject: [PATCH] SONAR-6007 Allow to search for issues at directory level --- .../org/sonar/server/issue/IssueQuery.java | 14 +- .../sonar/server/issue/IssueQueryService.java | 2 + .../issue/filter/IssueFilterParameters.java | 3 +- .../sonar/server/issue/index/IssueIndex.java | 2 + .../sonar/server/issue/ws/SearchAction.java | 14 +- .../server/component/ComponentTesting.java | 45 ++-- .../server/issue/IssueQueryServiceTest.java | 2 + .../org/sonar/server/issue/IssueTesting.java | 1 + .../issue/index/IssueIndexMediumTest.java | 15 ++ .../issue/ws/SearchActionMediumTest.java | 244 +++++++++++------- .../ws/SearchActionMediumTest/issue.json | 6 - 11 files changed, 217 insertions(+), 131 deletions(-) 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 553239d0564..a2b3a4a12c7 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 @@ -60,6 +60,7 @@ public class IssueQuery { private final Collection components; private final Collection modules; private final Collection projects; + private final Collection directories; private final Collection rules; private final Collection actionPlans; private final Collection reporters; @@ -86,6 +87,7 @@ public class IssueQuery { this.components = defaultCollection(builder.components); this.modules = defaultCollection(builder.modules); this.projects = defaultCollection(builder.projects); + this.directories = defaultCollection(builder.directories); this.rules = defaultCollection(builder.rules); this.actionPlans = defaultCollection(builder.actionPlans); this.reporters = defaultCollection(builder.reporters); @@ -133,6 +135,10 @@ public class IssueQuery { return projects; } + public Collection directories() { + return directories; + } + public Collection rules() { return rules; } @@ -232,6 +238,7 @@ public class IssueQuery { private Collection components; private Collection modules; private Collection projects; + private Collection directories; private Collection rules; private Collection actionPlans; private Collection reporters; @@ -288,6 +295,11 @@ public class IssueQuery { return this; } + public Builder directories(@Nullable Collection l) { + this.directories = l; + return this; + } + public Builder rules(@Nullable Collection rules) { this.rules = rules; return this; @@ -403,7 +415,7 @@ public class IssueQuery { } public Builder ignorePaging(@Nullable Boolean ignorePaging) { - this.ignorePaging = ignorePaging; + this.ignorePaging = ignorePaging; return this; } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java index d3212112885..f4022a34b01 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java @@ -79,6 +79,7 @@ public class IssueQueryService implements ServerComponent { .onComponentOnly(RubyUtils.toBoolean(params.get(IssueFilterParameters.ON_COMPONENT_ONLY))) .assigned(RubyUtils.toBoolean(params.get(IssueFilterParameters.ASSIGNED))) .planned(RubyUtils.toBoolean(params.get(IssueFilterParameters.PLANNED))) + .directories(RubyUtils.toStrings(params.get(IssueFilterParameters.DIRECTORIES))) .hideRules(RubyUtils.toBoolean(params.get(IssueFilterParameters.HIDE_RULES))) .createdAt(RubyUtils.toDate(params.get(IssueFilterParameters.CREATED_AT))) .createdAfter(RubyUtils.toDate(params.get(IssueFilterParameters.CREATED_AFTER))) @@ -138,6 +139,7 @@ public class IssueQueryService implements ServerComponent { .onComponentOnly(request.paramAsBoolean(IssueFilterParameters.ON_COMPONENT_ONLY)) .assigned(request.paramAsBoolean(IssueFilterParameters.ASSIGNED)) .planned(request.paramAsBoolean(IssueFilterParameters.PLANNED)) + .directories(request.paramAsStrings(IssueFilterParameters.DIRECTORIES)) .createdAt(request.paramAsDateTime(IssueFilterParameters.CREATED_AT)) .createdAfter(request.paramAsDateTime(IssueFilterParameters.CREATED_AFTER)) .createdBefore(request.paramAsDateTime(IssueFilterParameters.CREATED_BEFORE)) diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterParameters.java b/server/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterParameters.java index d56999fcc88..fd4666a2681 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterParameters.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterParameters.java @@ -48,6 +48,7 @@ public class IssueFilterParameters { public static final String PROJECTS = "projects"; public static final String PROJECT_KEYS = "projectKeys"; public static final String PROJECT_UUIDS = "projectUuids"; + public static final String DIRECTORIES = "directories"; public static final String ON_COMPONENT_ONLY = "onComponentOnly"; public static final String RULES = "rules"; public static final String ACTION_PLANS = "actionPlans"; @@ -69,7 +70,7 @@ public class IssueFilterParameters { public static final List ALL = ImmutableList.of(ISSUES, SEVERITIES, STATUSES, RESOLUTIONS, RESOLVED, COMPONENTS, COMPONENT_ROOTS, RULES, ACTION_PLANS, REPORTERS, TAGS, ASSIGNEES, LANGUAGES, ASSIGNED, PLANNED, HIDE_RULES, CREATED_AT, CREATED_AFTER, CREATED_BEFORE, PAGE_SIZE, PAGE_INDEX, SORT, ASC, COMPONENT_UUIDS, COMPONENT_ROOT_UUIDS, - PROJECTS, PROJECT_UUIDS, IGNORE_PAGING, PROJECT_KEYS, COMPONENT_KEYS, MODULE_KEYS, MODULE_UUIDS); + PROJECTS, PROJECT_UUIDS, IGNORE_PAGING, PROJECT_KEYS, COMPONENT_KEYS, MODULE_KEYS, MODULE_UUIDS, DIRECTORIES); public static final List ALL_WITHOUT_PAGINATION = newArrayList(Iterables.filter(ALL, new Predicate() { @Override 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 396ad9010be..963afc6c05b 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 @@ -270,6 +270,8 @@ public class IssueIndex extends BaseIndex { FilterBuilder compositeFilter = componentFilter(componentUuids); filters.put(IssueIndexDefinition.FIELD_ISSUE_COMPONENT_UUID, compositeFilter); + + filters.put(IssueIndexDefinition.FIELD_ISSUE_DIRECTORY_PATH, matchFilter(IssueIndexDefinition.FIELD_ISSUE_DIRECTORY_PATH, query.directories())); } } 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 7b91182ccfc..0f615189b8f 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 @@ -63,13 +63,7 @@ import org.sonar.server.user.UserSession; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; @@ -246,6 +240,10 @@ public class SearchAction extends SearchRequestHandler { "Views are not supported. If this parameter is set, moduleKeys must not be set.") .setExampleValue("7d8749e8-3070-4903-9188-bdd82933bb92"); + action.createParam(IssueFilterParameters.DIRECTORIES) + .setDescription("Since 5.1. To retrieve issues associated to a specific list of directories (comma-separated list of directory paths). ") + .setExampleValue("7d8749e8-3070-4903-9188-bdd82933bb92"); + action.createParam(IssueFilterParameters.ON_COMPONENT_ONLY) .setDescription("Return only issues at the component's level, not on its descendants (modules, directories, files, etc.)") .setBooleanPossibleValues() @@ -545,7 +543,7 @@ public class SearchAction extends SearchRequestHandler { } private void writeTags(Issue issue, JsonWriter json) { - Collection tags = ((IssueDoc) issue).tags(); + Collection tags = issue.tags(); if (tags != null && !tags.isEmpty()) { json.name("tags").beginArray(); for (String tag: tags) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java index a00154575aa..ccbba1a36e4 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java @@ -34,38 +34,37 @@ public class ComponentTesting { } public static ComponentDto newFileDto(ComponentDto module, String fileUuid) { - return new ComponentDto() - .setUuid(fileUuid) - .setProjectUuid(module.projectUuid()) - .setModuleUuid(module.uuid()) - .setModuleUuidPath(module.moduleUuidPath() + module.uuid() + MODULE_UUID_PATH_SEP) + return newComponent(module, fileUuid) .setKey("KEY_" + fileUuid) .setName("NAME_" + fileUuid) .setLongName("LONG_NAME_" + fileUuid) - .setParentProjectId(module.getId()) .setScope(Scopes.FILE) .setQualifier(Qualifiers.FILE) .setPath("src/main/xoo/org/sonar/samples/File.xoo") - .setLanguage("xoo") - .setEnabled(true); + .setLanguage("xoo"); + } + + public static ComponentDto newDirectory(ComponentDto module, String path) { + String uuid = Uuids.create(); + return newComponent(module, uuid) + .setKey(!path.equals("/") ? module.getKey() + ":" + path : module.getKey() + ":/") + .setName(path) + .setLongName(path) + .setPath(path) + .setScope(Scopes.DIRECTORY) + .setQualifier(Qualifiers.DIRECTORY); } public static ComponentDto newModuleDto(ComponentDto subProjectOrProject) { String uuid = Uuids.create(); - return new ComponentDto() - .setUuid(Uuids.create()) - .setProjectUuid(subProjectOrProject.projectUuid()) - .setModuleUuid(subProjectOrProject.uuid()) - .setModuleUuidPath(subProjectOrProject.moduleUuidPath() + subProjectOrProject.uuid() + MODULE_UUID_PATH_SEP) + return newComponent(subProjectOrProject, uuid) .setKey("KEY_" + uuid) .setName("NAME_" + uuid) .setLongName("LONG_NAME_" + uuid) - .setParentProjectId(subProjectOrProject.getId()) + .setPath("module") .setScope(Scopes.PROJECT) .setQualifier(Qualifiers.MODULE) - .setPath("module") - .setLanguage(null) - .setEnabled(true); + .setLanguage(null); } public static ComponentDto newProjectDto() { @@ -77,14 +76,24 @@ public class ComponentTesting { .setUuid(uuid) .setProjectUuid(uuid) .setModuleUuidPath(MODULE_UUID_PATH_SEP) + .setParentProjectId(null) .setKey("KEY_" + uuid) .setName("NAME_" + uuid) .setLongName("LONG_NAME_" + uuid) - .setParentProjectId(null) .setScope(Scopes.PROJECT) .setQualifier(Qualifiers.PROJECT) .setPath(null) .setLanguage(null) .setEnabled(true); } + + private static ComponentDto newComponent(ComponentDto module, String uuid) { + return new ComponentDto() + .setUuid(uuid) + .setProjectUuid(module.projectUuid()) + .setModuleUuid(module.uuid()) + .setModuleUuidPath(module.moduleUuidPath() + module.uuid() + MODULE_UUID_PATH_SEP) + .setParentProjectId(module.getId()) + .setEnabled(true); + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryServiceTest.java index 673b911e83f..9d5ac839b70 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryServiceTest.java @@ -94,6 +94,7 @@ public class IssueQueryServiceTest { map.put("components", componentKeys); ArrayList moduleKeys = newArrayList("org.sonar"); map.put("moduleKeys", moduleKeys); + map.put("directories", newArrayList("/src/main/java/example")); map.put("reporters", newArrayList("marilyn")); map.put("assignees", newArrayList("joanna")); map.put("languages", newArrayList("xoo")); @@ -141,6 +142,7 @@ public class IssueQueryServiceTest { assertThat(query.planned()).isTrue(); assertThat(query.hideRules()).isTrue(); assertThat(query.rules()).hasSize(2); + assertThat(query.directories()).containsOnly("/src/main/java/example"); assertThat(query.createdAfter()).isEqualTo(DateUtils.parseDateTime("2013-04-16T09:08:24+0200")); assertThat(query.createdBefore()).isEqualTo(DateUtils.parseDateTime("2013-04-17T09:08:24+0200")); assertThat(query.sort()).isEqualTo(IssueQuery.SORT_BY_CREATION_DATE); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueTesting.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueTesting.java index 393b6d88eb1..f35e63e0463 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueTesting.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueTesting.java @@ -68,6 +68,7 @@ public class IssueTesting { doc.setComponentUuid("FILE_1"); doc.setEffortToFix(3.14); doc.setFilePath("src/Foo.xoo"); + doc.setDirectoryPath("/src"); doc.setMessage("the message"); doc.setModuleUuid("MODULE_1"); doc.setModuleUuidPath("MODULE_1"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java index a72066d0cea..7dce52187eb 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java @@ -194,6 +194,21 @@ public class IssueIndexMediumTest { assertThat(index.search(IssueQuery.builder().componentUuids(newArrayList("unknown")).build(), new QueryContext()).getHits()).isEmpty(); } + @Test + public void filter_by_directories() throws Exception { + ComponentDto project = ComponentTesting.newProjectDto(); + ComponentDto file1 = ComponentTesting.newFileDto(project).setPath("src/main/xoo/F1.xoo"); + ComponentDto file2 = ComponentTesting.newFileDto(project).setPath("F2.xoo"); + + indexIssues( + IssueTesting.newDoc("ISSUE1", file1).setDirectoryPath("/src/main/xoo"), + IssueTesting.newDoc("ISSUE2", file2).setDirectoryPath("/")); + + assertThat(index.search(IssueQuery.builder().directories(newArrayList("/src/main/xoo")).build(), new QueryContext()).getHits()).hasSize(1); + assertThat(index.search(IssueQuery.builder().directories(newArrayList("/")).build(), new QueryContext()).getHits()).hasSize(1); + assertThat(index.search(IssueQuery.builder().directories(newArrayList("unknown")).build(), new QueryContext()).getHits()).isEmpty(); + } + @Test public void filter_by_severities() throws Exception { ComponentDto project = ComponentTesting.newProjectDto(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java index 5f52d466439..b8b7022cb34 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java @@ -32,14 +32,12 @@ import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.KeyValueFormat; import org.sonar.api.web.UserRole; import org.sonar.core.component.ComponentDto; -import org.sonar.core.component.SnapshotDto; import org.sonar.core.issue.db.*; import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.persistence.DbSession; import org.sonar.core.rule.RuleDto; import org.sonar.core.user.UserDto; import org.sonar.server.component.ComponentTesting; -import org.sonar.server.component.SnapshotTesting; import org.sonar.server.db.DbClient; import org.sonar.server.issue.IssueQuery; import org.sonar.server.issue.IssueTesting; @@ -65,10 +63,6 @@ public class SearchActionMediumTest { DbClient db; DbSession session; WsTester wsTester; - RuleDto rule; - ComponentDto project; - ComponentDto file; - ComponentDto otherFile; @Before public void setUp() throws Exception { @@ -76,41 +70,6 @@ public class SearchActionMediumTest { db = tester.get(DbClient.class); wsTester = tester.get(WsTester.class); session = db.openSession(false); - - rule = RuleTesting.newXooX1() - .setName("Rule name") - .setDescription("Rule desc") - .setStatus(RuleStatus.READY); - tester.get(RuleDao.class).insert(session, rule); - - project = ComponentTesting.newProjectDto().setUuid("ABCD").setProjectUuid("ABCD") - .setKey("MyProject"); - db.componentDao().insert(session, project); - db.snapshotDao().insert(session, SnapshotTesting.createForProject(project)); - session.commit(); - - // project can be seen by anyone - MockUserSession.set().setLogin("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - tester.get(InternalPermissionService.class).addPermission(new PermissionChange().setComponentKey(project.getKey()).setGroup(DefaultGroups.ANYONE).setPermission(UserRole.USER)); - tester.get(InternalPermissionService.class).addPermission( - new PermissionChange().setComponentKey(project.getKey()).setGroup(DefaultGroups.ANYONE).setPermission(UserRole.CODEVIEWER)); - - file = ComponentTesting.newFileDto(project).setUuid("BCDE") - .setKey("MyComponent") - .setParentProjectId(project.getId()); - db.componentDao().insert(session, file); - - otherFile = ComponentTesting.newFileDto(project).setUuid("FEDC") - .setKey("OtherComponent") - .setParentProjectId(project.getId()); - db.componentDao().insert(session, otherFile); - - UserDto john = new UserDto().setLogin("john").setName("John").setEmail("john@email.com"); - db.userDao().insert(session, john); - - session.commit(); - - MockUserSession.set().setLogin("john").addComponentPermission(UserRole.CODEVIEWER, project.getKey(), file.getKey()).setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); } @After @@ -129,7 +88,7 @@ public class SearchActionMediumTest { assertThat(show.isPost()).isFalse(); assertThat(show.isInternal()).isFalse(); assertThat(show.responseExampleAsString()).isNotEmpty(); - assertThat(show.params()).hasSize(37); + assertThat(show.params()).hasSize(38); } @Test @@ -146,7 +105,10 @@ public class SearchActionMediumTest { db.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com")); db.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); - IssueDto issue = IssueTesting.newDto(rule, file, project) + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project) .setDebt(10L) .setStatus("OPEN").setResolution("OPEN") .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") @@ -168,8 +130,10 @@ public class SearchActionMediumTest { @Test public void issues_on_different_projects() throws Exception { - db.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com")); - + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); IssueDto issue = IssueTesting.newDto(rule, file, project) .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") .setStatus("OPEN").setResolution("OPEN") @@ -178,22 +142,9 @@ public class SearchActionMediumTest { .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")); db.issueDao().insert(session, issue); - ComponentDto project2 = ComponentTesting.newProjectDto().setUuid("DBCA").setProjectUuid("DBCA") - .setKey("MyProject2"); - db.componentDao().insert(session, project2); - db.snapshotDao().insert(session, SnapshotTesting.createForProject(project2)); - session.commit(); - - tester.get(InternalPermissionService.class) - .addPermission(new PermissionChange().setComponentKey(project2.getKey()).setGroup(DefaultGroups.ANYONE).setPermission(UserRole.USER)); - tester.get(InternalPermissionService.class).addPermission( - new PermissionChange().setComponentKey(project2.getKey()).setGroup(DefaultGroups.ANYONE).setPermission(UserRole.CODEVIEWER)); - - ComponentDto file2 = ComponentTesting.newFileDto(project2).setUuid("EDCB") - .setKey("MyComponent2") - .setParentProjectId(project2.getId()); - db.componentDao().insert(session, file2); - + ComponentDto project2 = insertComponent(ComponentTesting.newProjectDto("DBCA").setKey("MyProject2")); + setDefaultProjectPermission(project2); + ComponentDto file2 = insertComponent(ComponentTesting.newFileDto(project2, "EDCB").setKey("MyComponent2")); IssueDto issue2 = IssueTesting.newDto(rule, file2, project2) .setKee("92fd47d4-b650-4037-80bc-7b112bd4eac2") .setStatus("OPEN").setResolution("OPEN") @@ -210,9 +161,14 @@ public class SearchActionMediumTest { @Test public void issue_with_comment() throws Exception { + db.userDao().insert(session, new UserDto().setLogin("john").setName("John").setEmail("john@email.com")); db.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); - IssueDto issue = IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project) + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); db.issueDao().insert(session, issue); tester.get(IssueChangeDao.class).insert(session, @@ -232,14 +188,16 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); + MockUserSession.set().setLogin("john"); WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute(); result.assertJson(this.getClass(), "issue_with_comment.json", false); } @Test public void issue_with_action_plan() throws Exception { - db.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com")); - db.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); tester.get(ActionPlanDao.class).save(new ActionPlanDto() .setKey("AP-ABCD") @@ -251,7 +209,8 @@ public class SearchActionMediumTest { .setCreatedAt(DateUtils.parseDateTime("2014-01-22T19:10:03+0100")) .setUpdatedAt(DateUtils.parseDateTime("2014-01-23T19:10:03+0100"))); - IssueDto issue = IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") + IssueDto issue = IssueTesting.newDto(newRule(), file, project) + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") .setActionPlanKey("AP-ABCD"); db.issueDao().insert(session, issue); session.commit(); @@ -263,7 +222,10 @@ public class SearchActionMediumTest { @Test public void issue_with_attributes() throws Exception { - IssueDto issue = IssueTesting.newDto(rule, file, project) + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project) .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") .setIssueAttributes(KeyValueFormat.format(ImmutableMap.of("jira-issue-key", "SONAR-1234"))); db.issueDao().insert(session, issue); @@ -278,6 +240,9 @@ public class SearchActionMediumTest { public void issue_with_extra_fields() throws Exception { db.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com")); db.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); tester.get(ActionPlanDao.class).save(new ActionPlanDto() .setKey("AP-ABCD") @@ -286,7 +251,7 @@ public class SearchActionMediumTest { .setProjectId(project.getId()) .setUserLogin("simon")); - IssueDto issue = IssueTesting.newDto(rule, file, project) + IssueDto issue = IssueTesting.newDto(newRule(), file, project) .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") .setAuthorLogin("John") .setAssignee("simon") @@ -296,6 +261,7 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); + MockUserSession.set().setLogin("john"); WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) .setParam("extra_fields", "actions,transitions,assigneeName,reporterName,actionPlanName").execute(); result.assertJson(this.getClass(), "issue_with_extra_fields.json", false); @@ -303,11 +269,12 @@ public class SearchActionMediumTest { @Test public void issue_linked_on_removed_file() throws Exception { - ComponentDto removedFile = ComponentTesting.newFileDto(project).setUuid("EDCB") + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto removedFile = insertComponent(ComponentTesting.newFileDto(project).setUuid("EDCB") .setEnabled(false) - .setKey("RemovedComponent") - .setParentProjectId(project.getId()); - db.componentDao().insert(session, removedFile); + .setKey("RemovedComponent")); IssueDto issue = IssueTesting.newDto(rule, removedFile, project) .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") @@ -326,7 +293,10 @@ public class SearchActionMediumTest { @Test public void issue_contains_component_id_for_eclipse() throws Exception { - IssueDto issue = IssueTesting.newDto(rule, file, project); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project); db.issueDao().insert(session, issue); session.commit(); tester.get(IssueIndexer.class).indexAll(); @@ -337,7 +307,11 @@ public class SearchActionMediumTest { @Test public void search_by_project_uuid() throws Exception { - db.issueDao().insert(session, IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); + db.issueDao().insert(session, issue); session.commit(); tester.get(IssueIndexer.class).indexAll(); @@ -354,7 +328,11 @@ public class SearchActionMediumTest { @Test public void search_by_component_uuid() throws Exception { - db.issueDao().insert(session, IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); + db.issueDao().insert(session, issue); session.commit(); tester.get(IssueIndexer.class).indexAll(); @@ -369,8 +347,34 @@ public class SearchActionMediumTest { .assertJson(this.getClass(), "no_issue.json", false); } + @Test + public void search_by_directory_path() throws Exception { + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto directory = insertComponent(ComponentTesting.newDirectory(project, "src/main/java/dir")); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent").setPath(directory.path() + "/MyComponent.java")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); + db.issueDao().insert(session, issue); + session.commit(); + tester.get(IssueIndexer.class).indexAll(); + + wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) + .setParam(IssueFilterParameters.DIRECTORIES, "/src/main/java/dir") + .execute() + .assertJson(this.getClass(), "search_by_file_uuid.json", false); + + wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) + .setParam(IssueFilterParameters.DIRECTORIES, "/src/main/java") + .execute() + .assertJson(this.getClass(), "no_issue.json", false); + } + @Test public void ignore_paging_with_one_component() throws Exception { + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); for (int i = 0; i < QueryContext.MAX_LIMIT + 1; i++) { IssueDto issue = IssueTesting.newDto(rule, file, project); tester.get(IssueDao.class).insert(session, issue); @@ -387,6 +391,10 @@ public class SearchActionMediumTest { @Test public void apply_paging_with_multiple_components() throws Exception { + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); for (int i = 0; i < QueryContext.MAX_LIMIT + 1; i++) { IssueDto issue = IssueTesting.newDto(rule, file, project); tester.get(IssueDao.class).insert(session, issue); @@ -394,6 +402,8 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); + ComponentDto otherFile = insertComponent(ComponentTesting.newFileDto(project).setUuid("FEDC").setKey("OtherComponent")); + WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) .setParam(IssueFilterParameters.COMPONENTS, file.getKey() + "," + otherFile.getKey()) .setParam(IssueFilterParameters.IGNORE_PAGING, "true") @@ -403,6 +413,10 @@ public class SearchActionMediumTest { @Test public void apply_paging_with_one_component() throws Exception { + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); for (int i = 0; i < QueryContext.MAX_LIMIT + 1; i++) { IssueDto issue = IssueTesting.newDto(rule, file, project); tester.get(IssueDao.class).insert(session, issue); @@ -416,26 +430,11 @@ public class SearchActionMediumTest { @Test public void components_contains_sub_projects() throws Exception { - ComponentDto project = ComponentTesting.newProjectDto().setKey("ProjectHavingModule"); - db.componentDao().insert(session, project); - SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project); - db.snapshotDao().insert(session, projectSnapshot); - session.commit(); - - // project can be seen by anyone - tester.get(InternalPermissionService.class).addPermission(new PermissionChange().setComponentKey(project.getKey()).setGroup(DefaultGroups.ANYONE).setPermission(UserRole.USER)); - - ComponentDto module = ComponentTesting.newFileDto(project).setKey("ModuleHavingFile") - .setScope("PRJ") - .setParentProjectId(project.getId()); - db.componentDao().insert(session, module); - db.snapshotDao().insert(session, SnapshotTesting.createForComponent(module, projectSnapshot)); - - ComponentDto file = ComponentTesting.newFileDto(module).setKey("FileLinkedToModule"); - db.componentDao().insert(session, file); - db.snapshotDao().insert(session, SnapshotTesting.createForComponent(file, projectSnapshot)); - - IssueDto issue = IssueTesting.newDto(rule, file, project); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("ProjectHavingModule")); + setDefaultProjectPermission(project); + ComponentDto module = insertComponent(ComponentTesting.newModuleDto(project).setKey("ModuleHavingFile")); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(module, "BCDE").setKey("FileLinkedToModule")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project); db.issueDao().insert(session, issue); session.commit(); tester.get(IssueIndexer.class).indexAll(); @@ -446,7 +445,10 @@ public class SearchActionMediumTest { @Test public void display_facets() throws Exception { - IssueDto issue = IssueTesting.newDto(rule, file, project) + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project) .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) .setDebt(10L) @@ -457,6 +459,7 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); + MockUserSession.set().setLogin("john"); WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) .setParam("resolved", "false") .setParam(SearchAction.PARAM_FACETS, "statuses,severities,resolutions,projectUuids,rules,componentUuids,assignees,languages,actionPlans") @@ -466,7 +469,10 @@ public class SearchActionMediumTest { @Test public void display_zero_valued_facets_for_selected_items() throws Exception { - IssueDto issue = IssueTesting.newDto(rule, file, project) + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project) .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) .setDebt(10L) @@ -477,6 +483,7 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); + MockUserSession.set().setLogin("john"); WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) .setParam("resolved", "false") .setParam("severities", "MAJOR,MINOR") @@ -488,7 +495,10 @@ public class SearchActionMediumTest { @Test public void hide_rules() throws Exception { - IssueDto issue = IssueTesting.newDto(rule, file, project) + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project) .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) .setDebt(10L) @@ -505,6 +515,10 @@ public class SearchActionMediumTest { @Test public void sort_by_updated_at() throws Exception { + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); db.issueDao().insert(session, IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac1").setIssueUpdateDate(DateUtils.parseDate("2014-11-02"))); db.issueDao().insert(session, IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2").setIssueUpdateDate(DateUtils.parseDate("2014-11-01"))); db.issueDao().insert(session, IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac3").setIssueUpdateDate(DateUtils.parseDate("2014-11-03"))); @@ -520,6 +534,10 @@ public class SearchActionMediumTest { @Test public void paging() throws Exception { + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); for (int i = 0; i < 12; i++) { IssueDto issue = IssueTesting.newDto(rule, file, project); tester.get(IssueDao.class).insert(session, issue); @@ -537,6 +555,10 @@ public class SearchActionMediumTest { @Test public void paging_with_page_size_to_minus_one() throws Exception { + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); for (int i = 0; i < 12; i++) { IssueDto issue = IssueTesting.newDto(rule, file, project); tester.get(IssueDao.class).insert(session, issue); @@ -554,6 +576,10 @@ public class SearchActionMediumTest { @Test public void deprecated_paging() throws Exception { + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newProjectDto("ABCD").setKey("MyProject")); + setDefaultProjectPermission(project); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, "BCDE").setKey("MyComponent")); for (int i = 0; i < 12; i++) { IssueDto issue = IssueTesting.newDto(rule, file, project); tester.get(IssueDao.class).insert(session, issue); @@ -576,4 +602,28 @@ public class SearchActionMediumTest { WsTester.Result result = request.execute(); result.assertJson(this.getClass(), "default_page_size_is_100.json", false); } + + private RuleDto newRule() { + RuleDto rule = RuleTesting.newXooX1() + .setName("Rule name") + .setDescription("Rule desc") + .setStatus(RuleStatus.READY); + tester.get(RuleDao.class).insert(session, rule); + session.commit(); + return rule; + } + + private void setDefaultProjectPermission(ComponentDto project) { + // project can be seen by anyone and by code viewer + MockUserSession.set().setLogin("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + tester.get(InternalPermissionService.class).addPermission(new PermissionChange().setComponentKey(project.getKey()).setGroup(DefaultGroups.ANYONE).setPermission(UserRole.USER)); + MockUserSession.set(); + } + + private ComponentDto insertComponent(ComponentDto component) { + db.componentDao().insert(session, component); + session.commit(); + return component; + } + } diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/issue.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/issue.json index f8b21d5396b..ece88f7ed43 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/issue.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/issue.json @@ -59,12 +59,6 @@ "name": "Fabrice", "active": true, "email": "fabrice@email.com" - }, - { - "login": "john", - "name": "John", - "active": true, - "email": "john@email.com" } ] } -- 2.39.5