]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6007 Allow to search for issues at directory level
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 22 Jan 2015 10:14:28 +0000 (11:14 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 22 Jan 2015 10:14:28 +0000 (11:14 +0100)
server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java
server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java
server/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterParameters.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java
server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryServiceTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueTesting.java
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/issue.json

index 553239d0564f30e5a798d545d610d62d88f8755f..a2b3a4a12c776e3895a3efb5aa4c4de62815e72d 100644 (file)
@@ -60,6 +60,7 @@ public class IssueQuery {
   private final Collection<String> components;
   private final Collection<String> modules;
   private final Collection<String> projects;
+  private final Collection<String> directories;
   private final Collection<RuleKey> rules;
   private final Collection<String> actionPlans;
   private final Collection<String> 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<String> directories() {
+    return directories;
+  }
+
   public Collection<RuleKey> rules() {
     return rules;
   }
@@ -232,6 +238,7 @@ public class IssueQuery {
     private Collection<String> components;
     private Collection<String> modules;
     private Collection<String> projects;
+    private Collection<String> directories;
     private Collection<RuleKey> rules;
     private Collection<String> actionPlans;
     private Collection<String> reporters;
@@ -288,6 +295,11 @@ public class IssueQuery {
       return this;
     }
 
+    public Builder directories(@Nullable Collection<String> l) {
+      this.directories = l;
+      return this;
+    }
+
     public Builder rules(@Nullable Collection<RuleKey> 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;
     }
   }
index d321211288578b4d6926117b4f1ea1cc5ff75e2b..f4022a34b019f6befdb7ac1b1af2f2a21240e6ff 100644 (file)
@@ -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))
index d56999fcc88e5de95197eec4aa7fa0abb644685c..fd4666a26817daf742b244fed2d0235c06ae98bd 100644 (file)
@@ -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<String> 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<String> ALL_WITHOUT_PAGINATION = newArrayList(Iterables.filter(ALL, new Predicate<String>() {
     @Override
index 396ad9010be1cd40018ede4190d17468dff2aaa6..963afc6c05baa79e52e2e2e6110066e4ccebe7e9 100644 (file)
@@ -270,6 +270,8 @@ public class IssueIndex extends BaseIndex<Issue, FakeIssueDto, String> {
 
       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()));
     }
   }
 
index 7b91182ccfc5c2ba8b6cddd24bf69ccf4acfad0d..0f615189b8f1b43c58713b7c09c7347f18fc52c3 100644 (file)
@@ -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<IssueQuery, Issue> {
         "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<IssueQuery, Issue> {
   }
 
   private void writeTags(Issue issue, JsonWriter json) {
-    Collection<String> tags = ((IssueDoc) issue).tags();
+    Collection<String> tags = issue.tags();
     if (tags != null && !tags.isEmpty()) {
       json.name("tags").beginArray();
       for (String tag: tags) {
index a00154575aa942e5e1bc09a9ab2b2c61e18e1018..ccbba1a36e49760389a46205cd6cf24324b17ace 100644 (file)
@@ -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);
+  }
 }
index 673b911e83fbc4c0385e8cf42d6c0e0c67c06843..9d5ac839b70298efc600bc90426aa3ab4ac6727f 100644 (file)
@@ -94,6 +94,7 @@ public class IssueQueryServiceTest {
     map.put("components", componentKeys);
     ArrayList<String> 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);
index 393b6d88eb15a2c2dce09aea4e43cb9759d3a966..f35e63e046378c4518453320914ce0091e8c6246 100644 (file)
@@ -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");
index a72066d0cea9ee8887555e1b2242795d6ff4fcab..7dce52187eb0ad244b303a21f4d10dc7ece19752 100644 (file)
@@ -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();
index 5f52d466439b9474289e5018a80643da20fe2b58..b8b7022cb3442ca756eed150fe4d99168c04576f 100644 (file)
@@ -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;
+  }
+
 }
index f8b21d5396bdbdce7cbb27e7af31e712f6502184..ece88f7ed436b74fc9ea6e45a8bf3a3902a1d966 100644 (file)
       "name": "Fabrice",
       "active": true,
       "email": "fabrice@email.com"
-    },
-    {
-      "login": "john",
-      "name": "John",
-      "active": true,
-      "email": "john@email.com"
     }
   ]
 }