]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4400 Issue tag cloud widget handles differential periods
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Wed, 11 Feb 2015 15:04:12 +0000 (16:04 +0100)
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Wed, 11 Feb 2015 15:55:31 +0000 (16:55 +0100)
plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/issues/issue_tag_cloud.html.erb
server/sonar-server/src/main/java/org/sonar/server/issue/ws/ComponentTagsAction.java
server/sonar-server/src/test/java/org/sonar/server/issue/ws/ComponentTagsActionTest.java
server/sonar-web/src/main/coffee/widgets/tag-cloud.coffee

index 9638db45121290d19ff30da39c5c1d275558d21d..99012a289e562144e6796a0e2f6e23c4b8793816 100644 (file)
@@ -3,11 +3,15 @@
   maxItems = widget_properties['maxItems'].to_i
 
   if has_role?(:user, @project) && !Internal.issues.listTagsForComponent(@project.uuid, maxItems).isEmpty()
-    search_options = {}
+    search_options = {
+      'resolved' => 'false'
+    }
     if @project
       search_options['componentUuids'] = @project.uuid
     end
-    search_options['resolved'] = 'false'
+    if @dashboard_configuration.selected_period?
+      search_options['createdAfter'] = @snapshot.period_datetime(@dashboard_configuration.period_index).strftime('%FT%T%z')
+    end
 
     title = message('widget.issue_tag_cloud.title')
 %>
 <!--[if (gte IE 9)|!(IE)]><!-->
 <script>
   (function () {
-    var query = [
+    var createdAfter = '';
+    <% if @dashboard_configuration.selected_period? -%>
+    createdAfter = moment('<%= search_options['createdAfter'] -%>').format('YYYY-MM-DD');
+    <% end -%>
+
+    var queryParams = [
           'componentUuid=<%= @project.uuid() -%>',
-          'ps=<%= maxItems -%>'
-        ].join('&'),
+          'ps=<%= maxItems -%>',
+          'createdAfter=' + createdAfter
+        ],
+        query = queryParams.join('&'),
         widget = new SonarWidgets.Widget();
 
     widget
@@ -36,7 +47,8 @@
       .options({
         maxItemsReachedMessage: '<%= message("widget.measure_filter_histogram.max_items_reached", :params => [maxItems]) -%>',
         baseUrl: baseUrl + '/component_issues/index?id=<%= @project.key -%>#resolved=false',
-        noData: '<%= message('no_data') -%>'
+        noData: '<%= message('no_data') -%>',
+        createdAfter: createdAfter
       })
       .render('#<%= containerId -%>');
 
index 27bd3393c9facaacce78cee96d1b7c0b81b15044..7b634bec3c8d9e5e6bafcfe281c7fb60d30e6be9 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.server.issue.ws;
 
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
 import com.google.common.io.Resources;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
@@ -29,6 +30,7 @@ import org.sonar.api.utils.text.JsonWriter;
 import org.sonar.server.issue.IssueQuery;
 import org.sonar.server.issue.IssueQueryService;
 import org.sonar.server.issue.IssueService;
+import org.sonar.server.issue.filter.IssueFilterParameters;
 
 import java.util.Map;
 
@@ -38,6 +40,9 @@ import java.util.Map;
  */
 public class ComponentTagsAction implements BaseIssuesWsAction {
 
+  private static final String PARAM_COMPONENT_UUID = "componentUuid";
+  private static final String PARAM_CREATED_AT = "createdAfter";
+  private static final String PARAM_PAGE_SIZE = "ps";
   private final IssueService service;
   private final IssueQueryService queryService;
 
@@ -54,11 +59,14 @@ public class ComponentTagsAction implements BaseIssuesWsAction {
       .setInternal(true)
       .setDescription("List tags for the issues under a given component (including issues on the descendants of the component)")
       .setResponseExample(Resources.getResource(getClass(), "example-component-tags.json"));
-    action.createParam("componentUuid")
+    action.createParam(PARAM_COMPONENT_UUID)
       .setDescription("A component UUID")
       .setRequired(true)
       .setExampleValue("7d8749e8-3070-4903-9188-bdd82933bb92");
-    action.createParam("ps")
+    action.createParam(PARAM_CREATED_AT)
+      .setDescription("To retrieve tags on issues created after the given date (inclusive). Format: date or datetime ISO formats")
+      .setExampleValue("2013-05-01 (or 2013-05-01T13:00:00+0100)");
+    action.createParam(PARAM_PAGE_SIZE)
       .setDescription("The maximum size of the list to return")
       .setExampleValue("25")
       .setDefaultValue("10");
@@ -66,12 +74,14 @@ public class ComponentTagsAction implements BaseIssuesWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
-    String componentUuid = request.mandatoryParam("componentUuid");
-    IssueQuery query = queryService.createFromMap(
-      ImmutableMap.<String, Object>of(
-        "componentUuids", componentUuid,
-        "resolved", false));
-    int pageSize = request.mandatoryParamAsInt("ps");
+    Builder<String, Object> paramBuilder = ImmutableMap.<String, Object>builder()
+      .put(IssueFilterParameters.COMPONENT_UUIDS, request.mandatoryParam(PARAM_COMPONENT_UUID))
+      .put(IssueFilterParameters.RESOLVED, false);
+    if (request.hasParam(PARAM_CREATED_AT)) {
+      paramBuilder.put(IssueFilterParameters.CREATED_AFTER, request.param(PARAM_CREATED_AT));
+    }
+    IssueQuery query = queryService.createFromMap(paramBuilder.build());
+    int pageSize = request.mandatoryParamAsInt(PARAM_PAGE_SIZE);
     JsonWriter json = response.newJsonWriter().beginObject().name("tags").beginArray();
     for (Map.Entry<String, Long> tag : service.listTagsForComponent(query, pageSize).entrySet()) {
       json.beginObject()
index 1948a4366905f341586bf2a672d57fd005157aee..fe6472b390cc4a69b5158a9b920f4d61fed55f58 100644 (file)
@@ -67,12 +67,16 @@ public class ComponentTagsActionTest {
     assertThat(action.isPost()).isFalse();
     assertThat(action.isInternal()).isTrue();
     assertThat(action.handler()).isEqualTo(componentTagsAction);
-    assertThat(action.params()).hasSize(2);
+    assertThat(action.params()).hasSize(3);
 
     Param query = action.param("componentUuid");
     assertThat(query.isRequired()).isTrue();
     assertThat(query.description()).isNotEmpty();
     assertThat(query.exampleValue()).isNotEmpty();
+    Param createdAfter = action.param("createdAfter");
+    assertThat(createdAfter.isRequired()).isFalse();
+    assertThat(createdAfter.description()).isNotEmpty();
+    assertThat(createdAfter.exampleValue()).isNotEmpty();
     Param pageSize = action.param("ps");
     assertThat(pageSize.isRequired()).isFalse();
     assertThat(pageSize.defaultValue()).isEqualTo("10");
@@ -98,6 +102,7 @@ public class ComponentTagsActionTest {
     ArgumentCaptor<Map> captor = ArgumentCaptor.forClass(Map.class);
     when(queryService.createFromMap(captor.capture())).thenReturn(query);
     when(service.listTagsForComponent(query, 5)).thenReturn(tags);
+
     tester.newGetRequest("api/issues", "component_tags").setParam("componentUuid", "polop").setParam("ps", "5").execute()
       .assertJson(getClass(), "component-tags.json");
     assertThat(captor.getValue())
@@ -105,4 +110,33 @@ public class ComponentTagsActionTest {
       .containsEntry("resolved", false);
     verify(service).listTagsForComponent(query, 5);
   }
+
+  @Test
+  public void should_return_tag_list_wuth_created_after() throws Exception {
+    Map<String, Long> tags = ImmutableMap.<String, Long>builder()
+      .put("convention", 2771L)
+      .put("brain-overload", 998L)
+      .put("cwe", 89L)
+      .put("bug", 32L)
+      .put("cert", 2L)
+      .build();
+    IssueQuery query = mock(IssueQuery.class);
+    ArgumentCaptor<Map> captor = ArgumentCaptor.forClass(Map.class);
+    when(queryService.createFromMap(captor.capture())).thenReturn(query);
+    when(service.listTagsForComponent(query, 5)).thenReturn(tags);
+
+    String componentUuid = "polop";
+    String createdAfter = "2011-04-25";
+    tester.newGetRequest("api/issues", "component_tags")
+      .setParam("componentUuid", componentUuid)
+      .setParam("createdAfter", createdAfter)
+      .setParam("ps", "5")
+      .execute()
+      .assertJson(getClass(), "component-tags.json");
+    assertThat(captor.getValue())
+      .containsEntry("componentUuids", componentUuid)
+      .containsEntry("resolved", false)
+      .containsEntry("createdAfter", createdAfter);
+    verify(service).listTagsForComponent(query, 5);
+  }
 }
index 12a203df5bfb105ecf4b0a61b2fb2fd2d3f76012..9d522808664c2ede11316e0790f597f1b203a48b 100644 (file)
@@ -19,6 +19,8 @@ class TagCloud extends window.SonarWidgets.BaseWidget
       wordsEnter.text (d) -> d.key
       wordsEnter.attr 'href', (d) =>
         url = @options().baseUrl + '|tags=' + d.key
+        if @options().createdAfter
+          url += '|createdAfter=' + @options().createdAfter
         url
       wordsEnter.attr 'title', (d) => @tooltip d