Add persistence layer with Liquibase migration

JPA entity, repository, persistence adapter for events. Liquibase
changelog creates the events table with BIGSERIAL ID and UUID tokens.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-05 10:56:39 +01:00
parent 830ca55f20
commit c80074093c
6 changed files with 348 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
package de.fete.adapter.out.persistence;
import static org.assertj.core.api.Assertions.assertThat;
import de.fete.TestcontainersConfig;
import de.fete.domain.model.Event;
import de.fete.domain.port.out.EventRepository;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Optional;
import java.util.UUID;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
@SpringBootTest
@Import(TestcontainersConfig.class)
class EventPersistenceAdapterTest {
@Autowired
private EventRepository eventRepository;
@Test
void saveReturnsEventWithGeneratedId() {
Event event = buildEvent();
Event saved = eventRepository.save(event);
assertThat(saved.getId()).isNotNull();
assertThat(saved.getTitle()).isEqualTo("Test Event");
}
@Test
void savedEventIsFoundByEventToken() {
Event event = buildEvent();
Event saved = eventRepository.save(event);
Optional<Event> found = eventRepository.findByEventToken(saved.getEventToken());
assertThat(found).isPresent();
assertThat(found.get().getTitle()).isEqualTo("Test Event");
assertThat(found.get().getId()).isEqualTo(saved.getId());
}
@Test
void findByUnknownEventTokenReturnsEmpty() {
Optional<Event> found = eventRepository.findByEventToken(UUID.randomUUID());
assertThat(found).isEmpty();
}
@Test
void allFieldsRoundTripCorrectly() {
OffsetDateTime dateTime =
OffsetDateTime.of(2026, 6, 15, 20, 0, 0, 0, ZoneOffset.ofHours(2));
LocalDate expiryDate = LocalDate.of(2026, 7, 15);
OffsetDateTime createdAt =
OffsetDateTime.of(2026, 3, 4, 12, 0, 0, 0, ZoneOffset.UTC);
var event = new Event();
event.setEventToken(UUID.randomUUID());
event.setOrganizerToken(UUID.randomUUID());
event.setTitle("Full Event");
event.setDescription("A detailed description");
event.setDateTime(dateTime);
event.setLocation("Berlin, Germany");
event.setExpiryDate(expiryDate);
event.setCreatedAt(createdAt);
Event saved = eventRepository.save(event);
Event found = eventRepository.findByEventToken(saved.getEventToken()).orElseThrow();
assertThat(found.getEventToken()).isEqualTo(event.getEventToken());
assertThat(found.getOrganizerToken()).isEqualTo(event.getOrganizerToken());
assertThat(found.getTitle()).isEqualTo("Full Event");
assertThat(found.getDescription()).isEqualTo("A detailed description");
assertThat(found.getDateTime().toInstant()).isEqualTo(dateTime.toInstant());
assertThat(found.getLocation()).isEqualTo("Berlin, Germany");
assertThat(found.getExpiryDate()).isEqualTo(expiryDate);
assertThat(found.getCreatedAt().toInstant()).isEqualTo(createdAt.toInstant());
}
private Event buildEvent() {
var event = new Event();
event.setEventToken(UUID.randomUUID());
event.setOrganizerToken(UUID.randomUUID());
event.setTitle("Test Event");
event.setDescription("Test description");
event.setDateTime(OffsetDateTime.now().plusDays(7));
event.setLocation("Somewhere");
event.setExpiryDate(LocalDate.now().plusDays(30));
event.setCreatedAt(OffsetDateTime.now());
return event;
}
}