Validate expiryDate is strictly after eventDate and harden rejection tests
CI / backend-test (push) Successful in 59s
CI / frontend-test (push) Successful in 22s
CI / frontend-e2e (push) Successful in 56s
CI / build-and-publish (push) Has been skipped

Adds ExpiryDateBeforeEventException (400) when expiryDate <= eventDate,
asserts DB row count unchanged after every rejection in integration tests,
and replaces all hardcoded dates in EventServiceTest with TODAY-relative
expressions derived from the fixed Clock.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-08 13:22:10 +01:00
parent 4d6df8d16b
commit 90bfd12bf3
5 changed files with 171 additions and 23 deletions
@@ -16,7 +16,6 @@ import java.time.Instant;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -32,6 +31,7 @@ class EventServiceTest {
private static final Instant FIXED_INSTANT =
LocalDate.of(2026, 3, 5).atStartOfDay(ZONE).toInstant();
private static final Clock FIXED_CLOCK = Clock.fixed(FIXED_INSTANT, ZONE);
private static final LocalDate TODAY = LocalDate.ofInstant(FIXED_INSTANT, ZONE);
@Mock
private EventRepository eventRepository;
@@ -51,21 +51,21 @@ class EventServiceTest {
var command = new CreateEventCommand(
"Birthday Party",
"Come celebrate!",
OffsetDateTime.of(2026, 6, 15, 20, 0, 0, 0, ZoneOffset.ofHours(2)),
ZoneId.of("Europe/Berlin"),
TODAY.plusDays(90).atStartOfDay(ZONE).toOffsetDateTime(),
ZONE,
"Berlin",
LocalDate.of(2026, 7, 15)
TODAY.plusDays(120)
);
Event result = eventService.createEvent(command);
assertThat(result.getTitle()).isEqualTo("Birthday Party");
assertThat(result.getDescription()).isEqualTo("Come celebrate!");
assertThat(result.getTimezone()).isEqualTo(ZoneId.of("Europe/Berlin"));
assertThat(result.getTimezone()).isEqualTo(ZONE);
assertThat(result.getLocation()).isEqualTo("Berlin");
assertThat(result.getEventToken()).isNotNull();
assertThat(result.getOrganizerToken()).isNotNull();
assertThat(result.getCreatedAt()).isEqualTo(OffsetDateTime.now(FIXED_CLOCK));
assertThat(result.getCreatedAt()).isEqualTo(OffsetDateTime.ofInstant(FIXED_INSTANT, ZONE));
}
@Test
@@ -75,8 +75,8 @@ class EventServiceTest {
var command = new CreateEventCommand(
"Test", null,
OffsetDateTime.now(FIXED_CLOCK).plusDays(1), ZONE, null,
LocalDate.now(FIXED_CLOCK).plusDays(30)
TODAY.plusDays(10).atStartOfDay(ZONE).toOffsetDateTime(), ZONE, null,
TODAY.plusDays(11)
);
eventService.createEvent(command);
@@ -90,8 +90,8 @@ class EventServiceTest {
void expiryDateTodayThrowsException() {
var command = new CreateEventCommand(
"Test", null,
OffsetDateTime.now(FIXED_CLOCK).plusDays(1), ZONE, null,
LocalDate.now(FIXED_CLOCK)
TODAY.plusDays(10).atStartOfDay(ZONE).toOffsetDateTime(), ZONE, null,
TODAY
);
assertThatThrownBy(() -> eventService.createEvent(command))
@@ -102,8 +102,8 @@ class EventServiceTest {
void expiryDateInPastThrowsException() {
var command = new CreateEventCommand(
"Test", null,
OffsetDateTime.now(FIXED_CLOCK).plusDays(1), ZONE, null,
LocalDate.now(FIXED_CLOCK).minusDays(5)
TODAY.plusDays(10).atStartOfDay(ZONE).toOffsetDateTime(), ZONE, null,
TODAY.minusDays(5)
);
assertThatThrownBy(() -> eventService.createEvent(command))
@@ -117,13 +117,56 @@ class EventServiceTest {
var command = new CreateEventCommand(
"Test", null,
OffsetDateTime.now(FIXED_CLOCK).plusDays(1), ZONE, null,
LocalDate.now(FIXED_CLOCK).plusDays(1)
TODAY.plusDays(1).atStartOfDay(ZONE).toOffsetDateTime(), ZONE, null,
TODAY.plusDays(2)
);
Event result = eventService.createEvent(command);
assertThat(result.getExpiryDate()).isEqualTo(LocalDate.of(2026, 3, 6));
assertThat(result.getExpiryDate()).isEqualTo(TODAY.plusDays(2));
}
@Test
void expiryDateSameAsEventDateThrowsException() {
var command = new CreateEventCommand(
"Test", null,
TODAY.plusDays(10).atStartOfDay(ZONE).toOffsetDateTime(),
ZONE, null,
TODAY.plusDays(10)
);
assertThatThrownBy(() -> eventService.createEvent(command))
.isInstanceOf(ExpiryDateBeforeEventException.class);
}
@Test
void expiryDateBeforeEventDateThrowsException() {
var command = new CreateEventCommand(
"Test", null,
TODAY.plusDays(10).atStartOfDay(ZONE).toOffsetDateTime(),
ZONE, null,
TODAY.plusDays(5)
);
assertThatThrownBy(() -> eventService.createEvent(command))
.isInstanceOf(ExpiryDateBeforeEventException.class);
}
@Test
void expiryDateDayAfterEventDateSucceeds() {
when(eventRepository.save(any(Event.class)))
.thenAnswer(invocation -> invocation.getArgument(0));
var command = new CreateEventCommand(
"Test", null,
TODAY.plusDays(10).atStartOfDay(ZONE).toOffsetDateTime(),
ZONE, null,
TODAY.plusDays(11)
);
Event result = eventService.createEvent(command);
assertThat(result.getExpiryDate()).isEqualTo(TODAY.plusDays(11));
}
// --- GetEventUseCase tests (T004) ---
@@ -163,9 +206,9 @@ class EventServiceTest {
var command = new CreateEventCommand(
"Test", null,
OffsetDateTime.now(FIXED_CLOCK).plusDays(1),
TODAY.plusDays(10).atStartOfDay(ZONE).toOffsetDateTime(),
ZoneId.of("America/New_York"), null,
LocalDate.now(FIXED_CLOCK).plusDays(30)
TODAY.plusDays(11)
);
Event result = eventService.createEvent(command);