]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9616 Support branch in api/project_analyses/search
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 3 Aug 2017 14:31:50 +0000 (16:31 +0200)
committerJanos Gyerik <janos.gyerik@sonarsource.com>
Tue, 12 Sep 2017 08:55:10 +0000 (10:55 +0200)
server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchAction.java
server/sonar-server/src/test/java/org/sonar/server/projectanalysis/ws/SearchActionTest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/projectanalysis/ProjectAnalysesWsParameters.java
sonar-ws/src/main/java/org/sonarqube/ws/client/projectanalysis/ProjectAnalysisService.java
sonar-ws/src/main/java/org/sonarqube/ws/client/projectanalysis/SearchRequest.java
sonar-ws/src/test/java/org/sonarqube/ws/client/projectanalysis/ProjectAnalysisServiceTest.java
sonar-ws/src/test/java/org/sonarqube/ws/client/projectanalysis/SearchRequestTest.java

index 3eddef80ffac802e74119ae8a173d52fe08d1732..1b1dc030b0b034b73816f150534a198dd22475d4 100644 (file)
@@ -49,8 +49,10 @@ import static org.sonar.api.utils.DateUtils.parseStartingDateOrDateTime;
 import static org.sonar.core.util.Protobuf.setNullable;
 import static org.sonar.db.component.SnapshotQuery.SORT_FIELD.BY_DATE;
 import static org.sonar.db.component.SnapshotQuery.SORT_ORDER.DESC;
+import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
 import static org.sonarqube.ws.client.projectanalysis.EventCategory.OTHER;
+import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_BRANCH;
 import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_CATEGORY;
 import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_FROM;
 import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_PROJECT;
@@ -86,6 +88,12 @@ public class SearchAction implements ProjectAnalysesWsAction {
       .setRequired(true)
       .setExampleValue(KeyExamples.KEY_PROJECT_EXAMPLE_001);
 
+    action.createParam(PARAM_BRANCH)
+      .setDescription("Branch key")
+      .setSince("6.6")
+      .setInternal(true)
+      .setExampleValue(KEY_BRANCH_EXAMPLE_001);
+
     action.createParam(PARAM_CATEGORY)
       .setDescription("Event category. Filter analyses that have at least one event of the category specified.")
       .setPossibleValues(EnumSet.allOf(EventCategory.class))
@@ -100,6 +108,7 @@ public class SearchAction implements ProjectAnalysesWsAction {
       .setDescription("Filter analyses created before the given date (inclusive). Format: date or datetime ISO formats")
       .setExampleValue("2013-05-01T13:00:00+0100")
       .setSince("6.5");
+
   }
 
   @Override
@@ -113,6 +122,7 @@ public class SearchAction implements ProjectAnalysesWsAction {
     String category = request.param(PARAM_CATEGORY);
     return SearchRequest.builder()
       .setProject(request.mandatoryParam(PARAM_PROJECT))
+      .setBranch(request.param(PARAM_BRANCH))
       .setCategory(category == null ? null : EventCategory.valueOf(category))
       .setPage(request.mandatoryParamAsInt(Param.PAGE))
       .setPageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE))
@@ -152,9 +162,18 @@ public class SearchAction implements ProjectAnalysesWsAction {
   }
 
   private void addProject(SearchData.Builder data) {
-    ComponentDto project = componentFinder.getByKey(data.getDbSession(), data.getRequest().getProject());
+    ComponentDto project = loadComponent(data.getDbSession(), data.getRequest());
     checkArgument(Scopes.PROJECT.equals(project.scope()) && ALLOWED_QUALIFIERS.contains(project.qualifier()), "A project or application is required");
     data.setProject(project);
   }
 
+  private ComponentDto loadComponent(DbSession dbSession, SearchRequest request) {
+    String project = request.getProject();
+    String branch = request.getBranch();
+    if (branch != null) {
+      return componentFinder.getByKeyAndBranch(dbSession, project, branch);
+    }
+    return componentFinder.getByKey(dbSession, project);
+  }
+
 }
index 24bf9f732a70ec00489882ed6d4e208e9fe2819c..c711aec2fa135ce92138604ef5e9f5815f8fd6ec 100644 (file)
@@ -64,6 +64,7 @@ import static org.sonarqube.ws.client.WsRequest.Method.POST;
 import static org.sonarqube.ws.client.projectanalysis.EventCategory.OTHER;
 import static org.sonarqube.ws.client.projectanalysis.EventCategory.QUALITY_GATE;
 import static org.sonarqube.ws.client.projectanalysis.EventCategory.VERSION;
+import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_BRANCH;
 import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_CATEGORY;
 import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_FROM;
 import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_PROJECT;
@@ -110,13 +111,13 @@ public class SearchActionTest {
 
   @Test
   public void return_analyses_ordered_by_analysis_date() {
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert()).setDbKey("P1"));
+    ComponentDto project = db.components().insertPrivateProject();
     userSession.addProjectPermission(UserRole.USER, project);
     db.components().insertSnapshot(newAnalysis(project).setUuid("A1").setCreatedAt(1_000_000L));
     db.components().insertSnapshot(newAnalysis(project).setUuid("A2").setCreatedAt(2_000_000L));
     db.components().insertSnapshot(newAnalysis(project).setUuid("A3").setCreatedAt(3_000_000L));
 
-    List<Analysis> result = call("P1").getAnalysesList();
+    List<Analysis> result = call(project.getKey()).getAnalysesList();
 
     assertThat(result).hasSize(3);
     assertThat(result).extracting(Analysis::getKey, a -> parseDateTime(a.getDate()).getTime()).containsExactly(
@@ -296,7 +297,7 @@ public class SearchActionTest {
     assertThat(result.getAnalysesList())
       .extracting(Analysis::getKey)
       .containsOnly(a2.getUuid(), a3.getUuid())
-    .doesNotContain(a1.getUuid(), a4.getUuid());
+      .doesNotContain(a1.getUuid(), a4.getUuid());
   }
 
   @Test
@@ -321,32 +322,34 @@ public class SearchActionTest {
   }
 
   @Test
-  public void empty_response() {
+  public void branch() {
     ComponentDto project = db.components().insertPrivateProject();
     userSession.addProjectPermission(UserRole.USER, project);
+    ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
+    SnapshotDto analysis = db.components().insertSnapshot(newAnalysis(branch));
+    EventDto event = db.events().insertEvent(newEvent(analysis).setCategory(EventCategory.QUALITY_GATE.getLabel()));
 
-    SearchResponse result = call(project.getDbKey());
+    List<Analysis> result = call(SearchRequest.builder()
+      .setProject(project.getKey())
+      .setBranch("my_branch")
+      .build())
+        .getAnalysesList();
+
+    assertThat(result).extracting(Analysis::getKey).containsExactlyInAnyOrder(analysis.getUuid());
+    assertThat(result.get(0).getEventsList()).extracting(Event::getKey).containsExactlyInAnyOrder(event.getUuid());
 
-    assertThat(result.hasPaging()).isTrue();
-    assertThat(result.getPaging()).extracting(Paging::getPageIndex, Paging::getPageSize, Paging::getTotal).containsExactly(1, 100, 0);
-    assertThat(result.getAnalysesCount()).isEqualTo(0);
   }
 
   @Test
-  public void definition() {
-    WebService.Action definition = ws.getDef();
-
-    assertThat(definition.key()).isEqualTo("search");
-    assertThat(definition.since()).isEqualTo("6.3");
-    assertThat(definition.responseExampleAsString()).isNotEmpty();
-    assertThat(definition.param("project").isRequired()).isTrue();
-    assertThat(definition.param("category")).isNotNull();
+  public void empty_response() {
+    ComponentDto project = db.components().insertPrivateProject();
+    userSession.addProjectPermission(UserRole.USER, project);
 
-    Param from = definition.param("from");
-    assertThat(from.since()).isEqualTo("6.5");
+    SearchResponse result = call(project.getDbKey());
 
-    Param to = definition.param("to");
-    assertThat(to.since()).isEqualTo("6.5");
+    assertThat(result.hasPaging()).isTrue();
+    assertThat(result.getPaging()).extracting(Paging::getPageIndex, Paging::getPageSize, Paging::getTotal).containsExactly(1, 100, 0);
+    assertThat(result.getAnalysesCount()).isEqualTo(0);
   }
 
   @Test
@@ -378,6 +381,44 @@ public class SearchActionTest {
     call(view.getDbKey());
   }
 
+  @Test
+  public void fail_if_branch_does_not_exist() {
+    ComponentDto project = db.components().insertPrivateProject();
+    userSession.addProjectPermission(UserRole.USER, project);
+    db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
+
+    expectedException.expect(NotFoundException.class);
+    expectedException.expectMessage(String.format("Component '%s' on branch '%s' not found", project.getKey(), "another_branch"));
+
+    call(SearchRequest.builder()
+      .setProject(project.getKey())
+      .setBranch("another_branch")
+      .build());
+  }
+
+  @Test
+  public void definition() {
+    WebService.Action definition = ws.getDef();
+
+    assertThat(definition.key()).isEqualTo("search");
+    assertThat(definition.since()).isEqualTo("6.3");
+    assertThat(definition.responseExampleAsString()).isNotEmpty();
+    assertThat(definition.param("project").isRequired()).isTrue();
+    assertThat(definition.param("category")).isNotNull();
+    assertThat(definition.params()).hasSize(7);
+
+    Param from = definition.param("from");
+    assertThat(from.since()).isEqualTo("6.5");
+
+    Param to = definition.param("to");
+    assertThat(to.since()).isEqualTo("6.5");
+
+    Param branch = definition.param("branch");
+    assertThat(branch.since()).isEqualTo("6.6");
+    assertThat(branch.isInternal()).isTrue();
+    assertThat(branch.isRequired()).isFalse();
+  }
+
   private static Function<Event, String> wsToDbCategory() {
     return e -> e == null ? null : EventCategory.valueOf(e.getCategory()).getLabel();
   }
@@ -392,6 +433,7 @@ public class SearchActionTest {
     TestRequest request = ws.newRequest()
       .setMethod(POST.name());
     setNullable(wsRequest.getProject(), project -> request.setParam(PARAM_PROJECT, project));
+    setNullable(wsRequest.getBranch(), branch -> request.setParam(PARAM_BRANCH, branch));
     setNullable(wsRequest.getCategory(), category -> request.setParam(PARAM_CATEGORY, category.name()));
     setNullable(wsRequest.getPage(), page -> request.setParam(Param.PAGE, String.valueOf(page)));
     setNullable(wsRequest.getPageSize(), pageSize -> request.setParam(Param.PAGE_SIZE, String.valueOf(pageSize)));
index 2e7e42e1a0d86794ec168258b8b766f29fd9de5b..3960760509244a8de5acf15df9e709efa970406a 100644 (file)
@@ -27,6 +27,7 @@ public class ProjectAnalysesWsParameters {
   public static final String PARAM_PROJECT = "project";
   public static final String PARAM_FROM = "from";
   public static final String PARAM_TO = "to";
+  public static final String PARAM_BRANCH = "branch";
 
   private ProjectAnalysesWsParameters() {
     // static access only
index 024f5fd0ee75d3f8ff48fd0520b6ade453b35e2c..23cd6034fae0d861a0e662058cc7f5a02cd0ece6 100644 (file)
@@ -26,6 +26,7 @@ import org.sonarqube.ws.client.WsConnector;
 
 import static org.sonar.api.server.ws.WebService.Param.PAGE;
 import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
+import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_BRANCH;
 import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_CATEGORY;
 import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_PROJECT;
 
@@ -39,6 +40,7 @@ public class ProjectAnalysisService extends BaseService {
     EventCategory eventCategory = searchRequest.getCategory();
     GetRequest request = new GetRequest(path("search"))
       .setParam(PARAM_PROJECT, searchRequest.getProject())
+      .setParam(PARAM_BRANCH, searchRequest.getBranch())
       .setParam(PARAM_CATEGORY, eventCategory == null ? null : eventCategory.name())
       .setParam(PAGE, searchRequest.getPage())
       .setParam(PAGE_SIZE, searchRequest.getPageSize());
index c067a12621c659c3b3f44b3165753262e9f9f976..c415d62b6adb900be6b2d2beca57741a044b7826 100644 (file)
@@ -30,6 +30,7 @@ public class SearchRequest {
   public static final int MAX_SIZE = 500;
 
   private final String project;
+  private final String branch;
   private final EventCategory category;
   private final int page;
   private final int pageSize;
@@ -38,6 +39,7 @@ public class SearchRequest {
 
   private SearchRequest(Builder builder) {
     this.project = builder.project;
+    this.branch= builder.branch;
     this.category = builder.category;
     this.page = builder.page;
     this.pageSize = builder.pageSize;
@@ -49,6 +51,11 @@ public class SearchRequest {
     return project;
   }
 
+  @CheckForNull
+  public String getBranch() {
+    return branch;
+  }
+
   @CheckForNull
   public EventCategory getCategory() {
     return category;
@@ -78,6 +85,7 @@ public class SearchRequest {
 
   public static class Builder {
     private String project;
+    private String branch;
     private EventCategory category;
     private int page = 1;
     private int pageSize = DEFAULT_PAGE_SIZE;
@@ -93,6 +101,11 @@ public class SearchRequest {
       return this;
     }
 
+    public Builder setBranch(@Nullable String branch) {
+      this.branch = branch;
+      return this;
+    }
+
     public Builder setCategory(@Nullable EventCategory category) {
       this.category = category;
       return this;
index 5e2d014944e82dd473e493feb74bcd0cbd757b6e..8139bd00434b3766e80ff44bb7314f5e43aec962 100644 (file)
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.mock;
 import static org.sonar.api.server.ws.WebService.Param.PAGE;
 import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
 import static org.sonarqube.ws.client.projectanalysis.EventCategory.QUALITY_GATE;
+import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_BRANCH;
 import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_CATEGORY;
 import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_PROJECT;
 
@@ -45,6 +46,7 @@ public class ProjectAnalysisServiceTest {
   public void search() {
     underTest.search(SearchRequest.builder()
       .setProject("project")
+      .setBranch("my_branch")
       .setCategory(QUALITY_GATE)
       .setPage(10)
       .setPageSize(50)
@@ -54,6 +56,7 @@ public class ProjectAnalysisServiceTest {
     assertThat(serviceTester.getGetParser()).isSameAs(ProjectAnalyses.SearchResponse.parser());
     serviceTester.assertThat(getRequest)
       .hasParam(PARAM_PROJECT, "project")
+      .hasParam(PARAM_BRANCH, "my_branch")
       .hasParam(PARAM_CATEGORY, QUALITY_GATE.name())
       .hasParam(PAGE, 10)
       .hasParam(PAGE_SIZE, 50)
@@ -61,19 +64,17 @@ public class ProjectAnalysisServiceTest {
   }
 
   @Test
-  public void search_without_category() {
+  public void search_with_minimal_fields() {
     underTest.search(SearchRequest.builder()
       .setProject("project")
-      .setPage(10)
-      .setPageSize(50)
       .build());
     GetRequest getRequest = serviceTester.getGetRequest();
 
     assertThat(serviceTester.getGetParser()).isSameAs(ProjectAnalyses.SearchResponse.parser());
     serviceTester.assertThat(getRequest)
       .hasParam(PARAM_PROJECT, "project")
-      .hasParam(PAGE, 10)
-      .hasParam(PAGE_SIZE, 50)
+      .hasParam(PAGE, 1)
+      .hasParam(PAGE_SIZE, 100)
       .andNoOtherParam();
   }
 
index 355fd27e5e852f1d2dca298b66b1cfe6754d310d..4abe04fa8a4c09ee813a5129d4c465a7152fa5fc 100644 (file)
@@ -36,6 +36,7 @@ public class SearchRequestTest {
   public void search_request() {
     SearchRequest result = underTest
       .setProject("P1")
+      .setBranch("my_branch")
       .setCategory(QUALITY_GATE)
       .setPage(2)
       .setPageSize(500)
@@ -44,6 +45,7 @@ public class SearchRequestTest {
       .build();
 
     assertThat(result.getProject()).isEqualTo("P1");
+    assertThat(result.getBranch()).isEqualTo("my_branch");
     assertThat(result.getPage()).isEqualTo(2);
     assertThat(result.getPageSize()).isEqualTo(500);
     assertThat(result.getCategory()).isEqualTo(QUALITY_GATE);