001/*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 *     http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014package org.gbif.api.jackson;
015
016import org.gbif.api.util.IsoDateInterval;
017
018import java.io.IOException;
019import java.time.LocalDate;
020import java.time.LocalDateTime;
021import java.time.OffsetDateTime;
022import java.time.Year;
023import java.time.YearMonth;
024import java.time.ZoneOffset;
025import java.time.temporal.Temporal;
026
027import org.junit.jupiter.api.Test;
028
029import com.fasterxml.jackson.databind.ObjectMapper;
030import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
031import com.fasterxml.jackson.databind.annotation.JsonSerialize;
032
033import static org.junit.jupiter.api.Assertions.assertEquals;
034import static org.junit.jupiter.api.Assertions.assertNull;
035
036/**
037 * Test {@link IsoDateInterval} serialization using DateRangeSerde.
038 */
039public class IsoDateIntervalDeserTest {
040
041  private static final ObjectMapper MAPPER = new ObjectMapper();
042
043  @Test
044  public void testBothWays() throws IOException {
045    // Implicit ranges
046    test(OffsetDateTime.of(2009, 2, 4, 5, 6, 7, 789_000_000, ZoneOffset.UTC), null, "2009-02-04T05:06:07.789Z");
047    test(OffsetDateTime.of(2009, 2, 4, 5, 6, 7, 789_000_000, ZoneOffset.ofHours(5)), null, "2009-02-04T05:06:07.789+05:00");
048    test(LocalDateTime.of(2009, 2, 4, 5, 6, 7, 789_000_000), null, "2009-02-04T05:06:07.789");
049    test(OffsetDateTime.of(2009, 2, 4, 5, 6, 7, 0, ZoneOffset.UTC), null, "2009-02-04T05:06:07Z");
050    test(OffsetDateTime.of(2009, 2, 4, 5, 6, 7, 0, ZoneOffset.ofHours(5)), null, "2009-02-04T05:06:07+05:00");
051    test(LocalDateTime.of(2009, 2, 4, 5, 6, 7, 0), null, "2009-02-04T05:06:07");
052    test(OffsetDateTime.of(2009, 2, 4, 5, 6, 0, 0, ZoneOffset.UTC), null, "2009-02-04T05:06Z");
053    test(OffsetDateTime.of(2009, 2, 4, 5, 6, 0, 0, ZoneOffset.ofHours(5)), null, "2009-02-04T05:06+05:00");
054    test(LocalDateTime.of(2009, 2, 4, 5, 6), null, "2009-02-04T05:06");
055    test(LocalDate.of(2009, 2, 4), null, "2009-02-04");
056    test(YearMonth.of(2009, 2), null, "2009-02");
057    test(Year.of(2009), null, "2009");
058
059    // Implicit ranges to simplify
060    test(OffsetDateTime.of(2009, 2, 4, 5, 6, 7, 0, ZoneOffset.UTC), OffsetDateTime.of(2009, 2, 4, 5, 6, 7, 0, ZoneOffset.UTC), "2009-02-04T05:06:07Z");
061    test(OffsetDateTime.of(2009, 2, 4, 5, 6, 7, 0, ZoneOffset.ofHours(5)), OffsetDateTime.of(2009, 2, 4, 5, 6, 7, 0, ZoneOffset.ofHours(5)), "2009-02-04T05:06:07+05:00");
062    test(LocalDateTime.of(2009, 2, 4, 5, 6, 7, 0), LocalDateTime.of(2009, 2, 4, 5, 6, 7, 0), "2009-02-04T05:06:07");
063    test(OffsetDateTime.of(2009, 2, 4, 5, 6, 0, 0, ZoneOffset.UTC), OffsetDateTime.of(2009, 2, 4, 5, 6, 0, 0, ZoneOffset.UTC), "2009-02-04T05:06Z");
064    test(OffsetDateTime.of(2009, 2, 4, 5, 6, 0, 0, ZoneOffset.ofHours(5)), OffsetDateTime.of(2009, 2, 4, 5, 6, 0, 0, ZoneOffset.ofHours(5)), "2009-02-04T05:06+05:00");
065    test(LocalDateTime.of(2009, 2, 4, 5, 6), LocalDateTime.of(2009, 2, 4, 5, 6), "2009-02-04T05:06");
066    test(LocalDate.of(2009, 2, 4), LocalDate.of(2009, 2, 4), "2009-02-04");
067    test(YearMonth.of(2009, 2), YearMonth.of(2009, 2), "2009-02");
068    test(Year.of(2009), Year.of(2009), "2009");
069
070    // Explicit ranges
071    test(OffsetDateTime.of(2009, 2, 4, 5, 6, 7, 0, ZoneOffset.UTC), OffsetDateTime.of(2009, 2, 14, 15, 16, 17, 0, ZoneOffset.UTC), "2009-02-04T05:06:07Z/2009-02-14T15:16:17Z");
072    test(OffsetDateTime.of(2009, 2, 4, 5, 6, 7, 0, ZoneOffset.ofHours(5)), OffsetDateTime.of(2009, 2, 14, 15, 16, 17, 0, ZoneOffset.ofHours(5)), "2009-02-04T05:06:07+05:00/2009-02-14T15:16:17+05:00");
073    test(LocalDateTime.of(2009, 2, 4, 5, 6, 7, 0), LocalDateTime.of(2009, 2, 14, 15, 16, 17, 0), "2009-02-04T05:06:07/2009-02-14T15:16:17");
074    test(OffsetDateTime.of(2009, 2, 4, 5, 6, 0, 0, ZoneOffset.UTC), OffsetDateTime.of(2009, 2, 14, 15, 16, 0, 0, ZoneOffset.UTC), "2009-02-04T05:06Z/2009-02-14T15:16Z");
075    test(OffsetDateTime.of(2009, 2, 4, 5, 6, 0, 0, ZoneOffset.ofHours(5)), OffsetDateTime.of(2009, 2, 14, 15, 16, 0, 0, ZoneOffset.ofHours(5)), "2009-02-04T05:06+05:00/2009-02-14T15:16+05:00");
076    test(LocalDateTime.of(2009, 2, 4, 5, 6), LocalDateTime.of(2009, 2, 14, 15, 16), "2009-02-04T05:06/2009-02-14T15:16");
077    test(LocalDate.of(2023, 1, 13), LocalDate.of(2023, 1, 14), "2023-01-13/2023-01-14");
078    test(YearMonth.of(2009, 2), YearMonth.of(2009, 4), "2009-02/2009-04");
079    test(Year.of(2009), Year.of(2010), "2009/2010");
080  }
081
082  private void test(Temporal from, Temporal to, String expectedJson) throws IOException {
083    IsoDateInterval isoDateInterval = new IsoDateInterval(from, to);
084    DateRangeWrapper drw = new DateRangeWrapper(isoDateInterval);
085    String json = MAPPER.writeValueAsString(drw);
086    assertEquals("{\"isoDateInterval\":\"" + expectedJson + "\"}", json);
087    assertEquals(from, MAPPER.readValue(json, DateRangeWrapper.class).isoDateInterval.getFrom());
088    if (from.equals(to)) {
089      assertNull(MAPPER.readValue(json, DateRangeWrapper.class).isoDateInterval.getTo());
090    } else {
091      assertEquals(to, MAPPER.readValue(json, DateRangeWrapper.class).isoDateInterval.getTo());
092    }
093  }
094
095  public static class DateRangeWrapper {
096    @JsonSerialize(using = IsoDateIntervalSerde.IsoDateIntervalSerializer.class)
097    @JsonDeserialize(using = IsoDateIntervalSerde.IsoDateIntervalDeserializer.class)
098    public IsoDateInterval isoDateInterval;
099
100    public DateRangeWrapper() {}
101
102    public DateRangeWrapper(IsoDateInterval isoDateInterval){
103      this.isoDateInterval = isoDateInterval;
104    }
105  }
106}