From 79625d0c9161e02c3c718c546a51538d2221bc4b Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Wed, 14 Sep 2016 18:02:55 +0200 Subject: [PATCH] SONAR-7038 Validate a 400 is sent when WS issues/search cannot parse the date --- .../sonar/server/issue/IssueQueryService.java | 25 ++------ .../issue/ws/SearchActionMediumTest.java | 58 ++++++++++++------- 2 files changed, 41 insertions(+), 42 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java index 610a72699c2..3c81d1246e2 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryService.java @@ -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 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 { private AtomicInteger counter; diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java index ee0a2966afb..713fffce768 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java @@ -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") -- 2.39.5