]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9616 Allow usage of main branch in ws having branch parameter
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 31 Aug 2017 14:19:51 +0000 (16:19 +0200)
committerJanos Gyerik <janos.gyerik@sonarsource.com>
Tue, 12 Sep 2017 09:34:58 +0000 (11:34 +0200)
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java
server/sonar-server/src/main/java/org/sonar/server/issue/IssueQuery.java
server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryFactory.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
server/sonar-server/src/test/java/org/sonar/server/component/ComponentFinderTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryFactoryTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java

index 5806296250bc81ac1c4fa92d5a92dbdb0b79a24e..d911187f8a045ffb954b878c88a819af4ef5eddf 100644 (file)
@@ -29,13 +29,13 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Set;
+import java.util.stream.Stream;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.apache.ibatis.session.ResultHandler;
 import org.apache.ibatis.session.RowBounds;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.resources.Scopes;
-import org.sonar.core.util.stream.MoreCollectors;
 import org.sonar.db.Dao;
 import org.sonar.db.DbSession;
 import org.sonar.db.RowNotFoundException;
@@ -44,6 +44,7 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Collections.emptyList;
 import static java.util.Objects.requireNonNull;
 import static org.apache.commons.lang.StringUtils.isBlank;
+import static org.sonar.core.util.stream.MoreCollectors.toList;
 import static org.sonar.db.DaoDatabaseUtils.buildLikeValue;
 import static org.sonar.db.DatabaseUtils.executeLargeInputs;
 import static org.sonar.db.DatabaseUtils.executeLargeUpdates;
@@ -172,8 +173,9 @@ public class ComponentDao implements Dao {
   }
 
   public List<ComponentDto> selectByKeysAndBranch(DbSession session, Collection<String> keys, String branch) {
-    List<String> dbKeys = keys.stream().map(k -> generateBranchKey(k, branch)).collect(MoreCollectors.toList());
-    return executeLargeInputs(dbKeys, mapper(session)::selectByDbKeys);
+    List<String> dbKeys = keys.stream().map(k -> generateBranchKey(k, branch)).collect(toList());
+    List<String> allKeys = Stream.of(keys, dbKeys) .flatMap(x -> x.stream()) .collect(toList());
+    return executeLargeInputs(allKeys, subKeys -> mapper(session).selectByKeysAndBranch(subKeys, branch));
   }
 
   public List<ComponentDto> selectComponentsHavingSameKeyOrderedById(DbSession session, String key) {
@@ -222,7 +224,7 @@ public class ComponentDao implements Dao {
   }
 
   public java.util.Optional<ComponentDto> selectByKeyAndBranch(DbSession session, String key, String branch) {
-    return java.util.Optional.ofNullable(mapper(session).selectByDbKey(generateBranchKey(key, branch)));
+    return java.util.Optional.ofNullable(mapper(session).selectByKeyAndBranch(key, generateBranchKey(key, branch), branch));
   }
 
   public List<UuidWithProjectUuidDto> selectAllViewsAndSubViews(DbSession session) {
index 0f3f5d74c330ce0795e322032395919bab24e4e4..ca7da22e6456c698ad6ef9fe75b1232591bdcb3c 100644 (file)
@@ -33,11 +33,8 @@ public interface ComponentMapper {
   @CheckForNull
   ComponentDto selectByKey(String key);
 
-  /**
-   * This method should be used to get a component by its key without filtering out branches
-   */
   @CheckForNull
-  ComponentDto selectByDbKey(String dbKey);
+  ComponentDto selectByKeyAndBranch(@Param("key") String key, @Param("dbKey") String dbKey, @Param("branch") String branch);
 
   @CheckForNull
   ComponentDto selectById(long id);
@@ -52,7 +49,7 @@ public interface ComponentMapper {
 
   List<ComponentDto> selectByKeys(@Param("keys") Collection<String> keys);
 
-  List<ComponentDto> selectByDbKeys(@Param("keys") Collection<String> keys);
+  List<ComponentDto> selectByKeysAndBranch(@Param("keys") Collection<String> keys, @Param("branch") String branch);
 
   List<ComponentDto> selectByIds(@Param("ids") Collection<Long> ids);
 
index 6031646c260ed22329062b73d990b6826e104c99..dec681a80fd824eca42e549b1ac550ff9265144d 100644 (file)
       p.kee=#{key,jdbcType=VARCHAR}
   </select>
 
-  <select id="selectByDbKey" parameterType="String" resultType="Component">
+  <select id="selectByKeyAndBranch" parameterType="String" resultType="Component">
     SELECT
     <include refid="componentColumns"/>
     FROM projects p
-    where
-    p.kee=#{key,jdbcType=VARCHAR}
+    INNER JOIN project_branches pb on pb.uuid = p.project_uuid
+    <where>
+      (p.kee=#{dbKey,jdbcType=VARCHAR} OR p.kee=#{key,jdbcType=VARCHAR})
+      AND pb.kee=#{branch,jdbcType=VARCHAR}
+    </where>
   </select>
 
   <select id="selectComponentsHavingSameKeyOrderedById" parameterType="String" resultType="Component">
       </foreach>
   </select>
 
-  <select id="selectByDbKeys" parameterType="String" resultType="Component">
-    select
+  <select id="selectByKeysAndBranch" parameterType="String" resultType="Component">
+    SELECT
     <include refid="componentColumns"/>
-    from projects p
-    where
+    FROM projects p
+    INNER JOIN project_branches pb on pb.uuid = p.project_uuid
+    <where>
     p.enabled=${_true}
-    and p.kee in
+    AND p.kee IN
     <foreach collection="keys" open="(" close=")" item="key" separator=",">
       #{key,jdbcType=VARCHAR}
     </foreach>
+    AND pb.kee=#{branch,jdbcType=VARCHAR}
+    </where>
   </select>
 
   <select id="selectByIds" parameterType="long" resultType="Component">
index ea464ee5f5f719a785a0d93a33e95fce7c8b41fd..a48bcf8f5b796b4f695514710d042620ef6e421b 100644 (file)
@@ -192,11 +192,12 @@ public class ComponentDaoTest {
 
   @Test
   public void selectByKeyAndBranch() {
-    ComponentDto project = db.components().insertPrivateProject();
+    ComponentDto project = db.components().insertMainBranch();
     ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
     ComponentDto file = db.components().insertComponent(newFileDto(branch));
 
-    assertThat(underTest.selectByKeyAndBranch(dbSession, project.getKey(), "my_branch").get().uuid()).isEqualTo(branch.uuid());
+    assertThat(underTest.selectByKeyAndBranch(dbSession, project.getKey(), "master").get().uuid()).isEqualTo(project.uuid());
+    assertThat(underTest.selectByKeyAndBranch(dbSession, branch.getKey(), "my_branch").get().uuid()).isEqualTo(branch.uuid());
     assertThat(underTest.selectByKeyAndBranch(dbSession, file.getKey(), "my_branch").get().uuid()).isEqualTo(file.uuid());
     assertThat(underTest.selectByKeyAndBranch(dbSession, "unknown", "my_branch")).isNotPresent();
     assertThat(underTest.selectByKeyAndBranch(dbSession, file.getKey(), "unknown")).isNotPresent();
@@ -251,7 +252,7 @@ public class ComponentDaoTest {
 
   @Test
   public void selectByKeysAndBranch() {
-    ComponentDto project = db.components().insertPrivateProject();
+    ComponentDto project = db.components().insertMainBranch();
     ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
     ComponentDto file1 = db.components().insertComponent(newFileDto(branch));
     ComponentDto file2 = db.components().insertComponent(newFileDto(branch));
@@ -265,6 +266,7 @@ public class ComponentDaoTest {
     assertThat(underTest.selectByKeysAndBranch(dbSession, singletonList(fileOnAnotherBranch.getKey()), "my_branch")).isEmpty();
     assertThat(underTest.selectByKeysAndBranch(dbSession, singletonList(file1.getKey()), "unknown")).isEmpty();
     assertThat(underTest.selectByKeysAndBranch(dbSession, singletonList("unknown"), "my_branch")).isEmpty();
+    assertThat(underTest.selectByKeysAndBranch(dbSession, singletonList(branch.getKey()), "master")).extracting(ComponentDto::uuid).containsExactlyInAnyOrder(project.uuid());
   }
 
   @Test
index 35538b9fc77b820a8be6b1b3e77bb1a3060a83be..043aa05f2fd5db7b4fa92fb8e6d9056306af8267 100644 (file)
@@ -82,6 +82,7 @@ public class IssueQuery {
   private final String facetMode;
   private final String organizationUuid;
   private final String branchUuid;
+  private final boolean mainBranch;
   private final boolean checkAuthorization;
 
   private IssueQuery(Builder builder) {
@@ -115,6 +116,7 @@ public class IssueQuery {
     this.facetMode = builder.facetMode;
     this.organizationUuid = builder.organizationUuid;
     this.branchUuid = builder.branchUuid;
+    this.mainBranch = builder.mainBranch;
   }
 
   public Collection<String> issueKeys() {
@@ -243,6 +245,10 @@ public class IssueQuery {
     return branchUuid;
   }
 
+  public boolean isMainBranch() {
+    return mainBranch;
+  }
+
   public String facetMode() {
     return facetMode;
   }
@@ -287,6 +293,7 @@ public class IssueQuery {
     private String facetMode;
     private String organizationUuid;
     private String branchUuid;
+    private boolean mainBranch = true;
 
     private Builder() {
 
@@ -463,6 +470,11 @@ public class IssueQuery {
       this.branchUuid = s;
       return this;
     }
+
+    public Builder mainBranch(boolean mainBranch) {
+      this.mainBranch = mainBranch;
+      return this;
+    }
   }
 
   private static <T> Collection<T> defaultCollection(@Nullable Collection<T> c) {
index 71e53f29e5ce341d8def0f52944b442c6a8ddf3c..678de1ce81d7ca151b07bb04e7d31176733bb29f 100644 (file)
@@ -234,11 +234,10 @@ public class IssueQueryFactory {
   private void addComponentParameters(IssueQuery.Builder builder, DbSession session, boolean onComponentOnly,
     List<ComponentDto> components, SearchWsRequest request) {
 
-    String branch = request.getBranch();
     builder.onComponentOnly(onComponentOnly);
     if (onComponentOnly) {
       builder.componentUuids(components.stream().map(ComponentDto::uuid).collect(toList()));
-      builder.branchUuid(branch == null ? null : components.get(0).projectUuid());
+      setBranch(builder, components.get(0), request.getBranch());
       return;
     }
 
@@ -249,9 +248,9 @@ public class IssueQueryFactory {
     if (projectUuids != null) {
       builder.projectUuids(projectUuids);
     } else if (projectKeys != null) {
-      List<ComponentDto> projects = getComponentsFromKeys(session, projectKeys, branch);
-      builder.projectUuids(projects.stream().map(p -> branch == null ? p.projectUuid() : p.getMainBranchProjectUuid()).collect(toList()));
-      builder.branchUuid(branch == null ? null : projects.get(0).projectUuid());
+      List<ComponentDto> projects = getComponentsFromKeys(session, projectKeys, request.getBranch());
+      builder.projectUuids(projects.stream().map(IssueQueryFactory::toProjectUuid).collect(toList()));
+      setBranch(builder, projects.get(0), request.getBranch());
     }
     builder.moduleUuids(request.getModuleUuids());
     builder.directories(request.getDirectories());
@@ -272,8 +271,7 @@ public class IssueQueryFactory {
     Set<String> qualifiers = components.stream().map(ComponentDto::qualifier).collect(toHashSet());
     checkArgument(qualifiers.size() == 1, "All components must have the same qualifier, found %s", String.join(",", qualifiers));
 
-    String branch = request.getBranch();
-    builder.branchUuid(branch == null ? null : components.get(0).projectUuid());
+    setBranch(builder, components.get(0), request.getBranch());
     String qualifier = qualifiers.iterator().next();
     switch (qualifier) {
       case Qualifiers.VIEW:
@@ -284,7 +282,7 @@ public class IssueQueryFactory {
         addApplications(builder, dbSession, components, request);
         break;
       case Qualifiers.PROJECT:
-        builder.projectUuids(components.stream().map(c -> branch == null ? c.projectUuid() : c.getMainBranchProjectUuid()).collect(toList()));
+        builder.projectUuids(components.stream().map(IssueQueryFactory::toProjectUuid).collect(toList()));
         break;
       case Qualifiers.MODULE:
         builder.moduleRootUuids(components.stream().map(ComponentDto::uuid).collect(toList()));
@@ -388,4 +386,14 @@ public class IssueQueryFactory {
     }
     return null;
   }
+
+  private static String toProjectUuid(ComponentDto componentDto) {
+    String mainBranchProjectUuid = componentDto.getMainBranchProjectUuid();
+    return mainBranchProjectUuid == null ? componentDto.projectUuid() : mainBranchProjectUuid;
+  }
+
+  private static void setBranch(IssueQuery.Builder builder, ComponentDto component, @Nullable String branch){
+    builder.branchUuid(branch == null ? null : component.projectUuid());
+    builder.mainBranch(branch == null || !branch.equals(component.getBranch()));
+  }
 }
index 107f49b3a8ae997d71c341c54a9eddc8227ab593..188a6a9e5987cc95354fc988b217a6e9cb21d204 100644 (file)
@@ -209,7 +209,7 @@ public class IssueIndex {
     QueryBuilder directoryFilter = createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_DIRECTORY_PATH, query.directories());
     QueryBuilder fileFilter = createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_COMPONENT_UUID, query.fileUuids());
     QueryBuilder branchFilter = createTermFilter(IssueIndexDefinition.FIELD_ISSUE_BRANCH_UUID, query.branchUuid());
-    filters.put("__is_main_branch", createTermFilter(IssueIndexDefinition.FIELD_ISSUE_IS_MAIN_BRANCH, Boolean.toString(query.branchUuid() == null)));
+    filters.put("__is_main_branch", createTermFilter(IssueIndexDefinition.FIELD_ISSUE_IS_MAIN_BRANCH, Boolean.toString(query.isMainBranch())));
 
     if (BooleanUtils.isTrue(query.onComponentOnly())) {
       filters.put(IssueIndexDefinition.FIELD_ISSUE_COMPONENT_UUID, componentFilter);
index 477acb543d85a7eb58d122593f852f63f26a2b46..ea314a825d862a9f48bb2940e52c3f36aeb827fb 100644 (file)
@@ -180,7 +180,7 @@ public class ComponentFinderTest {
 
   @Test
   public void get_by_key_and_branch() {
-    ComponentDto project = db.components().insertPrivateProject();
+    ComponentDto project = db.components().insertMainBranch();
     ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
     ComponentDto module = db.components().insertComponent(newModuleDto(branch));
     ComponentDto directory = db.components().insertComponent(newDirectory(module, "scr"));
@@ -192,6 +192,13 @@ public class ComponentFinderTest {
     assertThat(underTest.getByKeyAndBranch(dbSession, directory.getKey(), "my_branch").uuid()).isEqualTo(directory.uuid());
   }
 
+  @Test
+  public void get_by_key_and_branch_accept_main_branch() {
+    ComponentDto project = db.components().insertMainBranch();
+
+    assertThat(underTest.getByKeyAndBranch(dbSession, project.getKey(), "master").uuid()).isEqualTo(project.uuid());
+  }
+
   @Test
   public void fail_to_get_by_key_and_branch_when_branch_does_not_exist() {
     ComponentDto project = db.components().insertPrivateProject();
index 01ad51d4888a8e9c6e786538beafe8144e018225..2ac3e6455c4a12fc0d4cbb12cc2ef0053b6d9fe2 100644 (file)
@@ -356,14 +356,14 @@ public class IssueQueryFactoryTest {
     assertThat(underTest.create(new SearchWsRequest()
       .setProjectKeys(singletonList(branch.getKey()))
       .setBranch(branch.getBranch())))
-        .extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.projectUuids()))
-        .containsOnly(branch.uuid(), singletonList(project.uuid()));
+        .extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.projectUuids()), IssueQuery::isMainBranch)
+        .containsOnly(branch.uuid(), singletonList(project.uuid()), false);
 
     assertThat(underTest.create(new SearchWsRequest()
       .setComponentKeys(singletonList(branch.getKey()))
       .setBranch(branch.getBranch())))
-        .extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.projectUuids()))
-        .containsOnly(branch.uuid(), singletonList(project.uuid()));
+        .extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.projectUuids()), IssueQuery::isMainBranch)
+        .containsOnly(branch.uuid(), singletonList(project.uuid()), false);
   }
 
   @Test
@@ -375,22 +375,22 @@ public class IssueQueryFactoryTest {
     assertThat(underTest.create(new SearchWsRequest()
       .setComponentKeys(singletonList(file.getKey()))
       .setBranch(branch.getBranch())))
-        .extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.fileUuids()))
-        .containsOnly(branch.uuid(), singletonList(file.uuid()));
+        .extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.fileUuids()), IssueQuery::isMainBranch)
+        .containsOnly(branch.uuid(), singletonList(file.uuid()), false);
 
     assertThat(underTest.create(new SearchWsRequest()
       .setComponentKeys(singletonList(branch.getKey()))
       .setFileUuids(singletonList(file.uuid()))
       .setBranch(branch.getBranch())))
-        .extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.fileUuids()))
-        .containsOnly(branch.uuid(), singletonList(file.uuid()));
+        .extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.fileUuids()), IssueQuery::isMainBranch)
+        .containsOnly(branch.uuid(), singletonList(file.uuid()), false);
 
     assertThat(underTest.create(new SearchWsRequest()
       .setProjectKeys(singletonList(branch.getKey()))
       .setFileUuids(singletonList(file.uuid()))
       .setBranch(branch.getBranch())))
-        .extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.fileUuids()))
-        .containsOnly(branch.uuid(), singletonList(file.uuid()));
+        .extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.fileUuids()), IssueQuery::isMainBranch)
+        .containsOnly(branch.uuid(), singletonList(file.uuid()), false);
   }
 
   @Test
@@ -403,8 +403,25 @@ public class IssueQueryFactoryTest {
       .setComponentKeys(singletonList(file.getKey()))
       .setBranch(branch.getBranch())
       .setOnComponentOnly(true)))
-      .extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.componentUuids()))
-      .containsOnly(branch.uuid(), singletonList(file.uuid()));
+      .extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.componentUuids()), IssueQuery::isMainBranch)
+      .containsOnly(branch.uuid(), singletonList(file.uuid()), false);
+  }
+
+  @Test
+  public void search_issues_from_main_branch() {
+    ComponentDto project = db.components().insertMainBranch();
+    ComponentDto branch = db.components().insertProjectBranch(project);
+
+    assertThat(underTest.create(new SearchWsRequest()
+      .setProjectKeys(singletonList(project.getKey()))
+      .setBranch("master")))
+      .extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.projectUuids()), IssueQuery::isMainBranch)
+      .containsOnly(project.uuid(), singletonList(project.uuid()), true);
+    assertThat(underTest.create(new SearchWsRequest()
+      .setComponentKeys(singletonList(project.getKey()))
+      .setBranch("master")))
+      .extracting(IssueQuery::branchUuid, query -> new ArrayList<>(query.projectUuids()), IssueQuery::isMainBranch)
+      .containsOnly(project.uuid(), singletonList(project.uuid()), true);
   }
 
   @Test
index f11d9ab4c2bfdb8dc07226c13b296f95d31154f4..23e1fd1b57398bbb4ba538ce32a1fe6f4091cf0a 100644 (file)
@@ -368,10 +368,10 @@ public class IssueIndexTest {
     IssueDoc issueOnAnotherBranch = newDoc(anotherbBranch);
     indexIssues(issueOnProject, issueOnBranch, issueOnAnotherBranch);
 
-    assertThatSearchReturnsOnly(IssueQuery.builder().branchUuid(branch.uuid()), issueOnBranch.key());
-    assertThatSearchReturnsOnly(IssueQuery.builder().componentUuids(singletonList(branch.uuid())).branchUuid(branch.uuid()), issueOnBranch.key());
-    assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(singletonList(project.uuid())).branchUuid(branch.uuid()), issueOnBranch.key());
-    assertThatSearchReturnsOnly(IssueQuery.builder().componentUuids(singletonList(branch.uuid())).projectUuids(singletonList(project.uuid())).branchUuid(branch.uuid()),
+    assertThatSearchReturnsOnly(IssueQuery.builder().branchUuid(branch.uuid()).mainBranch(false), issueOnBranch.key());
+    assertThatSearchReturnsOnly(IssueQuery.builder().componentUuids(singletonList(branch.uuid())).branchUuid(branch.uuid()).mainBranch(false), issueOnBranch.key());
+    assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(singletonList(project.uuid())).branchUuid(branch.uuid()).mainBranch(false), issueOnBranch.key());
+    assertThatSearchReturnsOnly(IssueQuery.builder().componentUuids(singletonList(branch.uuid())).projectUuids(singletonList(project.uuid())).branchUuid(branch.uuid()).mainBranch(false),
       issueOnBranch.key());
     assertThatSearchReturnsEmpty(IssueQuery.builder().branchUuid("unknown"));
   }
@@ -393,10 +393,26 @@ public class IssueIndexTest {
       newDoc("I5", branchModule),
       newDoc("I6", branchFile));
 
-    assertThatSearchReturnsOnly(IssueQuery.builder().branchUuid(branch.uuid()), "I4", "I5", "I6");
-    assertThatSearchReturnsOnly(IssueQuery.builder().moduleUuids(singletonList(branchModule.uuid())).branchUuid(branch.uuid()), "I5", "I6");
-    assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(singletonList(branchFile.uuid())).branchUuid(branch.uuid()), "I6");
-    assertThatSearchReturnsEmpty(IssueQuery.builder().fileUuids(singletonList(branchFile.uuid())).branchUuid("unknown"));
+    assertThatSearchReturnsOnly(IssueQuery.builder().branchUuid(branch.uuid()).mainBranch(false), "I4", "I5", "I6");
+    assertThatSearchReturnsOnly(IssueQuery.builder().moduleUuids(singletonList(branchModule.uuid())).branchUuid(branch.uuid()).mainBranch(false), "I5", "I6");
+    assertThatSearchReturnsOnly(IssueQuery.builder().fileUuids(singletonList(branchFile.uuid())).branchUuid(branch.uuid()).mainBranch(false), "I6");
+    assertThatSearchReturnsEmpty(IssueQuery.builder().fileUuids(singletonList(branchFile.uuid())).mainBranch(false).branchUuid("unknown"));
+  }
+
+  @Test
+  public void issues_from_main_branch() {
+    ComponentDto project = db.components().insertPrivateProject();
+    ComponentDto branch = db.components().insertProjectBranch(project);
+
+    IssueDoc issueOnProject = newDoc(project);
+    IssueDoc issueOnBranch = newDoc(branch);
+    indexIssues(issueOnProject, issueOnBranch);
+
+    assertThatSearchReturnsOnly(IssueQuery.builder().branchUuid(project.uuid()).mainBranch(true), issueOnProject.key());
+    assertThatSearchReturnsOnly(IssueQuery.builder().componentUuids(singletonList(project.uuid())).branchUuid(project.uuid()).mainBranch(true), issueOnProject.key());
+    assertThatSearchReturnsOnly(IssueQuery.builder().projectUuids(singletonList(project.uuid())).branchUuid(project.uuid()).mainBranch(true), issueOnProject.key());
+    assertThatSearchReturnsOnly(IssueQuery.builder().componentUuids(singletonList(project.uuid())).projectUuids(singletonList(project.uuid())).branchUuid(project.uuid()).mainBranch(true),
+      issueOnProject.key());
   }
 
   @Test
@@ -1347,11 +1363,11 @@ public class IssueIndexTest {
     assertThat(underTest.searchBranchStatistics(project.uuid(), singletonList("unknown"))).isEmpty();
   }
 
-  private void addIssues(ComponentDto branch, int bugs, int vulnerabilities, int codeSmelles) {
+  private void addIssues(ComponentDto component, int bugs, int vulnerabilities, int codeSmelles) {
     List<IssueDoc> issues = new ArrayList<>();
-    IntStream.range(0, bugs).forEach(b -> issues.add(newDoc(branch).setType(BUG)));
-    IntStream.range(0, vulnerabilities).forEach(v -> issues.add(newDoc(branch).setType(VULNERABILITY)));
-    IntStream.range(0, codeSmelles).forEach(c -> issues.add(newDoc(branch).setType(CODE_SMELL)));
+    IntStream.range(0, bugs).forEach(b -> issues.add(newDoc(component).setType(BUG)));
+    IntStream.range(0, vulnerabilities).forEach(v -> issues.add(newDoc(component).setType(VULNERABILITY)));
+    IntStream.range(0, codeSmelles).forEach(c -> issues.add(newDoc(component).setType(CODE_SMELL)));
     indexIssues(issues.toArray(new IssueDoc[issues.size()]));
   }
 
index 4654c080ed6bf62b171adc467f31300f6caf0788..8ad91f54f46ef92981bc61870c9ae0e2ae9f3254 100644 (file)
@@ -736,6 +736,31 @@ public class SearchActionComponentsTest {
         tuple(branch.getKey(), branch.getBranch()));
   }
 
+  @Test
+  public void search_using_main_branch_name() {
+    RuleDefinitionDto rule = db.rules().insert();
+    ComponentDto project = db.components().insertMainBranch();
+    userSession.addProjectPermission(UserRole.USER, project);
+    ComponentDto projectFile = db.components().insertComponent(newFileDto(project));
+    IssueDto projectIssue = db.issues().insertIssue(newIssue(rule, project, projectFile));
+    allowAnyoneOnProjects(project);
+    indexIssuesAndViews();
+
+    SearchWsResponse result = ws.newRequest()
+      .setParam(PARAM_COMPONENT_KEYS, project.getKey())
+      .setParam(PARAM_BRANCH, "master")
+      .executeProtobuf(SearchWsResponse.class);
+
+    assertThat(result.getIssuesList())
+      .extracting(Issue::getKey, Issue::getComponent, Issue::hasBranch)
+      .containsExactlyInAnyOrder(tuple(projectIssue.getKey(), projectFile.getKey(), false));
+    assertThat(result.getComponentsList())
+      .extracting(Issues.Component::getKey, Issues.Component::hasBranch)
+      .containsExactlyInAnyOrder(
+        tuple(projectFile.getKey(), false),
+        tuple(project.getKey(), false));
+  }
+
   @Test
   public void does_not_return_branch_issues_on_not_contextualized_search() {
     RuleDefinitionDto rule = db.rules().insert();