diff --git a/src/main/java/io/redlink/more/data/repository/StudyRepository.java b/src/main/java/io/redlink/more/data/repository/StudyRepository.java index 90d6acb..07410cb 100644 --- a/src/main/java/io/redlink/more/data/repository/StudyRepository.java +++ b/src/main/java/io/redlink/more/data/repository/StudyRepository.java @@ -2,22 +2,13 @@ * Copyright (c) 2022 Redlink GmbH. */ package io.redlink.more.data.repository; -import org.apache.commons.lang3.tuple.Pair; -import io.redlink.more.data.model.*; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.time.Instant; -import java.util.List; -import java.util.Optional; -import java.util.OptionalInt; -import java.util.function.Supplier; +import io.redlink.more.data.model.*; import io.redlink.more.data.model.scheduler.Interval; import io.redlink.more.data.model.scheduler.RelativeEvent; import io.redlink.more.data.model.scheduler.ScheduleEvent; import io.redlink.more.data.schedule.SchedulerUtils; +import org.apache.commons.lang3.tuple.Pair; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; @@ -27,6 +18,15 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import java.util.OptionalInt; +import java.util.function.Supplier; + import static io.redlink.more.data.repository.DbUtils.toInstant; import static io.redlink.more.data.repository.DbUtils.toLocalDate; @@ -67,41 +67,41 @@ INNER JOIN studies s on (s.study_id = pt.study_id) private static final String SQL_INSERT_CREDENTIALS = "WITH data as (SELECT :api_secret as api_secret, :study_id as study_id, :participant_id as participant_id) " + - "INSERT INTO api_credentials (api_id, api_secret, study_id, participant_id) " + - "SELECT md5(study_id::text || random()::text), api_secret, study_id, participant_id FROM data " + - "RETURNING api_id"; + "INSERT INTO api_credentials (api_id, api_secret, study_id, participant_id) " + + "SELECT md5(study_id::text || random()::text), api_secret, study_id, participant_id FROM data " + + "RETURNING api_id"; private static final String SQL_CLEAR_CREDENTIALS = "DELETE FROM api_credentials " + - "WHERE api_id = :api_id " + - "RETURNING study_id, participant_id"; + "WHERE api_id = :api_id " + + "RETURNING study_id, participant_id"; private static final String SQL_INSERT_STUDY_CONSENT = "INSERT INTO participation_consents(study_id, participant_id, accepted, origin, content_md5) VALUES (:study_id, :participant_id, :accepted, :origin, :content_md5) " + - "ON CONFLICT (study_id, participant_id) DO " + - " UPDATE SET accepted = excluded.accepted, origin = excluded.origin, content_md5 = excluded.content_md5, " + - " consent_timestamp = now(), consent_withdrawn = NULL"; + "ON CONFLICT (study_id, participant_id) DO " + + " UPDATE SET accepted = excluded.accepted, origin = excluded.origin, content_md5 = excluded.content_md5, " + + " consent_timestamp = now(), consent_withdrawn = NULL"; private static final String SQL_WITHDRAW_STUDY_CONSENT = "UPDATE participation_consents " + - "SET consent_withdrawn = now() " + - "WHERE study_id = :study_id AND participant_id = :participant_id"; + "SET consent_withdrawn = now() " + + "WHERE study_id = :study_id AND participant_id = :participant_id"; private static final String SQL_INSERT_OBSERVATION_CONSENT = "INSERT INTO observation_consents(study_id, participant_id, observation_id) VALUES (:study_id, :participant_id, :observation_id) " + - "ON CONFLICT (study_id, participant_id, observation_id) DO NOTHING"; + "ON CONFLICT (study_id, participant_id, observation_id) DO NOTHING"; private static final String SQL_SET_PARTICIPANT_STATUS = "UPDATE participants " + - "SET status = :newStatus::participant_status, start = :start, modified = now() " + - "WHERE study_id = :study_id AND participant_id = :participant_id AND status = :oldStatus::participant_status"; + "SET status = :newStatus::participant_status, start = :start, modified = now() " + + "WHERE study_id = :study_id AND participant_id = :participant_id AND status = :oldStatus::participant_status"; private static final String SQL_LIST_PARTICIPANTS_BY_STUDY = "SELECT participant_id, alias, status, sg.study_group_id, sg.title as study_group_title, start " + - "FROM participants p LEFT OUTER JOIN study_groups sg ON ( p.study_id = sg.study_id AND p.study_group_id = sg.study_group_id ) " + - "WHERE p.study_id = :study_id " + - "AND (p.study_group_id = :study_group_id OR :study_group_id::INT IS NULL)"; + "FROM participants p LEFT OUTER JOIN study_groups sg ON ( p.study_id = sg.study_id AND p.study_group_id = sg.study_group_id ) " + + "WHERE p.study_id = :study_id " + + "AND (p.study_group_id = :study_group_id OR :study_group_id::INT IS NULL)"; private static final String GET_OBSERVATION_PROPERTIES_FOR_PARTICIPANT = "SELECT properties FROM participant_observation_properties " + - "WHERE study_id = ? AND participant_id = ? AND observation_id = ?"; + "WHERE study_id = ? AND participant_id = ? AND observation_id = ?"; private static final String GET_API_ROUTING_INFO_BY_API_TOKEN = """ SELECT t.study_id, t.observation_id, o.study_group_id, o.type, t.token, @@ -116,14 +116,14 @@ INNER JOIN studies s ON (t.study_id = s.study_id) private static final String GET_PARTICIPANT_INFO_AND_START_DURATION_END_FOR_STUDY_AND_PARTICIPANT = "SELECT start, participant_id, alias, COALESCE(sg.duration, s.duration) AS duration, s.planned_end_date FROM participants p " + - "LEFT OUTER JOIN study_groups sg on p.study_id = sg.study_id and p.study_group_id = sg.study_group_id " + - "JOIN studies s on p.study_id = s.study_id " + - "WHERE p.study_id = ? AND participant_id = ?"; + "LEFT OUTER JOIN study_groups sg on p.study_id = sg.study_id and p.study_group_id = sg.study_group_id " + + "JOIN studies s on p.study_id = s.study_id " + + "WHERE p.study_id = ? AND participant_id = ?"; private static final String GET_DURATION_INFO_FOR_STUDY = "SELECT sg.study_group_id as groupid, sg.duration AS groupduration, s.duration AS studyduration, s.planned_end_date AS enddate, s.planned_start_date AS startdate FROM studies s " + - "LEFT OUTER JOIN study_groups sg on s.study_id = sg.study_id " + - "WHERE s.study_id = ?"; + "LEFT OUTER JOIN study_groups sg on s.study_id = sg.study_id " + + "WHERE s.study_id = ?"; private final JdbcTemplate jdbcTemplate; private final NamedParameterJdbcTemplate namedTemplate; @@ -147,7 +147,7 @@ private Optional getRoutingInfo(String registrationToken, boolean l } public Optional getApiRoutingInfo(Long studyId, Integer observationId, Integer tokenId) { - try(var stream = jdbcTemplate.queryForStream( + try (var stream = jdbcTemplate.queryForStream( GET_API_ROUTING_INFO_BY_API_TOKEN, getApiRoutingInfoRowMapper(), studyId, observationId, tokenId @@ -177,7 +177,7 @@ public Optional findStudy(RoutingInfo routingInfo) { public Optional findStudy(RoutingInfo routingInfo, boolean filterObservationsByGroup) { final List observations = listObservations( - routingInfo.studyId(), routingInfo.studyGroupId().orElse(-1), routingInfo.participantId(),filterObservationsByGroup); + routingInfo.studyId(), routingInfo.studyGroupId().orElse(-1), routingInfo.participantId(), filterObservationsByGroup); final SimpleParticipant participant = findParticipant(routingInfo).orElse(null); @@ -216,7 +216,7 @@ public List listParticipants(long studyId, OptionalInt groupId) { } private List listObservations(long studyId, int groupId, int participantId, boolean filterByGroup) { - if(filterByGroup) { + if (filterByGroup) { return jdbcTemplate.query(SQL_LIST_OBSERVATIONS_BY_STUDY, getObservationRowMapper(), studyId, groupId).stream() .map(o -> mergeParticipantProperties(o, studyId, participantId)) .toList(); @@ -248,7 +248,7 @@ public Optional getParticipantProperties(Long studyId, Integer participa } private static RowMapper getParticipantObservationPropertiesRowMapper() { - return (rs, rowNum) -> DbUtils.readObject(rs,"properties"); + return (rs, rowNum) -> DbUtils.readObject(rs, "properties"); } private static RowMapper getObservationScheduleRowMapper() { @@ -361,7 +361,7 @@ private static RowMapper getObservationRowMapper() { rs.getString("title"), rs.getString("type"), rs.getString("participant_info"), - DbUtils.readObject(rs,"properties"), + DbUtils.readObject(rs, "properties"), DbUtils.readEvent(rs, "schedule"), toInstant(rs.getTimestamp("created")), toInstant(rs.getTimestamp("modified")), @@ -425,16 +425,11 @@ private static MapSqlParameterSource toParameterSource(long studyId, int partici } public Interval getInterval(Long studyId, Integer participantId, RelativeEvent event) { - try(var stream = jdbcTemplate.queryForStream( + try (var stream = jdbcTemplate.queryForStream( GET_PARTICIPANT_INFO_AND_START_DURATION_END_FOR_STUDY_AND_PARTICIPANT, ((rs, rowNum) -> { Instant start = rs.getTimestamp("start").toInstant(); - // TODO correct sql.Date to Instant with Time 0 ?! - Instant end = Optional.ofNullable(DbUtils.readDuration(rs, "duration")) - .map(d -> d.getEnd(start)) - .orElse(Instant.ofEpochMilli(rs.getDate("planned_end_date").getTime())); - return new Interval(start, SchedulerUtils.getEnd(event, start, end)); - + return new Interval(start, SchedulerUtils.getEnd(event, start)); }), studyId, participantId )) { @@ -444,12 +439,12 @@ public Interval getInterval(Long studyId, Integer participantId, RelativeEvent e public Optional getStudyDurationInfo(Long studyId) { return jdbcTemplate.query(GET_DURATION_INFO_FOR_STUDY, - ((rs, rowNum) -> new StudyDurationInfo() - .setEndDate(rs.getDate("enddate").toLocalDate()) - .setStartDate(rs.getDate("startdate").toLocalDate()) - .setDuration(DbUtils.readDuration(rs, "studyduration")) - .addGroupDuration(Pair.of(rs.getInt("groupid"), DbUtils.readDuration(rs, "groupduration")) - )), studyId).stream() + ((rs, rowNum) -> new StudyDurationInfo() + .setEndDate(rs.getDate("enddate").toLocalDate()) + .setStartDate(rs.getDate("startdate").toLocalDate()) + .setDuration(DbUtils.readDuration(rs, "studyduration")) + .addGroupDuration(Pair.of(rs.getInt("groupid"), DbUtils.readDuration(rs, "groupduration")) + )), studyId).stream() .reduce((prev, curr) -> prev.addGroupDuration(curr.getGroupDurations().get(0))); } } diff --git a/src/main/java/io/redlink/more/data/schedule/SchedulerUtils.java b/src/main/java/io/redlink/more/data/schedule/SchedulerUtils.java index bd8772b..051bf22 100644 --- a/src/main/java/io/redlink/more/data/schedule/SchedulerUtils.java +++ b/src/main/java/io/redlink/more/data/schedule/SchedulerUtils.java @@ -24,13 +24,13 @@ public class SchedulerUtils { - public static Instant getEnd(RelativeEvent event, Instant start, Instant end) { - return parseToObservationSchedulesForRelativeEvent(event, start, end) + public static Instant getEnd(RelativeEvent event, Instant start) { + return parseToObservationSchedulesForRelativeEvent(event, start) .stream().map(Range::getMaximum).max(Instant::compareTo).orElse(null); } public static List> parseToObservationSchedulesForRelativeEvent( - RelativeEvent event, Instant start, Instant maxEnd) { + RelativeEvent event, Instant start) { final List> events = new ArrayList<>(); @@ -42,13 +42,12 @@ public static List> parseToObservationSchedulesForRelativeEvent( if (event.getRrrule() != null) { RelativeRecurrenceRule rrule = event.getRrrule(); Instant maxEndOfRule = currentEvt.getMaximum().plus(rrule.getEndAfter().getValue(), rrule.getEndAfter().getUnit().toTemporalUnit()); - maxEnd = maxEnd.isBefore(maxEndOfRule) ? maxEnd : maxEndOfRule; long durationInMs = currentEvt.getMaximum().toEpochMilli() - currentEvt.getMinimum().toEpochMilli(); - while (currentEvt.getMaximum().isBefore(maxEnd)) { + while (currentEvt.getMaximum().isBefore(maxEndOfRule)) { events.add(currentEvt); - Instant estart = currentEvt.getMinimum().plus(rrule.getFrequency().getValue(), rrule.getFrequency().getUnit().toTemporalUnit()); - currentEvt = Range.of(estart, estart.plusMillis(durationInMs)); + Instant eventStart = currentEvt.getMinimum().plus(rrule.getFrequency().getValue(), rrule.getFrequency().getUnit().toTemporalUnit()); + currentEvt = Range.of(eventStart, eventStart.plusMillis(durationInMs)); } } else { events.add(currentEvt); @@ -90,7 +89,7 @@ public static List> parseToObservationSchedules(ScheduleEvent sch if (scheduleEvent instanceof Event event) { return parseToObservationSchedulesForEvent(event, start, end); } else if (scheduleEvent instanceof RelativeEvent relativeEvent) { - return parseToObservationSchedulesForRelativeEvent(relativeEvent, start, end); + return parseToObservationSchedulesForRelativeEvent(relativeEvent, start); } else { return Collections.emptyList(); } diff --git a/src/test/java/io/redlink/more/data/schedule/SchedulerUtilsTest.java b/src/test/java/io/redlink/more/data/schedule/SchedulerUtilsTest.java index 669357f..2d97e5f 100644 --- a/src/test/java/io/redlink/more/data/schedule/SchedulerUtilsTest.java +++ b/src/test/java/io/redlink/more/data/schedule/SchedulerUtilsTest.java @@ -10,8 +10,6 @@ import io.redlink.more.data.model.Observation; import io.redlink.more.data.model.scheduler.*; -import java.time.LocalTime; - import org.apache.commons.lang3.Range; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; @@ -21,6 +19,7 @@ import java.time.Instant; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -28,7 +27,7 @@ import java.util.List; import static io.redlink.more.data.schedule.SchedulerUtils.shiftStartIfObservationAlreadyEnded; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -43,7 +42,7 @@ void testParseDailyEvent() { List> expectedValues = new ArrayList<>(); expectedValues.add(Range.of(LocalDateTime.parse("2022-11-23 14:00:00", formatter).toInstant(ZoneOffset.UTC) - ,LocalDateTime.parse("2022-11-23 16:00:00", formatter).toInstant(ZoneOffset.UTC))); + , LocalDateTime.parse("2022-11-23 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2022-11-24 14:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2022-11-24 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2022-11-25 14:00:00", formatter).toInstant(ZoneOffset.UTC), @@ -70,7 +69,8 @@ void testParseDailyEvent() { actualValues = SchedulerUtils.parseToObservationSchedules(eventUntil, Instant.parse("2022-10-01T00:00:00.000Z"), Instant.parse("2023-10-01T00:00:00.000Z")); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), - Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } + Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); + } @Test @DisplayName("Parsing daily event with count and until. Event duration is 30min") @@ -78,7 +78,7 @@ void testParseDailyEventWith30MinDuration() { List> expectedValues = new ArrayList<>(); expectedValues.add(Range.of(LocalDateTime.parse("2022-11-23 14:00:00", formatter).toInstant(ZoneOffset.UTC) - ,LocalDateTime.parse("2022-11-23 14:30:00", formatter).toInstant(ZoneOffset.UTC))); + , LocalDateTime.parse("2022-11-23 14:30:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2022-11-24 14:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2022-11-24 14:30:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2022-11-25 14:00:00", formatter).toInstant(ZoneOffset.UTC), @@ -105,14 +105,16 @@ void testParseDailyEventWith30MinDuration() { actualValues = SchedulerUtils.parseToObservationSchedules(eventUntil, Instant.parse("2022-10-01T00:00:00.000Z"), Instant.parse("2023-10-01T00:00:00.000Z")); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), - Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } + Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); + } + @Test @DisplayName("Parsing monthly event with until and byDay and bySetPos") void testParseMonthlyEvent() { List> expectedValues = new ArrayList<>(); expectedValues.add(Range.of(LocalDateTime.parse("2022-12-05 14:00:00", formatter).toInstant(ZoneOffset.UTC) - ,LocalDateTime.parse("2022-12-05 16:00:00", formatter).toInstant(ZoneOffset.UTC))); + , LocalDateTime.parse("2022-12-05 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2023-01-02 14:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2023-01-02 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2023-02-06 14:00:00", formatter).toInstant(ZoneOffset.UTC), @@ -130,7 +132,8 @@ void testParseMonthlyEvent() { List> actualValues = SchedulerUtils.parseToObservationSchedules(event, Instant.parse("2022-10-01T00:00:00.000Z"), Instant.parse("2023-10-01T00:00:00.000Z")); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), - Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } + Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); + } @Test @DisplayName("Parsing monthly event with until and array of byDay and bySetPos") @@ -138,21 +141,21 @@ void testParseMonthlyEventByDays() { List> expectedValues = new ArrayList<>(); expectedValues.add(Range.of(LocalDateTime.parse("2022-12-05 14:00:00", formatter).toInstant(ZoneOffset.UTC) - ,LocalDateTime.parse("2022-12-05 16:00:00", formatter).toInstant(ZoneOffset.UTC))); + , LocalDateTime.parse("2022-12-05 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2022-12-06 14:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2022-12-06 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2022-12-07 14:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2022-12-07 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2023-01-02 14:00:00", formatter).toInstant(ZoneOffset.UTC) - ,LocalDateTime.parse("2023-01-02 16:00:00", formatter).toInstant(ZoneOffset.UTC))); + , LocalDateTime.parse("2023-01-02 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2023-01-03 14:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2023-01-03 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2023-01-04 14:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2023-01-04 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2023-02-01 14:00:00", formatter).toInstant(ZoneOffset.UTC) - ,LocalDateTime.parse("2023-02-01 16:00:00", formatter).toInstant(ZoneOffset.UTC))); + , LocalDateTime.parse("2023-02-01 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2023-02-06 14:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2023-02-06 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2023-02-07 14:00:00", formatter).toInstant(ZoneOffset.UTC), @@ -169,7 +172,8 @@ void testParseMonthlyEventByDays() { .setCount(9)); List> actualValues = SchedulerUtils.parseToObservationSchedules(event, Instant.parse("2022-10-01T00:00:00.000Z"), Instant.parse("2023-10-01T00:00:00.000Z")); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), - Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } + Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); + } @Test @DisplayName("Parsing weekly event with count") @@ -177,7 +181,7 @@ void testParseWeeklyEvent() { List> expectedValues = new ArrayList<>(); expectedValues.add(Range.of(LocalDateTime.parse("2022-11-23 14:00:00", formatter).toInstant(ZoneOffset.UTC) - ,LocalDateTime.parse("2022-11-23 16:00:00", formatter).toInstant(ZoneOffset.UTC))); + , LocalDateTime.parse("2022-11-23 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2022-11-30 14:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2022-11-30 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2022-12-07 14:00:00", formatter).toInstant(ZoneOffset.UTC), @@ -193,7 +197,8 @@ void testParseWeeklyEvent() { .setCount(3)); List> actualValues = SchedulerUtils.parseToObservationSchedules(event, Instant.parse("2022-10-01T00:00:00.000Z"), Instant.parse("2023-10-01T00:00:00.000Z")); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), - Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } + Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); + } @Test @DisplayName("Parsing yearly event with count") @@ -201,7 +206,7 @@ void testParseYearlyEvent() { List> expectedValues = new ArrayList<>(); expectedValues.add(Range.of(LocalDateTime.parse("2022-12-05 14:00:00", formatter).toInstant(ZoneOffset.UTC) - ,LocalDateTime.parse("2022-12-05 16:00:00", formatter).toInstant(ZoneOffset.UTC))); + , LocalDateTime.parse("2022-12-05 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2023-12-05 14:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2023-12-05 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2024-12-05 14:00:00", formatter).toInstant(ZoneOffset.UTC), @@ -218,7 +223,8 @@ void testParseYearlyEvent() { .setCount(3)); List> actualValues = SchedulerUtils.parseToObservationSchedules(event, Instant.parse("2022-10-01T00:00:00.000Z"), Instant.parse("2030-10-01T00:00:00.000Z")); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), - Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } + Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); + } @Test @DisplayName("Parsing yearly event with count and bySetPos") @@ -226,7 +232,7 @@ void testParseYearlyEventBySetPos() { List> expectedValues = new ArrayList<>(); expectedValues.add(Range.of(LocalDateTime.parse("2022-12-05 14:00:00", formatter).toInstant(ZoneOffset.UTC) - ,LocalDateTime.parse("2022-12-05 16:00:00", formatter).toInstant(ZoneOffset.UTC))); + , LocalDateTime.parse("2022-12-05 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2023-12-04 14:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2023-12-04 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2024-12-02 14:00:00", formatter).toInstant(ZoneOffset.UTC), @@ -244,7 +250,8 @@ void testParseYearlyEventBySetPos() { .setCount(3)); List> actualValues = SchedulerUtils.parseToObservationSchedules(event, Instant.parse("2022-10-01T00:00:00.000Z"), Instant.parse("2030-10-01T00:00:00.000Z")); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), - Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } + Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); + } @Test @DisplayName("Parsing yearly event with count and bySetPos and byDays") @@ -252,17 +259,17 @@ void testParseYearlyEventBySetPosAndByDays() { List> expectedValues = new ArrayList<>(); expectedValues.add(Range.of(LocalDateTime.parse("2022-12-05 14:00:00", formatter).toInstant(ZoneOffset.UTC) - ,LocalDateTime.parse("2022-12-05 16:00:00", formatter).toInstant(ZoneOffset.UTC))); + , LocalDateTime.parse("2022-12-05 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2022-12-06 14:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2022-12-06 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2023-12-04 14:00:00", formatter).toInstant(ZoneOffset.UTC) - ,LocalDateTime.parse("2023-12-04 16:00:00", formatter).toInstant(ZoneOffset.UTC))); + , LocalDateTime.parse("2023-12-04 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2023-12-05 14:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2023-12-05 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2024-12-02 14:00:00", formatter).toInstant(ZoneOffset.UTC) - ,LocalDateTime.parse("2024-12-02 16:00:00", formatter).toInstant(ZoneOffset.UTC))); + , LocalDateTime.parse("2024-12-02 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2024-12-03 14:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2024-12-03 16:00:00", formatter).toInstant(ZoneOffset.UTC))); @@ -287,7 +294,7 @@ void testParseHourlyEvent() { List> expectedValues = new ArrayList<>(); expectedValues.add(Range.of(LocalDateTime.parse("2022-12-05 15:00:00", formatter).toInstant(ZoneOffset.UTC) - ,LocalDateTime.parse("2022-12-05 16:00:00", formatter).toInstant(ZoneOffset.UTC))); + , LocalDateTime.parse("2022-12-05 16:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2022-12-05 17:00:00", formatter).toInstant(ZoneOffset.UTC), LocalDateTime.parse("2022-12-05 18:00:00", formatter).toInstant(ZoneOffset.UTC))); expectedValues.add(Range.of(LocalDateTime.parse("2022-12-05 19:00:00", formatter).toInstant(ZoneOffset.UTC), @@ -310,19 +317,18 @@ void testParseHourlyEvent() { void testRelativeEvent() { RelativeEvent event = new RelativeEvent() .setDtstart( - new RelativeDate() - .setOffset(new Duration().setValue(1).setUnit(Duration.Unit.DAY)) - .setTime(LocalTime.parse("10:00")) + new RelativeDate() + .setOffset(new Duration().setValue(1).setUnit(Duration.Unit.DAY)) + .setTime(LocalTime.parse("10:00")) ).setDtend( - new RelativeDate() - .setOffset(new Duration().setValue(1).setUnit(Duration.Unit.DAY)) - .setTime(LocalTime.parse("11:30")) + new RelativeDate() + .setOffset(new Duration().setValue(1).setUnit(Duration.Unit.DAY)) + .setTime(LocalTime.parse("11:30")) ); - Instant start = Instant.ofEpochSecond(1700118000); // Thursday, 30. November 2023 00:00:00 - Instant maxEnd = Instant.ofEpochSecond(1701302400); // Thursday, 16. November 2023 07:00:00 + Instant start = Instant.ofEpochSecond(1700118000); // Thursday, 16. November 2023 07:00:00 - List> events = SchedulerUtils.parseToObservationSchedulesForRelativeEvent(event, start, maxEnd); + List> events = SchedulerUtils.parseToObservationSchedulesForRelativeEvent(event, start); Assertions.assertEquals(1, events.size()); } @@ -345,9 +351,8 @@ void testRelativeEventWithRecursion() { ); Instant start = Instant.ofEpochSecond(1700118000); // Thursday, 16. November 2023 07:00:00 - Instant maxEnd = Instant.ofEpochSecond(1701302400); // Thursday, 30. November 2023 00:00:00 - List> events = SchedulerUtils.parseToObservationSchedulesForRelativeEvent(event, start, maxEnd); + List> events = SchedulerUtils.parseToObservationSchedulesForRelativeEvent(event, start); Assertions.assertEquals(5, events.size()); } @@ -370,10 +375,9 @@ void testRelativeEventWithRecursionLongRun() { ); Instant start = Instant.ofEpochSecond(1700118000); // Thursday, 16. November 2023 07:00:00 - Instant maxEnd = Instant.ofEpochSecond(1701302400); // Thursday, 30. November 2023 00:00:00 - List> events = SchedulerUtils.parseToObservationSchedulesForRelativeEvent(event, start, maxEnd); - Assertions.assertEquals(5, events.size()); + List> events = SchedulerUtils.parseToObservationSchedulesForRelativeEvent(event, start); + Assertions.assertEquals(34, events.size()); } @Test