diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2020-12-03 09:37:58 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2020-12-03 20:06:38 +0000 |
commit | 6741d92467d65179e77e910612d91e55b84e660d (patch) | |
tree | 32c8cb53394f16f09609438435ea3062c5fc281e /server/sonar-webserver-es | |
parent | 19c1858b5e72a19332e6a77fd532712e07b47a77 (diff) | |
download | sonarqube-6741d92467d65179e77e910612d91e55b84e660d.tar.gz sonarqube-6741d92467d65179e77e910612d91e55b84e660d.zip |
SONAR-8427 Add a timeZone param to api/issues/search
Diffstat (limited to 'server/sonar-webserver-es')
9 files changed, 158 insertions, 43 deletions
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/component/index/ComponentIndex.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/component/index/ComponentIndex.java index 489e18e758b..886f81583ec 100644 --- a/server/sonar-webserver-es/src/main/java/org/sonar/server/component/index/ComponentIndex.java +++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/component/index/ComponentIndex.java @@ -104,7 +104,7 @@ public class ComponentIndex { SearchRequest request = EsClient.prepareSearch(TYPE_COMPONENT.getMainType()) .source(source); - return new SearchIdResult<>(client.search(request), id -> id, system2.getDefaultTimeZone()); + return new SearchIdResult<>(client.search(request), id -> id, system2.getDefaultTimeZone().toZoneId()); } public ComponentIndexResults searchSuggestions(SuggestionQuery query) { diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java index 1446e48f4ab..0f016ac6c26 100644 --- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java +++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java @@ -809,7 +809,7 @@ public class IssueIndex { .dateHistogramInterval(bucketSize) .minDocCount(0L) .format(DateUtils.DATETIME_FORMAT) - .timeZone(system.getDefaultTimeZone().toZoneId()) + .timeZone(Optional.ofNullable(query.timeZone()).orElse(system.getDefaultTimeZone().toZoneId())) // ES dateHistogram bounds are inclusive while createdBefore parameter is exclusive .extendedBounds(new ExtendedBounds(startInclusive ? startTime : (startTime + 1), endTime - 1L)); addEffortAggregationIfNeeded(query, dateHistogram); diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java index c58511323c8..38eb36bb7af 100644 --- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java +++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java @@ -20,6 +20,7 @@ package org.sonar.server.issue.index; import com.google.common.collect.ImmutableSet; +import java.time.ZoneId; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -96,6 +97,7 @@ public class IssueQuery { private final String organizationUuid; private final String branchUuid; private final boolean mainBranch; + private final ZoneId timeZone; private IssueQuery(Builder builder) { this.issueKeys = defaultCollection(builder.issueKeys); @@ -133,6 +135,7 @@ public class IssueQuery { this.organizationUuid = builder.organizationUuid; this.branchUuid = builder.branchUuid; this.mainBranch = builder.mainBranch; + this.timeZone = builder.timeZone; } public Collection<String> issueKeys() { @@ -294,6 +297,11 @@ public class IssueQuery { return new Builder(); } + @CheckForNull + public ZoneId timeZone() { + return timeZone; + } + public static class Builder { private Collection<String> issueKeys; private Collection<String> severities; @@ -330,6 +338,7 @@ public class IssueQuery { private String organizationUuid; private String branchUuid; private boolean mainBranch = true; + private ZoneId timeZone; private Builder() { @@ -536,6 +545,11 @@ public class IssueQuery { this.mainBranch = mainBranch; return this; } + + public Builder timeZone(ZoneId timeZone) { + this.timeZone = timeZone; + return this; + } } private static <T> Collection<T> defaultCollection(@Nullable Collection<T> c) { diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java index 3e93bf5c4ef..65b79e2c509 100644 --- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java +++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java @@ -23,8 +23,10 @@ import com.google.common.base.Joiner; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import java.time.Clock; +import java.time.DateTimeException; import java.time.OffsetDateTime; import java.time.Period; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -66,7 +68,6 @@ import static org.sonar.api.issue.Issue.STATUSES; import static org.sonar.api.issue.Issue.STATUS_REVIEWED; import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW; 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.core.util.stream.MoreCollectors.toHashSet; @@ -108,6 +109,7 @@ public class IssueQueryFactory { public IssueQuery create(SearchRequest request) { try (DbSession dbSession = dbClient.openSession(false)) { + final ZoneId timeZone = parseTimeZone(request.getTimeZone()).orElse(clock.getZone()); IssueQuery.Builder builder = IssueQuery.builder() .issueKeys(request.getIssues()) .severities(request.getSeverities()) @@ -126,16 +128,17 @@ public class IssueQueryFactory { .cwe(request.getCwe()) .sonarsourceSecurity(request.getSonarsourceSecurity()) .assigned(request.getAssigned()) - .createdAt(parseDateOrDateTime(request.getCreatedAt())) - .createdBefore(parseEndingDateOrDateTime(request.getCreatedBefore())) + .createdAt(parseStartingDateOrDateTime(request.getCreatedAt(), timeZone)) + .createdBefore(parseEndingDateOrDateTime(request.getCreatedBefore(), timeZone)) .facetMode(request.getFacetMode()) - .organizationUuid(convertOrganizationKeyToUuid(dbSession, request.getOrganization())); + .organizationUuid(convertOrganizationKeyToUuid(dbSession, request.getOrganization())) + .timeZone(timeZone); List<ComponentDto> allComponents = new ArrayList<>(); boolean effectiveOnComponentOnly = mergeDeprecatedComponentParameters(dbSession, request, allComponents); addComponentParameters(builder, dbSession, effectiveOnComponentOnly, allComponents, request); - setCreatedAfterFromRequest(dbSession, builder, request, allComponents); + setCreatedAfterFromRequest(dbSession, builder, request, allComponents, timeZone); String sort = request.getSort(); if (!Strings.isNullOrEmpty(sort)) { builder.sort(sort); @@ -145,6 +148,17 @@ public class IssueQueryFactory { } } + private Optional<ZoneId> parseTimeZone(@Nullable String timeZone) { + if (timeZone == null) { + return Optional.empty(); + } + try { + return Optional.of(ZoneId.of(timeZone)); + } catch (DateTimeException e) { + throw new IllegalArgumentException("TimeZone '" + timeZone + "' cannot be parsed as a valid zone ID"); + } + } + private void setCreatedAfterFromDates(IssueQuery.Builder builder, @Nullable Date createdAfter, @Nullable String createdInLast, boolean createdAfterInclusive) { Date actualCreatedAfter = createdAfter; if (createdInLast != null) { @@ -165,8 +179,8 @@ public class IssueQueryFactory { return organization.map(OrganizationDto::getUuid).orElse(UNKNOWN); } - private void setCreatedAfterFromRequest(DbSession dbSession, IssueQuery.Builder builder, SearchRequest request, List<ComponentDto> componentUuids) { - Date createdAfter = parseStartingDateOrDateTime(request.getCreatedAfter()); + private void setCreatedAfterFromRequest(DbSession dbSession, IssueQuery.Builder builder, SearchRequest request, List<ComponentDto> componentUuids, ZoneId timeZone) { + Date createdAfter = parseStartingDateOrDateTime(request.getCreatedAfter(), timeZone); String createdInLast = request.getCreatedInLast(); if (request.getSinceLeakPeriod() == null || !request.getSinceLeakPeriod()) { diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java index 4231f0d42be..bf81c3a02d7 100644 --- a/server/sonar-webserver-es/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java +++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java @@ -226,7 +226,7 @@ public class ProjectMeasuresIndex { filtersComputer.getPostFilters().ifPresent(searchSourceBuilder::postFilter); SearchResponse response = client.search(EsClient.prepareSearch(TYPE_PROJECT_MEASURES.getMainType()) .source(searchSourceBuilder)); - return new SearchIdResult<>(response, id -> id, system2.getDefaultTimeZone()); + return new SearchIdResult<>(response, id -> id, system2.getDefaultTimeZone().toZoneId()); } private static RequestFiltersComputer createFiltersComputer(SearchOptions searchOptions, AllFilters allFilters) { diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java index 74d67113b28..35ed6595a36 100644 --- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java +++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java @@ -197,7 +197,7 @@ public class IssueIndexDebtTest { IssueDocTesting.newDoc("I3", file).setAssigneeUuid("uuid-simon").setEffort(10L), IssueDocTesting.newDoc("I4", file).setAssigneeUuid(null).setEffort(10L)); - Facets facets = new Facets(underTest.search(newQueryBuilder().build(), new SearchOptions().addFacets(asList("assignees"))), system2.getDefaultTimeZone()); + Facets facets = new Facets(underTest.search(newQueryBuilder().build(), new SearchOptions().addFacets(asList("assignees"))), system2.getDefaultTimeZone().toZoneId()); assertThat(facets.getNames()).containsOnly("assignees", FACET_MODE_EFFORT); assertThat(facets.get("assignees")).containsOnly(entry("uuid-steph", 10L), entry("uuid-simon", 20L), entry("", 10L)); assertThat(facets.get(FACET_MODE_EFFORT)).containsOnly(entry("total", 40L)); @@ -214,7 +214,7 @@ public class IssueIndexDebtTest { IssueDocTesting.newDoc("I3", file).setAuthorLogin("simon").setEffort(10L), IssueDocTesting.newDoc("I4", file).setAuthorLogin(null).setEffort(10L)); - Facets facets = new Facets(underTest.search(newQueryBuilder().build(), new SearchOptions().addFacets(asList("authors"))), system2.getDefaultTimeZone()); + Facets facets = new Facets(underTest.search(newQueryBuilder().build(), new SearchOptions().addFacets(asList("authors"))), system2.getDefaultTimeZone().toZoneId()); assertThat(facets.getNames()).containsOnly("authors", FACET_MODE_EFFORT); assertThat(facets.get("authors")).containsOnly(entry("steph", 10L), entry("simon", 20L)); assertThat(facets.get(FACET_MODE_EFFORT)).containsOnly(entry("total", 40L)); @@ -225,7 +225,7 @@ public class IssueIndexDebtTest { SearchOptions searchOptions = fixtureForCreatedAtFacet(); Builder query = newQueryBuilder().createdBefore(parseDateTime("2016-01-01T00:00:00+0100")); - Map<String, Long> createdAt = new Facets(underTest.search(query.build(), searchOptions), system2.getDefaultTimeZone()).get("createdAt"); + Map<String, Long> createdAt = new Facets(underTest.search(query.build(), searchOptions), system2.getDefaultTimeZone().toZoneId()).get("createdAt"); assertThat(createdAt).containsOnly( entry("2011-01-01", 10L), entry("2012-01-01", 0L), @@ -257,7 +257,7 @@ public class IssueIndexDebtTest { } private Facets search(String additionalFacet) { - return new Facets(underTest.search(newQueryBuilder().build(), new SearchOptions().addFacets(singletonList(additionalFacet))), system2.getDefaultTimeZone()); + return new Facets(underTest.search(newQueryBuilder().build(), new SearchOptions().addFacets(singletonList(additionalFacet))), system2.getDefaultTimeZone().toZoneId()); } private Builder newQueryBuilder() { diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java index 11437d42c90..fb9bbaa04eb 100644 --- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java +++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java @@ -19,7 +19,10 @@ */ package org.sonar.server.issue.index; +import java.time.ZoneId; +import java.util.Date; import java.util.Map; +import java.util.TimeZone; import org.elasticsearch.action.search.SearchResponse; import org.junit.Rule; import org.junit.Test; @@ -80,7 +83,8 @@ public class IssueIndexFacetsTest { public UserSessionRule userSessionRule = UserSessionRule.standalone(); @Rule public ExpectedException expectedException = none(); - private System2 system2 = new TestSystem2().setNow(1_500_000_000_000L).setDefaultTimeZone(getTimeZone("GMT-01:00")); + private final TimeZone defaultTimezone = getTimeZone("GMT-01:00"); + private System2 system2 = new TestSystem2().setNow(1_500_000_000_000L).setDefaultTimeZone(defaultTimezone); @Rule public DbTester db = DbTester.create(system2); @@ -431,7 +435,7 @@ public class IssueIndexFacetsTest { } @Test - public void facet_on_created_at_with_less_than_20_days() { + public void facet_on_created_at_with_less_than_20_days_use_system_timezone_by_default() { SearchOptions options = fixtureForCreatedAtFacet(); IssueQuery query = IssueQuery.builder() @@ -439,7 +443,7 @@ public class IssueIndexFacetsTest { .createdBefore(parseDateTime("2014-09-08T00:00:00+0100")) .build(); SearchResponse result = underTest.search(query, options); - Map<String, Long> buckets = new Facets(result, system2.getDefaultTimeZone()).get("createdAt"); + Map<String, Long> buckets = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt"); assertThat(buckets).containsOnly( entry("2014-08-31", 0L), entry("2014-09-01", 2L), @@ -452,6 +456,53 @@ public class IssueIndexFacetsTest { } @Test + public void facet_on_created_at_with_less_than_20_days_use_user_timezone_if_provided() { + // Use timezones very far from each other in order to see some issues moving to a different calendar day + final ZoneId plus14 = ZoneId.of("Pacific/Kiritimati"); + final ZoneId minus11 = ZoneId.of("Pacific/Pago_Pago"); + + + SearchOptions options = fixtureForCreatedAtFacet(); + + final Date startDate = parseDateTime("2014-09-01T00:00:00+0000"); + final Date endDate = parseDateTime("2014-09-08T00:00:00+0000"); + + IssueQuery queryPlus14 = IssueQuery.builder() + .createdAfter(startDate) + .createdBefore(endDate) + .timeZone(plus14) + .build(); + SearchResponse resultPlus14 = underTest.search(queryPlus14, options); + Map<String, Long> bucketsPlus14 = new Facets(resultPlus14, plus14).get("createdAt"); + assertThat(bucketsPlus14).containsOnly( + entry("2014-09-01", 0L), + entry("2014-09-02", 2L), + entry("2014-09-03", 1L), + entry("2014-09-04", 0L), + entry("2014-09-05", 0L), + entry("2014-09-06", 1L), + entry("2014-09-07", 0L), + entry("2014-09-08", 0L)); + + IssueQuery queryMinus11 = IssueQuery.builder() + .createdAfter(startDate) + .createdBefore(endDate) + .timeZone(minus11) + .build(); + SearchResponse resultMinus11 = underTest.search(queryMinus11, options); + Map<String, Long> bucketsMinus11 = new Facets(resultMinus11, minus11).get("createdAt"); + assertThat(bucketsMinus11).containsOnly( + entry("2014-08-31", 1L), + entry("2014-09-01", 1L), + entry("2014-09-02", 1L), + entry("2014-09-03", 0L), + entry("2014-09-04", 0L), + entry("2014-09-05", 1L), + entry("2014-09-06", 0L), + entry("2014-09-07", 0L)); + } + + @Test public void facet_on_created_at_with_less_than_20_weeks() { SearchOptions options = fixtureForCreatedAtFacet(); @@ -459,7 +510,7 @@ public class IssueIndexFacetsTest { .createdAfter(parseDateTime("2014-09-01T00:00:00+0100")) .createdBefore(parseDateTime("2014-09-21T00:00:00+0100")).build(), options); - Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone()).get("createdAt"); + Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt"); assertThat(createdAt).containsOnly( entry("2014-08-25", 0L), entry("2014-09-01", 4L), @@ -475,7 +526,7 @@ public class IssueIndexFacetsTest { .createdAfter(parseDateTime("2014-09-01T00:00:00+0100")) .createdBefore(parseDateTime("2015-01-19T00:00:00+0100")).build(), options); - Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone()).get("createdAt"); + Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt"); assertThat(createdAt).containsOnly( entry("2014-08-01", 0L), entry("2014-09-01", 5L), @@ -493,7 +544,7 @@ public class IssueIndexFacetsTest { .createdAfter(parseDateTime("2011-01-01T00:00:00+0100")) .createdBefore(parseDateTime("2016-01-01T00:00:00+0100")).build(), options); - Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone()).get("createdAt"); + Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt"); assertThat(createdAt).containsOnly( entry("2010-01-01", 0L), entry("2011-01-01", 1L), @@ -511,7 +562,7 @@ public class IssueIndexFacetsTest { .createdAfter(parseDateTime("2014-09-01T00:00:00-0100")) .createdBefore(parseDateTime("2014-09-02T00:00:00-0100")).build(), options); - Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone()).get("createdAt"); + Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt"); assertThat(createdAt).containsOnly( entry("2014-09-01", 2L)); } @@ -524,7 +575,7 @@ public class IssueIndexFacetsTest { .createdAfter(parseDateTime("2009-01-01T00:00:00+0100")) .createdBefore(parseDateTime("2016-01-01T00:00:00+0100")) .build(), options); - Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone()).get("createdAt"); + Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt"); assertThat(createdAt).containsOnly( entry("2008-01-01", 0L), entry("2009-01-01", 0L), @@ -543,7 +594,7 @@ public class IssueIndexFacetsTest { SearchResponse result = underTest.search(IssueQuery.builder() .createdBefore(parseDateTime("2016-01-01T00:00:00+0100")).build(), searchOptions); - Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone()).get("createdAt"); + Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt"); assertThat(createdAt).containsOnly( entry("2011-01-01", 1L), entry("2012-01-01", 0L), @@ -557,7 +608,7 @@ public class IssueIndexFacetsTest { SearchOptions searchOptions = new SearchOptions().addFacets("createdAt"); SearchResponse result = underTest.search(IssueQuery.builder().build(), searchOptions); - Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone()).get("createdAt"); + Map<String, Long> createdAt = new Facets(result, system2.getDefaultTimeZone().toZoneId()).get("createdAt"); assertThat(createdAt).isNull(); } @@ -566,12 +617,12 @@ public class IssueIndexFacetsTest { ComponentDto file = newFileDto(project, null); IssueDoc issue0 = newDoc("ISSUE0", file).setFuncCreationDate(parseDateTime("2011-04-25T00:05:13+0000")); - IssueDoc issue1 = newDoc("I1", file).setFuncCreationDate(parseDateTime("2014-09-01T12:34:56+0100")); - IssueDoc issue2 = newDoc("I2", file).setFuncCreationDate(parseDateTime("2014-09-01T10:46:00-1200")); - IssueDoc issue3 = newDoc("I3", file).setFuncCreationDate(parseDateTime("2014-09-02T23:34:56+1200")); - IssueDoc issue4 = newDoc("I4", file).setFuncCreationDate(parseDateTime("2014-09-05T12:34:56+0100")); - IssueDoc issue5 = newDoc("I5", file).setFuncCreationDate(parseDateTime("2014-09-20T12:34:56+0100")); - IssueDoc issue6 = newDoc("I6", file).setFuncCreationDate(parseDateTime("2015-01-18T12:34:56+0100")); + IssueDoc issue1 = newDoc("I1", file).setFuncCreationDate(parseDateTime("2014-09-01T10:34:56+0000")); + IssueDoc issue2 = newDoc("I2", file).setFuncCreationDate(parseDateTime("2014-09-01T22:46:00+0000")); + IssueDoc issue3 = newDoc("I3", file).setFuncCreationDate(parseDateTime("2014-09-02T11:34:56+0000")); + IssueDoc issue4 = newDoc("I4", file).setFuncCreationDate(parseDateTime("2014-09-05T11:34:56+0000")); + IssueDoc issue5 = newDoc("I5", file).setFuncCreationDate(parseDateTime("2014-09-20T11:34:56+0000")); + IssueDoc issue6 = newDoc("I6", file).setFuncCreationDate(parseDateTime("2015-01-18T11:34:56+0000")); indexIssues(issue0, issue1, issue2, issue3, issue4, issue5, issue6); @@ -586,7 +637,7 @@ public class IssueIndexFacetsTest { @SafeVarargs private final void assertThatFacetHasExactly(IssueQuery.Builder query, String facet, Map.Entry<String, Long>... expectedEntries) { SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(singletonList(facet))); - Facets facets = new Facets(result, system2.getDefaultTimeZone()); + Facets facets = new Facets(result, system2.getDefaultTimeZone().toZoneId()); assertThat(facets.getNames()).containsOnly(facet, "effort"); assertThat(facets.get(facet)).containsExactly(expectedEntries); } @@ -594,14 +645,14 @@ public class IssueIndexFacetsTest { @SafeVarargs private final void assertThatFacetHasOnly(IssueQuery.Builder query, String facet, Map.Entry<String, Long>... expectedEntries) { SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(singletonList(facet))); - Facets facets = new Facets(result, system2.getDefaultTimeZone()); + Facets facets = new Facets(result, system2.getDefaultTimeZone().toZoneId()); assertThat(facets.getNames()).containsOnly(facet, "effort"); assertThat(facets.get(facet)).containsOnly(expectedEntries); } private void assertThatFacetHasSize(IssueQuery issueQuery, String facet, int expectedSize) { SearchResponse result = underTest.search(issueQuery, new SearchOptions().addFacets(singletonList(facet))); - Facets facets = new Facets(result, system2.getDefaultTimeZone()); + Facets facets = new Facets(result, system2.getDefaultTimeZone().toZoneId()); assertThat(facets.get(facet)).hasSize(expectedSize); } } diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityHotspotsTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityHotspotsTest.java index 054986e98fe..cb5e38dcd29 100644 --- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityHotspotsTest.java +++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityHotspotsTest.java @@ -142,7 +142,7 @@ public class IssueIndexSecurityHotspotsTest { @SafeVarargs private final void assertThatFacetHasOnly(IssueQuery.Builder query, String facet, Map.Entry<String, Long>... expectedEntries) { SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(singletonList(facet))); - Facets facets = new Facets(result, system2.getDefaultTimeZone()); + Facets facets = new Facets(result, system2.getDefaultTimeZone().toZoneId()); assertThat(facets.getNames()).containsOnly(facet, "effort"); assertThat(facets.get(facet)).containsOnly(expectedEntries); } diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java index 0ebb3805a41..d73c46b97ef 100644 --- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java +++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java @@ -20,6 +20,7 @@ package org.sonar.server.issue.index; import java.time.Clock; +import java.time.ZoneId; import java.time.ZoneOffset; import java.util.ArrayList; import java.util.Collections; @@ -30,7 +31,6 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.resources.Qualifiers; import org.sonar.api.rule.RuleKey; -import org.sonar.api.utils.DateUtils; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.SnapshotDto; @@ -50,6 +50,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.sonar.api.resources.Qualifiers.APP; import static org.sonar.api.utils.DateUtils.addDays; +import static org.sonar.api.utils.DateUtils.parseDateTime; import static org.sonar.api.web.UserRole.USER; import static org.sonar.db.component.ComponentTesting.newDirectory; import static org.sonar.db.component.ComponentTesting.newFileDto; @@ -123,9 +124,9 @@ public class IssueQueryFactoryTest { assertThat(query.assigned()).isTrue(); assertThat(query.rules()).hasSize(2); assertThat(query.directories()).containsOnly("aDirPath"); - assertThat(query.createdAfter().date()).isEqualTo(DateUtils.parseDateTime("2013-04-16T09:08:24+0200")); + assertThat(query.createdAfter().date()).isEqualTo(parseDateTime("2013-04-16T09:08:24+0200")); assertThat(query.createdAfter().inclusive()).isTrue(); - assertThat(query.createdBefore()).isEqualTo(DateUtils.parseDateTime("2013-04-17T09:08:24+0200")); + assertThat(query.createdBefore()).isEqualTo(parseDateTime("2013-04-17T09:08:24+0200")); assertThat(query.sort()).isEqualTo(IssueQuery.SORT_BY_CREATION_DATE); assertThat(query.asc()).isTrue(); } @@ -154,25 +155,49 @@ public class IssueQueryFactoryTest { @Test public void dates_are_inclusive() { + when(clock.getZone()).thenReturn(ZoneId.of("Europe/Paris")); SearchRequest request = new SearchRequest() .setCreatedAfter("2013-04-16") .setCreatedBefore("2013-04-17"); IssueQuery query = underTest.create(request); - assertThat(query.createdAfter().date()).isEqualTo(DateUtils.parseDate("2013-04-16")); + assertThat(query.createdAfter().date()).isEqualTo(parseDateTime("2013-04-16T00:00:00+0200")); assertThat(query.createdAfter().inclusive()).isTrue(); - assertThat(query.createdBefore()).isEqualTo(DateUtils.parseDate("2013-04-18")); + assertThat(query.createdBefore()).isEqualTo(parseDateTime("2013-04-18T00:00:00+0200")); } @Test public void creation_date_support_localdate() { + when(clock.getZone()).thenReturn(ZoneId.of("Europe/Paris")); SearchRequest request = new SearchRequest() .setCreatedAt("2013-04-16"); IssueQuery query = underTest.create(request); - assertThat(query.createdAt()).isEqualTo(DateUtils.parseDate("2013-04-16")); + assertThat(query.createdAt()).isEqualTo(parseDateTime("2013-04-16T00:00:00+0200")); + } + + @Test + public void use_provided_timezone_to_parse_createdAfter() { + SearchRequest request = new SearchRequest() + .setCreatedAfter("2020-04-16") + .setTimeZone("Europe/Volgograd"); + + IssueQuery query = underTest.create(request); + + assertThat(query.createdAfter().date()).isEqualTo(parseDateTime("2020-04-16T00:00:00+0400")); + } + + @Test + public void use_provided_timezone_to_parse_createdBefore() { + SearchRequest request = new SearchRequest() + .setCreatedBefore("2020-04-16") + .setTimeZone("Europe/Moscow"); + + IssueQuery query = underTest.create(request); + + assertThat(query.createdBefore()).isEqualTo(parseDateTime("2020-04-17T00:00:00+0300")); } @Test @@ -182,7 +207,7 @@ public class IssueQueryFactoryTest { IssueQuery query = underTest.create(request); - assertThat(query.createdAt()).isEqualTo(DateUtils.parseDateTime("2013-04-16T09:08:24+0200")); + assertThat(query.createdAt()).isEqualTo(parseDateTime("2013-04-16T09:08:24+0200")); } @Test @@ -225,6 +250,17 @@ public class IssueQueryFactoryTest { } @Test + public void fail_if_invalid_timezone() { + SearchRequest request = new SearchRequest() + .setTimeZone("Poitou-Charentes"); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("TimeZone 'Poitou-Charentes' cannot be parsed as a valid zone ID"); + + underTest.create(request); + } + + @Test public void param_componentUuids_enables_search_in_view_tree_if_user_has_permission_on_view() { ComponentDto view = db.components().insertView(); SearchRequest request = new SearchRequest() @@ -499,12 +535,12 @@ public class IssueQueryFactoryTest { @Test public void set_created_after_from_created_since() { - Date now = DateUtils.parseDateTime("2013-07-25T07:35:00+0100"); + Date now = parseDateTime("2013-07-25T07:35:00+0100"); when(clock.instant()).thenReturn(now.toInstant()); when(clock.getZone()).thenReturn(ZoneOffset.UTC); SearchRequest request = new SearchRequest() .setCreatedInLast("1y2m3w4d"); - assertThat(underTest.create(request).createdAfter().date()).isEqualTo(DateUtils.parseDateTime("2012-04-30T07:35:00+0100")); + assertThat(underTest.create(request).createdAfter().date()).isEqualTo(parseDateTime("2012-04-30T07:35:00+0100")); assertThat(underTest.create(request).createdAfter().inclusive()).isTrue(); } |