]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7038 Validate a 400 is sent when WS issues/search cannot parse the date
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Wed, 14 Sep 2016 16:02:55 +0000 (18:02 +0200)
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Fri, 16 Sep 2016 08:28:08 +0000 (10:28 +0200)
server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java
server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java

index 610a72699c2370b91e26dee101311ac04bdfc3cf..3c81d1246e2cbc7df625af52f87fc4f7fe75e2c4 100644 (file)
@@ -49,8 +49,6 @@ import org.sonar.api.ce.ComputeEngineSide;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.server.ServerSide;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.api.utils.SonarException;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
@@ -70,7 +68,9 @@ import static com.google.common.collect.FluentIterable.from;
 import static com.google.common.collect.Lists.newArrayList;
 import static java.lang.String.format;
 import static org.sonar.api.utils.DateUtils.longToDate;
+import static org.sonar.api.utils.DateUtils.parseDateOrDateTime;
 import static org.sonar.api.utils.DateUtils.parseEndingDateOrDateTime;
+import static org.sonar.api.utils.DateUtils.parseStartingDateOrDateTime;
 import static org.sonar.db.component.ComponentDtoFunctions.toProjectUuid;
 import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
 import static org.sonar.server.ws.WsUtils.checkRequest;
@@ -193,7 +193,7 @@ public class IssueQueryService {
         .tags(request.getTags())
         .types(request.getTypes())
         .assigned(request.getAssigned())
-        .createdAt(parseAsDateTime(request.getCreatedAt()))
+        .createdAt(parseDateOrDateTime(request.getCreatedAt()))
         .createdBefore(parseEndingDateOrDateTime(request.getCreatedBefore()))
         .facetMode(request.getFacetMode());
 
@@ -232,7 +232,7 @@ public class IssueQueryService {
   }
 
   private Date buildCreatedAfterFromRequest(DbSession dbSession, SearchWsRequest request, Set<String> componentUuids) {
-    Date createdAfter = parseAsDateTime(request.getCreatedAfter());
+    Date createdAfter = parseStartingDateOrDateTime(request.getCreatedAfter());
     String createdInLast = request.getCreatedInLast();
 
     if (request.getSinceLeakPeriod() == null || !request.getSinceLeakPeriod()) {
@@ -457,23 +457,6 @@ public class IssueQueryService {
     return null;
   }
 
-  @CheckForNull
-  private static Date parseAsDateTime(@Nullable String stringDate) {
-    if (stringDate == null) {
-      return null;
-    }
-
-    try {
-      return DateUtils.parseDateTime(stringDate);
-    } catch (SonarException notDateTime) {
-      try {
-        return DateUtils.parseDate(stringDate);
-      } catch (SonarException notDateEither) {
-        throw new IllegalArgumentException(String.format("'%s' cannot be parsed as either a date or date+time", stringDate));
-      }
-    }
-  }
-
   private static class HasTwoOrMoreElements implements Predicate<Object> {
     private AtomicInteger counter;
 
index ee0a2966afb6e0872b3fe1162cfbb57ef75cd777..713fffce7688fe764d8dd87a842b30154e8f8eab 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 import org.sonar.api.issue.Issue;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.security.DefaultGroups;
@@ -55,8 +56,11 @@ import org.sonar.server.ws.WsTester;
 
 import static java.util.Arrays.asList;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.issue.ws.IssuesWs.API_ENDPOINT;
+import static org.sonar.server.issue.ws.SearchAction.SEARCH_ACTION;
 import static org.sonarqube.ws.client.issue.IssueFilterParameters.ADDITIONAL_FIELDS;
 import static org.sonarqube.ws.client.issue.IssueFilterParameters.COMPONENTS;
+import static org.sonarqube.ws.client.issue.IssueFilterParameters.CREATED_AFTER;
 import static org.sonarqube.ws.client.issue.IssueFilterParameters.DEPRECATED_FACET_MODE_DEBT;
 import static org.sonarqube.ws.client.issue.IssueFilterParameters.FACET_MODE_EFFORT;
 import static org.sonarqube.ws.client.issue.IssueFilterParameters.HIDE_COMMENTS;
@@ -70,6 +74,8 @@ public class SearchActionMediumTest {
 
   @Rule
   public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester);
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
 
   DbClient db;
   DbSession session;
@@ -104,7 +110,7 @@ public class SearchActionMediumTest {
 
   @Test
   public void empty_search() throws Exception {
-    WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
+    WsTester.TestRequest request = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION);
     WsTester.Result result = request.execute();
 
     assertThat(result).isNotNull();
@@ -135,7 +141,7 @@ public class SearchActionMediumTest {
     session.commit();
     tester.get(IssueIndexer.class).indexAll();
 
-    WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute();
+    WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION).execute();
     result.assertJson(this.getClass(), "response_contains_all_fields_except_additional_fields.json");
   }
 
@@ -169,7 +175,7 @@ public class SearchActionMediumTest {
     tester.get(IssueIndexer.class).indexAll();
 
     userSessionRule.login("john");
-    WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
+    WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION)
       .setParam("additionalFields", "comments,users")
       .execute();
     result.assertJson(this.getClass(), "issue_with_comments.json");
@@ -205,7 +211,7 @@ public class SearchActionMediumTest {
     tester.get(IssueIndexer.class).indexAll();
 
     userSessionRule.login("john");
-    WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).setParam(HIDE_COMMENTS, "true").execute();
+    WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION).setParam(HIDE_COMMENTS, "true").execute();
     result.assertJson(this.getClass(), "issue_with_comment_hidden.json");
     assertThat(result.outputAsString()).doesNotContain("fabrice");
   }
@@ -227,7 +233,7 @@ public class SearchActionMediumTest {
     tester.get(IssueIndexer.class).indexAll();
 
     userSessionRule.login("john");
-    WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
+    WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION)
       .setParam("additionalFields", "_all").execute();
     result.assertJson(this.getClass(), "load_additional_fields.json");
   }
@@ -252,7 +258,7 @@ public class SearchActionMediumTest {
     session.commit();
     tester.get(IssueIndexer.class).indexAll();
 
-    WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
+    WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION)
       .execute();
     result.assertJson(this.getClass(), "issue_on_removed_file.json");
   }
@@ -267,7 +273,7 @@ public class SearchActionMediumTest {
     session.commit();
     tester.get(IssueIndexer.class).indexAll();
 
-    WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute();
+    WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION).execute();
     assertThat(result.outputAsString()).contains("\"componentId\":" + file.getId() + ",");
   }
 
@@ -284,7 +290,7 @@ public class SearchActionMediumTest {
     session.commit();
     tester.get(IssueIndexer.class).indexAll();
 
-    WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).setParam(COMPONENTS, file.getKey()).execute();
+    WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION).setParam(COMPONENTS, file.getKey()).execute();
     result.assertJson(this.getClass(), "apply_paging_with_one_component.json");
   }
 
@@ -299,7 +305,7 @@ public class SearchActionMediumTest {
     session.commit();
     tester.get(IssueIndexer.class).indexAll();
 
-    WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).setParam(ADDITIONAL_FIELDS, "_all").execute();
+    WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION).setParam(ADDITIONAL_FIELDS, "_all").execute();
     result.assertJson(this.getClass(), "components_contains_sub_projects.json");
   }
 
@@ -320,7 +326,7 @@ public class SearchActionMediumTest {
     tester.get(IssueIndexer.class).indexAll();
 
     userSessionRule.login("john");
-    WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
+    WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION)
       .setParam("resolved", "false")
       .setParam(WebService.Param.FACETS, "statuses,severities,resolutions,projectUuids,rules,fileUuids,assignees,languages,actionPlans,types")
       .execute();
@@ -344,7 +350,7 @@ public class SearchActionMediumTest {
     tester.get(IssueIndexer.class).indexAll();
 
     userSessionRule.login("john");
-    WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
+    WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION)
       .setParam("resolved", "false")
       .setParam(WebService.Param.FACETS, "statuses,severities,resolutions,projectUuids,rules,fileUuids,assignees,languages,actionPlans")
       .setParam("facetMode", FACET_MODE_EFFORT)
@@ -369,7 +375,7 @@ public class SearchActionMediumTest {
     tester.get(IssueIndexer.class).indexAll();
 
     userSessionRule.login("john");
-    WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
+    WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION)
       .setParam("resolved", "false")
       .setParam("severities", "MAJOR,MINOR")
       .setParam("languages", "xoo,polop,palap")
@@ -414,7 +420,7 @@ public class SearchActionMediumTest {
     tester.get(IssueIndexer.class).indexAll();
 
     userSessionRule.login("john");
-    wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
+    wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION)
       .setParam("resolved", "false")
       .setParam("assignees", "__me__")
       .setParam(WebService.Param.FACETS, "assignees,assigned_to_me")
@@ -445,7 +451,7 @@ public class SearchActionMediumTest {
     session.commit();
     tester.get(IssueIndexer.class).indexAll();
 
-    wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
+    wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION)
       .setParam("resolved", "false")
       .setParam("assignees", "__me__")
       .execute()
@@ -488,7 +494,7 @@ public class SearchActionMediumTest {
     tester.get(IssueIndexer.class).indexAll();
 
     userSessionRule.login("john-bob.polop");
-    wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
+    wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION)
       .setParam("resolved", "false")
       .setParam("assignees", "alice")
       .setParam(WebService.Param.FACETS, "assignees,assigned_to_me")
@@ -514,7 +520,7 @@ public class SearchActionMediumTest {
     session.commit();
     tester.get(IssueIndexer.class).indexAll();
 
-    WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
+    WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION)
       .setParam("sort", IssueQuery.SORT_BY_UPDATE_DATE)
       .setParam("asc", "false")
       .execute();
@@ -534,7 +540,7 @@ public class SearchActionMediumTest {
     session.commit();
     tester.get(IssueIndexer.class).indexAll();
 
-    WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
+    WsTester.TestRequest request = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION);
     request.setParam(WebService.Param.PAGE, "2");
     request.setParam(WebService.Param.PAGE_SIZE, "9");
 
@@ -555,7 +561,7 @@ public class SearchActionMediumTest {
     session.commit();
     tester.get(IssueIndexer.class).indexAll();
 
-    WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
+    WsTester.TestRequest request = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION);
     request.setParam(WebService.Param.PAGE, "1");
     request.setParam(WebService.Param.PAGE_SIZE, "-1");
 
@@ -576,7 +582,7 @@ public class SearchActionMediumTest {
     session.commit();
     tester.get(IssueIndexer.class).indexAll();
 
-    WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
+    WsTester.TestRequest request = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION);
     request.setParam(PAGE_INDEX, "2");
     request.setParam(PAGE_SIZE, "9");
 
@@ -586,7 +592,7 @@ public class SearchActionMediumTest {
 
   @Test
   public void default_page_size_is_100() throws Exception {
-    WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
+    WsTester.TestRequest request = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION);
 
     WsTester.Result result = request.execute();
     result.assertJson(this.getClass(), "default_page_size_is_100.json");
@@ -609,7 +615,7 @@ public class SearchActionMediumTest {
     tester.get(IssueIndexer.class).indexAll();
 
     userSessionRule.login("john");
-    WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
+    WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION)
       .setParam("resolved", "false")
       .setParam(WebService.Param.FACETS, "severities")
       .setParam("facetMode", DEPRECATED_FACET_MODE_DEBT)
@@ -617,6 +623,16 @@ public class SearchActionMediumTest {
     result.assertJson(this.getClass(), "display_deprecated_debt_fields.json");
   }
 
+  @Test
+  public void fail_when_invalid_format() throws Exception {
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage("Date 'wrong-date-input' cannot be parsed as either a date or date+time");
+
+    wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION)
+      .setParam(CREATED_AFTER, "wrong-date-input")
+      .execute();
+  }
+
   private RuleDto newRule() {
     RuleDto rule = RuleTesting.newXooX1()
       .setName("Rule name")