From d8c63efc00564599ad765997f359baa00a773678 Mon Sep 17 00:00:00 2001 From: Jan Cortiel Date: Tue, 3 Dec 2024 11:12:18 +0100 Subject: [PATCH] #549: Refactor SchedulerUtils method signatures to allow relative schedules to go beyond the planned study end date Refactored methods in SchedulerUtils to remove the redundant 'maxEnd' parameter, simplifying function calls and streamlining logic. Modified related calls in StudyRepository to align with the updated method signatures. Additionally, adjusted imports and improved test formatting for consistency and readability across files. --- .../more/data/repository/StudyRepository.java | 97 +++++++++---------- .../more/data/schedule/SchedulerUtils.java | 15 ++- .../data/schedule/SchedulerUtilsTest.java | 78 ++++++++------- 3 files changed, 94 insertions(+), 96 deletions(-) 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