diff --git a/src/main/java/io/redlink/more/data/controller/transformer/StudyTransformer.java b/src/main/java/io/redlink/more/data/controller/transformer/StudyTransformer.java index c59ec70..fc6d9f8 100644 --- a/src/main/java/io/redlink/more/data/controller/transformer/StudyTransformer.java +++ b/src/main/java/io/redlink/more/data/controller/transformer/StudyTransformer.java @@ -12,6 +12,7 @@ import org.apache.commons.lang3.tuple.Pair; import java.time.Instant; +import java.time.LocalDateTime; import java.util.List; public final class StudyTransformer { @@ -30,7 +31,7 @@ public static StudyDTO toDTO(Study study) { .contact(toDTO(study.contact())) .start(study.startDate()) .end(study.endDate()) - .observations(toDTO(study.observations())) + .observations(toDTO(study.observations(), study.participant().start())) .version(BaseTransformers.toVersionTag(study.modified())) ; } @@ -53,11 +54,11 @@ public static ContactInfoDTO toDTO(Contact contact) { ; } - public static List toDTO(List observations) { - return observations.stream().map(StudyTransformer::toDTO).toList(); + public static List toDTO(List observations, LocalDateTime start) { + return observations.stream().map(o -> StudyTransformer.toDTO(o, start)).toList(); } - public static ObservationDTO toDTO(Observation observation) { + public static ObservationDTO toDTO(Observation observation, LocalDateTime start) { ObservationDTO dto = new ObservationDTO() .observationId(String.valueOf(observation.observationId())) .observationType(observation.type()) @@ -68,9 +69,9 @@ public static ObservationDTO toDTO(Observation observation) { .hidden(observation.hidden()) .noSchedule(observation.noSchedule()) ; - if(observation.observationSchedule() != null) { + if(observation.observationSchedule() != null && start != null) { dto.schedule(ICalendarParser - .parseToObservationSchedules(observation.observationSchedule()) + .parseToObservationSchedules(observation.observationSchedule(), start) .stream() .map(StudyTransformer::toObservationScheduleDTO) .toList()); diff --git a/src/main/java/io/redlink/more/data/model/Observation.java b/src/main/java/io/redlink/more/data/model/Observation.java index 0a7d039..6037555 100644 --- a/src/main/java/io/redlink/more/data/model/Observation.java +++ b/src/main/java/io/redlink/more/data/model/Observation.java @@ -1,5 +1,7 @@ package io.redlink.more.data.model; +import io.redlink.more.data.model.scheduler.ScheduleEvent; + import java.time.Instant; public record Observation( @@ -8,7 +10,7 @@ public record Observation( String type, String participantInfo, Object properties, - Event observationSchedule, + ScheduleEvent observationSchedule, Instant created, Instant modified, boolean hidden, diff --git a/src/main/java/io/redlink/more/data/model/SimpleParticipant.java b/src/main/java/io/redlink/more/data/model/SimpleParticipant.java index 60f68b4..fe1d9ed 100644 --- a/src/main/java/io/redlink/more/data/model/SimpleParticipant.java +++ b/src/main/java/io/redlink/more/data/model/SimpleParticipant.java @@ -1,7 +1,10 @@ package io.redlink.more.data.model; +import java.time.LocalDateTime; + public record SimpleParticipant( int id, - String alias + String alias, + LocalDateTime start ) { } diff --git a/src/main/java/io/redlink/more/data/model/Study.java b/src/main/java/io/redlink/more/data/model/Study.java index 9524c8b..f316018 100644 --- a/src/main/java/io/redlink/more/data/model/Study.java +++ b/src/main/java/io/redlink/more/data/model/Study.java @@ -1,7 +1,5 @@ package io.redlink.more.data.model; -import io.redlink.more.data.api.app.v1.model.StudyDTO; - import java.time.Instant; import java.time.LocalDate; import java.util.List; diff --git a/src/main/java/io/redlink/more/data/model/scheduler/Duration.java b/src/main/java/io/redlink/more/data/model/scheduler/Duration.java new file mode 100644 index 0000000..7fa6998 --- /dev/null +++ b/src/main/java/io/redlink/more/data/model/scheduler/Duration.java @@ -0,0 +1,75 @@ +package io.redlink.more.data.model.scheduler; + +import com.fasterxml.jackson.annotation.JsonCreator; + +public class Duration { + + private Integer value; + + /** + * unit of time to offset + */ + public enum Unit { + MINUTE("MINUTE"), + + HOUR("HOUR"), + + DAY("DAY"); + + private String value; + + Unit(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static Unit fromValue(String value) { + for (Unit b : Unit.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + private Unit unit; + + public Duration() { + } + + public Integer getValue() { + return value; + } + + public Duration setValue(Integer value) { + this.value = value; + return this; + } + + public Unit getUnit() { + return unit; + } + + public Duration setUnit(Unit unit) { + this.unit = unit; + return this; + } + + @Override + public String toString() { + return "Duration{" + + "offset=" + value + + ", unit=" + unit + + '}'; + } +} diff --git a/src/main/java/io/redlink/more/data/model/Event.java b/src/main/java/io/redlink/more/data/model/scheduler/Event.java similarity index 74% rename from src/main/java/io/redlink/more/data/model/Event.java rename to src/main/java/io/redlink/more/data/model/scheduler/Event.java index 14524f8..2d1be61 100644 --- a/src/main/java/io/redlink/more/data/model/Event.java +++ b/src/main/java/io/redlink/more/data/model/scheduler/Event.java @@ -1,12 +1,19 @@ -package io.redlink.more.data.model; +package io.redlink.more.data.model.scheduler; import java.time.Instant; -public class Event { +public class Event implements ScheduleEvent { + public static final String TYPE = "Event"; + private String type; private Instant dateStart; private Instant dateEnd; private RecurrenceRule recurrenceRule; + @Override + public String getType() { + return TYPE; + } + public Instant getDateStart() { return dateStart; } @@ -33,4 +40,6 @@ public Event setRRule(RecurrenceRule recurrenceRule) { this.recurrenceRule = recurrenceRule; return this; } + + } diff --git a/src/main/java/io/redlink/more/data/model/RecurrenceRule.java b/src/main/java/io/redlink/more/data/model/scheduler/RecurrenceRule.java similarity index 97% rename from src/main/java/io/redlink/more/data/model/RecurrenceRule.java rename to src/main/java/io/redlink/more/data/model/scheduler/RecurrenceRule.java index 80a4093..25122bd 100644 --- a/src/main/java/io/redlink/more/data/model/RecurrenceRule.java +++ b/src/main/java/io/redlink/more/data/model/scheduler/RecurrenceRule.java @@ -1,4 +1,4 @@ -package io.redlink.more.data.model; +package io.redlink.more.data.model.scheduler; import java.time.Instant; import java.util.List; diff --git a/src/main/java/io/redlink/more/data/model/scheduler/RelativeDate.java b/src/main/java/io/redlink/more/data/model/scheduler/RelativeDate.java new file mode 100644 index 0000000..54811d2 --- /dev/null +++ b/src/main/java/io/redlink/more/data/model/scheduler/RelativeDate.java @@ -0,0 +1,28 @@ +package io.redlink.more.data.model.scheduler; + +public class RelativeDate { + + private Duration offset; + private String time; + + public RelativeDate() { + } + + public Duration getOffset() { + return offset; + } + + public RelativeDate setOffset(Duration offset) { + this.offset = offset; + return this; + } + + public String getTime() { + return time; + } + + public RelativeDate setTime(String time) { + this.time = time; + return this; + } +} diff --git a/src/main/java/io/redlink/more/data/model/scheduler/RelativeEvent.java b/src/main/java/io/redlink/more/data/model/scheduler/RelativeEvent.java new file mode 100644 index 0000000..2d6302f --- /dev/null +++ b/src/main/java/io/redlink/more/data/model/scheduler/RelativeEvent.java @@ -0,0 +1,54 @@ +package io.redlink.more.data.model.scheduler; + +public class RelativeEvent implements ScheduleEvent { + + public static final String TYPE = "RelativeEvent"; + + private String type; + + private RelativeDate dtstart; + + private RelativeDate dtend; + + private RelativeRecurrenceRule rrrule; + + public RelativeEvent() { + } + + @Override + public String getType() { + return TYPE; + } + + public RelativeEvent setType(String type) { + this.type = type; + return this; + } + + public RelativeDate getDtstart() { + return dtstart; + } + + public RelativeEvent setDtstart(RelativeDate dtstart) { + this.dtstart = dtstart; + return this; + } + + public RelativeDate getDtend() { + return dtend; + } + + public RelativeEvent setDtend(RelativeDate dtend) { + this.dtend = dtend; + return this; + } + + public RelativeRecurrenceRule getRrrule() { + return rrrule; + } + + public RelativeEvent setRrrule(RelativeRecurrenceRule rrrule) { + this.rrrule = rrrule; + return this; + } +} diff --git a/src/main/java/io/redlink/more/data/model/scheduler/RelativeRecurrenceRule.java b/src/main/java/io/redlink/more/data/model/scheduler/RelativeRecurrenceRule.java new file mode 100644 index 0000000..f98726c --- /dev/null +++ b/src/main/java/io/redlink/more/data/model/scheduler/RelativeRecurrenceRule.java @@ -0,0 +1,29 @@ +package io.redlink.more.data.model.scheduler; + +public class RelativeRecurrenceRule { + + private Duration frequency; + + private Duration endAfter; + + public RelativeRecurrenceRule() { + } + + public Duration getFrequency() { + return frequency; + } + + public RelativeRecurrenceRule setFrequency(Duration frequency) { + this.frequency = frequency; + return this; + } + + public Duration getEndAfter() { + return endAfter; + } + + public RelativeRecurrenceRule setEndAfter(Duration endAfter) { + this.endAfter = endAfter; + return this; + } +} diff --git a/src/main/java/io/redlink/more/data/model/scheduler/ScheduleEvent.java b/src/main/java/io/redlink/more/data/model/scheduler/ScheduleEvent.java new file mode 100644 index 0000000..22a971c --- /dev/null +++ b/src/main/java/io/redlink/more/data/model/scheduler/ScheduleEvent.java @@ -0,0 +1,18 @@ +package io.redlink.more.data.model.scheduler; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +@JsonIgnoreProperties( + value = "type", // ignore manually set type, it will be automatically generated by Jackson during serialization + allowSetters = true // allows the type to be set during deserialization +) +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true, defaultImpl = Event.class) +@JsonSubTypes({ + @JsonSubTypes.Type(value = Event.class, name = Event.TYPE), + @JsonSubTypes.Type(value = RelativeEvent.class, name = RelativeEvent.TYPE) +}) +public interface ScheduleEvent { + public String getType(); +} diff --git a/src/main/java/io/redlink/more/data/repository/DbUtils.java b/src/main/java/io/redlink/more/data/repository/DbUtils.java index 65bee7c..c8136fd 100644 --- a/src/main/java/io/redlink/more/data/repository/DbUtils.java +++ b/src/main/java/io/redlink/more/data/repository/DbUtils.java @@ -7,7 +7,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import io.redlink.more.data.model.Event; +import io.redlink.more.data.model.scheduler.ScheduleEvent; import java.sql.*; import java.time.Instant; @@ -50,11 +50,11 @@ public static OptionalInt readOptionalInt(ResultSet row, String columnLabel) thr } } - public static Event readEvent(ResultSet row, String columnLabel) throws SQLException { + public static ScheduleEvent readEvent(ResultSet row, String columnLabel) throws SQLException { var rawValue = row.getString(columnLabel); if(rawValue == null) return null; try { - return MAPPER.readValue(rawValue, Event.class); + return MAPPER.readValue(rawValue, ScheduleEvent.class); } catch (JsonProcessingException e) { throw new SQLDataException("Could not read Event from column '" + columnLabel + "'", e); } 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 980f09a..9379b42 100644 --- a/src/main/java/io/redlink/more/data/repository/StudyRepository.java +++ b/src/main/java/io/redlink/more/data/repository/StudyRepository.java @@ -7,10 +7,14 @@ import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Timestamp; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; import java.util.OptionalInt; import java.util.function.Supplier; + +import io.redlink.more.data.model.scheduler.ScheduleEvent; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; @@ -72,7 +76,7 @@ public class StudyRepository { "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, modified = now() " + + "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 GET_OBSERVATION_PROPERTIES_FOR_PARTICIPANT = @@ -124,7 +128,7 @@ public Optional getParticipantStudyGroupId(Long studyId, Integer pa } } - public Optional getObservationSchedule(Long studyId, Integer observationId) { + public Optional getObservationSchedule(Long studyId, Integer observationId) { try (var stream = jdbcTemplate.queryForStream( GET_OBSERVATION_SCHEDULE, getObservationScheduleRowMapper(), @@ -154,7 +158,8 @@ public Optional findParticipant(RoutingInfo routingInfo) { try (var stream = jdbcTemplate.queryForStream(SQL_FIND_PARTICIPANT_BY_STUDY_AND_ID, (rs, rowNum) -> new SimpleParticipant( rs.getInt("participant_id"), - rs.getString("alias") + rs.getString("alias"), + Optional.ofNullable(rs.getTimestamp("start")).map(Timestamp::toLocalDateTime).orElse(null) ) , routingInfo.studyId(), routingInfo.participantId())) { return stream.findFirst(); @@ -191,7 +196,7 @@ private static RowMapper getParticipantObservationPropertiesRowMapper() return (rs, rowNum) -> DbUtils.readObject(rs,"properties"); } - private static RowMapper getObservationScheduleRowMapper() { + private static RowMapper getObservationScheduleRowMapper() { return (rs, rowNum) -> DbUtils.readEvent(rs, "schedule"); } @@ -203,7 +208,7 @@ public Optional createCredentials(String registrationToken, ParticipantC var routingInfo = ri.get(); final String secret = passwordSupplier.get(); - storeConsent(routingInfo.studyId(), routingInfo.participantId(), consent); + //storeConsent(routingInfo.studyId(), routingInfo.participantId(), consent); final String apiId = namedTemplate.queryForObject(SQL_INSERT_CREDENTIALS, toParameterSource(routingInfo.studyId(), routingInfo.participantId()) @@ -221,6 +226,7 @@ public Optional createCredentials(String registrationToken, ParticipantC private void updateParticipantStatus(long studyId, int particpantId, String oldStatus, String newStatus) { namedTemplate.update(SQL_SET_PARTICIPANT_STATUS, toParameterSource(studyId, particpantId) + .addValue("start", "active".equals(newStatus) ? Timestamp.valueOf(LocalDateTime.now()) : null) .addValue("oldStatus", oldStatus) .addValue("newStatus", newStatus) ); diff --git a/src/main/java/io/redlink/more/data/schedule/ICalendarParser.java b/src/main/java/io/redlink/more/data/schedule/ICalendarParser.java index c94dbe1..97c952e 100644 --- a/src/main/java/io/redlink/more/data/schedule/ICalendarParser.java +++ b/src/main/java/io/redlink/more/data/schedule/ICalendarParser.java @@ -5,13 +5,15 @@ import biweekly.util.Frequency; import biweekly.util.Recurrence; import biweekly.util.com.google.ical.compat.javautil.DateIterator; -import io.redlink.more.data.model.Event; -import io.redlink.more.data.model.RecurrenceRule; +import io.redlink.more.data.model.scheduler.Event; +import io.redlink.more.data.model.scheduler.RecurrenceRule; +import io.redlink.more.data.model.scheduler.ScheduleEvent; import org.apache.commons.lang3.tuple.Pair; import java.sql.Date; import java.time.Duration; import java.time.Instant; +import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; @@ -20,16 +22,18 @@ public class ICalendarParser { - public static List> parseToObservationSchedules(Event event) { + public static List> parseToObservationSchedules(ScheduleEvent scheduleEvent, LocalDateTime start) { + //TODO implement + Event event = (Event) scheduleEvent; List> observationSchedules = new ArrayList<>(); if(event.getDateStart() != null && event.getDateEnd() != null) { VEvent iCalEvent = parseToICalEvent(event); long eventDuration = getEventTime(event); DateIterator it = iCalEvent.getDateIterator(TimeZone.getDefault()); while (it.hasNext()) { - Instant start = it.next().toInstant(); - Instant end = start.plus(eventDuration, ChronoUnit.SECONDS); - observationSchedules.add(Pair.of(start, end)); + Instant ostart = it.next().toInstant(); + Instant oend = ostart.plus(eventDuration, ChronoUnit.SECONDS); + observationSchedules.add(Pair.of(ostart, oend)); } } // TODO edge cases if calculated days are not consecutive (e.g. first weekend -> first of month is a sunday) diff --git a/src/main/java/io/redlink/more/data/service/ExternalService.java b/src/main/java/io/redlink/more/data/service/ExternalService.java index dcf0a53..2540b5e 100644 --- a/src/main/java/io/redlink/more/data/service/ExternalService.java +++ b/src/main/java/io/redlink/more/data/service/ExternalService.java @@ -3,13 +3,13 @@ import io.redlink.more.data.exception.BadRequestException; import io.redlink.more.data.exception.NotFoundException; import io.redlink.more.data.model.ApiRoutingInfo; -import io.redlink.more.data.model.Event; +import io.redlink.more.data.model.scheduler.Event; +import io.redlink.more.data.model.scheduler.ScheduleEvent; import io.redlink.more.data.repository.StudyRepository; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import java.time.Instant; -import java.time.OffsetDateTime; import java.util.List; import java.util.Optional; import java.util.OptionalInt; @@ -47,12 +47,20 @@ public ApiRoutingInfo validateRoutingInfo(ApiRoutingInfo routingInfo, Integer pa } public void validateTimeFrame(Long studyId, Integer observationId, List timestamps) { - Optional schedule = repository.getObservationSchedule(studyId, observationId); + Optional schedule = repository.getObservationSchedule(studyId, observationId); if(schedule.isEmpty()){ throw NotFoundException.Observation(observationId); } - Instant startDate = schedule.get().getDateStart(); - Instant endDate = schedule.get().getDateEnd(); + + //TODO implement and cache because of inefficiency + if(!Event.class.isAssignableFrom(schedule.get().getClass())) { + throw new RuntimeException("Schedule type currently not supported"); + } + + Event event = (Event) schedule.get(); + + Instant startDate = event.getDateStart(); + Instant endDate = event.getDateEnd(); timestamps.forEach(timestamp -> { if(timestamp.isBefore(startDate) || timestamp.isAfter(endDate)) diff --git a/src/test/java/io/redlink/more/data/schedule/ICalendarParserTest.java b/src/test/java/io/redlink/more/data/schedule/ICalendarParserTest.java index 140d95e..6ec4d26 100644 --- a/src/test/java/io/redlink/more/data/schedule/ICalendarParserTest.java +++ b/src/test/java/io/redlink/more/data/schedule/ICalendarParserTest.java @@ -1,7 +1,7 @@ package io.redlink.more.data.schedule; -import io.redlink.more.data.model.Event; -import io.redlink.more.data.model.RecurrenceRule; +import io.redlink.more.data.model.scheduler.Event; +import io.redlink.more.data.model.scheduler.RecurrenceRule; import org.apache.commons.lang3.tuple.Pair; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -42,7 +42,7 @@ void testParseDailyEvent() { .setFreq("DAILY") .setInterval(1) .setCount(3)); - List> actualValues = ICalendarParser.parseToObservationSchedules(eventCount); + List> actualValues = ICalendarParser.parseToObservationSchedules(eventCount, LocalDateTime.now()); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); @@ -54,7 +54,7 @@ void testParseDailyEvent() { .setInterval(1) .setUntil(LocalDateTime.parse("2022-11-25 14:00:00", formatter).toInstant(ZoneOffset.UTC))); - actualValues = ICalendarParser.parseToObservationSchedules(eventUntil); + actualValues = ICalendarParser.parseToObservationSchedules(eventUntil, LocalDateTime.now()); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } @@ -77,7 +77,7 @@ void testParseDailyEventWith30MinDuration() { .setFreq("DAILY") .setInterval(1) .setCount(3)); - List> actualValues = ICalendarParser.parseToObservationSchedules(eventCount); + List> actualValues = ICalendarParser.parseToObservationSchedules(eventCount, LocalDateTime.now()); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); @@ -89,7 +89,7 @@ void testParseDailyEventWith30MinDuration() { .setInterval(1) .setUntil(LocalDateTime.parse("2022-11-25 14:00:00", formatter).toInstant(ZoneOffset.UTC))); - actualValues = ICalendarParser.parseToObservationSchedules(eventUntil); + actualValues = ICalendarParser.parseToObservationSchedules(eventUntil, LocalDateTime.now()); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } @Test @@ -114,7 +114,7 @@ void testParseMonthlyEvent() { .setBySetPos(1) .setCount(3)); - List> actualValues = ICalendarParser.parseToObservationSchedules(event); + List> actualValues = ICalendarParser.parseToObservationSchedules(event, LocalDateTime.now()); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } @@ -153,7 +153,7 @@ void testParseMonthlyEventByDays() { .setByDay(List.of(new String[]{"MO", "TU", "WE"})) .setBySetPos(1) .setCount(9)); - List> actualValues = ICalendarParser.parseToObservationSchedules(event); + List> actualValues = ICalendarParser.parseToObservationSchedules(event, LocalDateTime.now()); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } @@ -177,7 +177,7 @@ void testParseWeeklyEvent() { .setInterval(1) .setByDay(List.of(new String[]{"WE"})) .setCount(3)); - List> actualValues = ICalendarParser.parseToObservationSchedules(event); + List> actualValues = ICalendarParser.parseToObservationSchedules(event, LocalDateTime.now()); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } @@ -202,7 +202,7 @@ void testParseYearlyEvent() { .setByMonthDay(5) .setByMonth(12) .setCount(3)); - List> actualValues = ICalendarParser.parseToObservationSchedules(event); + List> actualValues = ICalendarParser.parseToObservationSchedules(event, LocalDateTime.now()); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } @@ -228,7 +228,7 @@ void testParseYearlyEventBySetPos() { .setByDay(List.of(new String[]{"MO"})) .setByMonth(12) .setCount(3)); - List> actualValues = ICalendarParser.parseToObservationSchedules(event); + List> actualValues = ICalendarParser.parseToObservationSchedules(event, LocalDateTime.now()); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } @@ -262,7 +262,7 @@ void testParseYearlyEventBySetPosAndByDays() { .setByDay(List.of(new String[]{"MO", "TU"})) .setByMonth(12) .setCount(6)); - List> actualValues = ICalendarParser.parseToObservationSchedules(event); + List> actualValues = ICalendarParser.parseToObservationSchedules(event, LocalDateTime.now()); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); } @@ -286,7 +286,7 @@ void testParseHourlyEvent() { .setFreq("HOURLY") .setInterval(2) .setUntil(LocalDateTime.parse("2022-12-05 20:00:00", formatter).toInstant(ZoneOffset.UTC))); - List> actualValues = ICalendarParser.parseToObservationSchedules(event); + List> actualValues = ICalendarParser.parseToObservationSchedules(event, LocalDateTime.now()); assertArrayEquals(Arrays.stream(expectedValues.toArray()).map(Object::toString).toArray(), Arrays.stream(actualValues.toArray()).map(Object::toString).toArray()); }