diff --git a/backend/src/main/java/de/fete/adapter/in/web/EventController.java b/backend/src/main/java/de/fete/adapter/in/web/EventController.java index bd8b407..25a0d20 100644 --- a/backend/src/main/java/de/fete/adapter/in/web/EventController.java +++ b/backend/src/main/java/de/fete/adapter/in/web/EventController.java @@ -20,9 +20,7 @@ import de.fete.domain.port.in.CreateEventUseCase; import de.fete.domain.port.in.CreateRsvpUseCase; import de.fete.domain.port.in.GetAttendeesUseCase; import de.fete.domain.port.in.GetEventUseCase; -import java.time.Clock; import java.time.DateTimeException; -import java.time.LocalDate; import java.time.ZoneId; import java.util.List; import java.util.UUID; @@ -39,22 +37,19 @@ public class EventController implements EventsApi { private final CreateRsvpUseCase createRsvpUseCase; private final CountAttendeesByEventUseCase countAttendeesByEventUseCase; private final GetAttendeesUseCase getAttendeesUseCase; - private final Clock clock; - /** Creates a new controller with the given use cases and clock. */ + /** Creates a new controller with the given use cases. */ public EventController( CreateEventUseCase createEventUseCase, GetEventUseCase getEventUseCase, CreateRsvpUseCase createRsvpUseCase, CountAttendeesByEventUseCase countAttendeesByEventUseCase, - GetAttendeesUseCase getAttendeesUseCase, - Clock clock) { + GetAttendeesUseCase getAttendeesUseCase) { this.createEventUseCase = createEventUseCase; this.getEventUseCase = getEventUseCase; this.createRsvpUseCase = createRsvpUseCase; this.countAttendeesByEventUseCase = countAttendeesByEventUseCase; this.getAttendeesUseCase = getAttendeesUseCase; - this.clock = clock; } @Override @@ -67,8 +62,7 @@ public class EventController implements EventsApi { request.getDescription(), request.getDateTime(), zoneId, - request.getLocation(), - request.getExpiryDate() + request.getLocation() ); Event event = createEventUseCase.createEvent(command); @@ -79,7 +73,6 @@ public class EventController implements EventsApi { response.setTitle(event.getTitle()); response.setDateTime(event.getDateTime()); response.setTimezone(event.getTimezone().getId()); - response.setExpiryDate(event.getExpiryDate()); return ResponseEntity.status(HttpStatus.CREATED).body(response); } @@ -99,8 +92,6 @@ public class EventController implements EventsApi { response.setLocation(event.getLocation()); response.setAttendeeCount( (int) countAttendeesByEventUseCase.countByEvent(eventToken)); - response.setExpired( - event.getExpiryDate().isBefore(LocalDate.now(clock))); return ResponseEntity.ok(response); } diff --git a/backend/src/main/java/de/fete/application/service/EventService.java b/backend/src/main/java/de/fete/application/service/EventService.java index 1f03fa3..70d226d 100644 --- a/backend/src/main/java/de/fete/application/service/EventService.java +++ b/backend/src/main/java/de/fete/application/service/EventService.java @@ -17,6 +17,8 @@ import org.springframework.stereotype.Service; @Service public class EventService implements CreateEventUseCase, GetEventUseCase { + private static final int EXPIRY_DAYS_AFTER_EVENT = 7; + private final EventRepository eventRepository; private final Clock clock; @@ -28,13 +30,7 @@ public class EventService implements CreateEventUseCase, GetEventUseCase { @Override public Event createEvent(CreateEventCommand command) { - if (!command.expiryDate().isAfter(LocalDate.now(clock))) { - throw new ExpiryDateInPastException(command.expiryDate()); - } - - if (!command.expiryDate().isAfter(command.dateTime().toLocalDate())) { - throw new ExpiryDateBeforeEventException(command.expiryDate(), command.dateTime()); - } + LocalDate expiryDate = command.dateTime().toLocalDate().plusDays(EXPIRY_DAYS_AFTER_EVENT); var event = new Event(); event.setEventToken(EventToken.generate()); @@ -44,7 +40,7 @@ public class EventService implements CreateEventUseCase, GetEventUseCase { event.setDateTime(command.dateTime()); event.setTimezone(command.timezone()); event.setLocation(command.location()); - event.setExpiryDate(command.expiryDate()); + event.setExpiryDate(expiryDate); event.setCreatedAt(OffsetDateTime.now(clock)); return eventRepository.save(event); diff --git a/backend/src/main/java/de/fete/domain/model/CreateEventCommand.java b/backend/src/main/java/de/fete/domain/model/CreateEventCommand.java index 331df0c..08351fd 100644 --- a/backend/src/main/java/de/fete/domain/model/CreateEventCommand.java +++ b/backend/src/main/java/de/fete/domain/model/CreateEventCommand.java @@ -10,6 +10,5 @@ public record CreateEventCommand( String description, OffsetDateTime dateTime, ZoneId timezone, - String location, - LocalDate expiryDate + String location ) {} diff --git a/backend/src/main/resources/openapi/api.yaml b/backend/src/main/resources/openapi/api.yaml index 5435fff..9fb1a01 100644 --- a/backend/src/main/resources/openapi/api.yaml +++ b/backend/src/main/resources/openapi/api.yaml @@ -160,7 +160,6 @@ components: - title - dateTime - timezone - - expiryDate properties: title: type: string @@ -181,11 +180,6 @@ components: location: type: string maxLength: 500 - expiryDate: - type: string - format: date - description: Date after which event data is deleted. Must be in the future. - example: "2026-06-15" CreateEventResponse: type: object @@ -195,7 +189,6 @@ components: - title - dateTime - timezone - - expiryDate properties: eventToken: type: string @@ -218,10 +211,6 @@ components: type: string description: IANA timezone of the organizer example: "Europe/Berlin" - expiryDate: - type: string - format: date - example: "2026-06-15" GetEventResponse: type: object @@ -231,7 +220,6 @@ components: - dateTime - timezone - attendeeCount - - expired properties: eventToken: type: string @@ -264,10 +252,6 @@ components: minimum: 0 description: Number of confirmed attendees (attending=true) example: 12 - expired: - type: boolean - description: Whether the event's expiry date has passed - example: false CreateRsvpRequest: type: object diff --git a/backend/src/test/java/de/fete/adapter/in/web/EventControllerIntegrationTest.java b/backend/src/test/java/de/fete/adapter/in/web/EventControllerIntegrationTest.java index 21d93ac..d05292b 100644 --- a/backend/src/test/java/de/fete/adapter/in/web/EventControllerIntegrationTest.java +++ b/backend/src/test/java/de/fete/adapter/in/web/EventControllerIntegrationTest.java @@ -55,8 +55,7 @@ class EventControllerIntegrationTest { .description("Come celebrate!") .dateTime(OffsetDateTime.of(2026, 6, 15, 20, 0, 0, 0, ZoneOffset.ofHours(2))) .timezone("Europe/Berlin") - .location("Berlin") - .expiryDate(LocalDate.of(2026, 6, 16)); + .location("Berlin"); var result = mockMvc.perform(post("/api/events") .contentType(MediaType.APPLICATION_JSON) @@ -67,7 +66,6 @@ class EventControllerIntegrationTest { .andExpect(jsonPath("$.title").value("Birthday Party")) .andExpect(jsonPath("$.timezone").value("Europe/Berlin")) .andExpect(jsonPath("$.dateTime").isNotEmpty()) - .andExpect(jsonPath("$.expiryDate").isNotEmpty()) .andReturn(); var response = objectMapper.readValue( @@ -79,7 +77,7 @@ class EventControllerIntegrationTest { assertThat(persisted.getDescription()).isEqualTo("Come celebrate!"); assertThat(persisted.getTimezone()).isEqualTo("Europe/Berlin"); assertThat(persisted.getLocation()).isEqualTo("Berlin"); - assertThat(persisted.getExpiryDate()).isEqualTo(request.getExpiryDate()); + assertThat(persisted.getExpiryDate()).isEqualTo(LocalDate.of(2026, 6, 22)); assertThat(persisted.getDateTime().toInstant()) .isEqualTo(request.getDateTime().toInstant()); assertThat(persisted.getOrganizerToken()).isNotNull(); @@ -91,8 +89,7 @@ class EventControllerIntegrationTest { var request = new CreateEventRequest() .title("Minimal Event") .dateTime(OffsetDateTime.of(2026, 6, 15, 20, 0, 0, 0, ZoneOffset.ofHours(2))) - .timezone("UTC") - .expiryDate(LocalDate.of(2026, 6, 16)); + .timezone("UTC"); var result = mockMvc.perform(post("/api/events") .contentType(MediaType.APPLICATION_JSON) @@ -119,8 +116,7 @@ class EventControllerIntegrationTest { var request = new CreateEventRequest() .dateTime(OffsetDateTime.of(2026, 6, 15, 20, 0, 0, 0, ZoneOffset.ofHours(2))) - .timezone("Europe/Berlin") - .expiryDate(LocalDate.of(2026, 6, 16)); + .timezone("Europe/Berlin"); mockMvc.perform(post("/api/events") .contentType(MediaType.APPLICATION_JSON) @@ -139,26 +135,6 @@ class EventControllerIntegrationTest { var request = new CreateEventRequest() .title("No Date") - .timezone("Europe/Berlin") - .expiryDate(LocalDate.of(2026, 6, 16)); - - mockMvc.perform(post("/api/events") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(request))) - .andExpect(status().isBadRequest()) - .andExpect(content().contentTypeCompatibleWith("application/problem+json")) - .andExpect(jsonPath("$.fieldErrors").isArray()); - - assertThat(jpaRepository.count()).isEqualTo(countBefore); - } - - @Test - void createEventMissingExpiryDateReturns400() throws Exception { - long countBefore = jpaRepository.count(); - - var request = new CreateEventRequest() - .title("No Expiry") - .dateTime(OffsetDateTime.of(2026, 6, 15, 20, 0, 0, 0, ZoneOffset.ofHours(2))) .timezone("Europe/Berlin"); mockMvc.perform(post("/api/events") @@ -171,93 +147,12 @@ class EventControllerIntegrationTest { assertThat(jpaRepository.count()).isEqualTo(countBefore); } - @Test - void createEventExpiryDateInPastReturns400() throws Exception { - long countBefore = jpaRepository.count(); - - var request = new CreateEventRequest() - .title("Past Expiry") - .dateTime(OffsetDateTime.of(2026, 6, 15, 20, 0, 0, 0, ZoneOffset.ofHours(2))) - .timezone("Europe/Berlin") - .expiryDate(LocalDate.of(2025, 1, 1)); - - mockMvc.perform(post("/api/events") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(request))) - .andExpect(status().isBadRequest()) - .andExpect(content().contentTypeCompatibleWith("application/problem+json")) - .andExpect(jsonPath("$.type").value("urn:problem-type:expiry-date-in-past")); - - assertThat(jpaRepository.count()).isEqualTo(countBefore); - } - - @Test - void createEventExpiryDateTodayReturns400() throws Exception { - long countBefore = jpaRepository.count(); - - var request = new CreateEventRequest() - .title("Today Expiry") - .dateTime(OffsetDateTime.of(2026, 6, 15, 20, 0, 0, 0, ZoneOffset.ofHours(2))) - .timezone("Europe/Berlin") - .expiryDate(LocalDate.now()); - - mockMvc.perform(post("/api/events") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(request))) - .andExpect(status().isBadRequest()) - .andExpect(content().contentTypeCompatibleWith("application/problem+json")) - .andExpect(jsonPath("$.type").value("urn:problem-type:expiry-date-in-past")); - - assertThat(jpaRepository.count()).isEqualTo(countBefore); - } - - @Test - void createEventExpiryDateBeforeEventDateReturns400() throws Exception { - long countBefore = jpaRepository.count(); - - var request = new CreateEventRequest() - .title("Bad Expiry") - .dateTime(OffsetDateTime.of(2026, 6, 15, 20, 0, 0, 0, ZoneOffset.ofHours(2))) - .timezone("Europe/Berlin") - .expiryDate(LocalDate.of(2026, 6, 10)); - - mockMvc.perform(post("/api/events") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(request))) - .andExpect(status().isBadRequest()) - .andExpect(content().contentTypeCompatibleWith("application/problem+json")) - .andExpect(jsonPath("$.type").value("urn:problem-type:expiry-date-before-event")); - - assertThat(jpaRepository.count()).isEqualTo(countBefore); - } - - @Test - void createEventExpiryDateSameAsEventDateReturns400() throws Exception { - long countBefore = jpaRepository.count(); - - var request = new CreateEventRequest() - .title("Same Day Expiry") - .dateTime(OffsetDateTime.of(2026, 6, 15, 20, 0, 0, 0, ZoneOffset.ofHours(2))) - .timezone("Europe/Berlin") - .expiryDate(LocalDate.of(2026, 6, 15)); - - mockMvc.perform(post("/api/events") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(request))) - .andExpect(status().isBadRequest()) - .andExpect(content().contentTypeCompatibleWith("application/problem+json")) - .andExpect(jsonPath("$.type").value("urn:problem-type:expiry-date-before-event")); - - assertThat(jpaRepository.count()).isEqualTo(countBefore); - } - @Test void errorResponseContentTypeIsProblemJson() throws Exception { var request = new CreateEventRequest() .title("") .dateTime(OffsetDateTime.of(2026, 6, 15, 20, 0, 0, 0, ZoneOffset.ofHours(2))) - .timezone("Europe/Berlin") - .expiryDate(LocalDate.of(2026, 6, 16)); + .timezone("Europe/Berlin"); mockMvc.perform(post("/api/events") .contentType(MediaType.APPLICATION_JSON) @@ -273,8 +168,7 @@ class EventControllerIntegrationTest { var request = new CreateEventRequest() .title("Bad TZ") .dateTime(OffsetDateTime.of(2026, 6, 15, 20, 0, 0, 0, ZoneOffset.ofHours(2))) - .timezone("Not/A/Zone") - .expiryDate(LocalDate.of(2026, 6, 16)); + .timezone("Not/A/Zone"); mockMvc.perform(post("/api/events") .contentType(MediaType.APPLICATION_JSON) @@ -302,7 +196,6 @@ class EventControllerIntegrationTest { .andExpect(jsonPath("$.timezone").value("Europe/Berlin")) .andExpect(jsonPath("$.location").value("Central Park")) .andExpect(jsonPath("$.attendeeCount").value(0)) - .andExpect(jsonPath("$.expired").value(false)) .andExpect(jsonPath("$.dateTime").isNotEmpty()); } @@ -327,18 +220,6 @@ class EventControllerIntegrationTest { .andExpect(jsonPath("$.type").value("urn:problem-type:event-not-found")); } - @Test - void getExpiredEventReturnsExpiredTrue() throws Exception { - EventJpaEntity entity = seedEvent( - "Past Event", "It happened", "Europe/Berlin", - "Old Venue", LocalDate.now().minusDays(1)); - - mockMvc.perform(get("/api/events/" + entity.getEventToken())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.title").value("Past Event")) - .andExpect(jsonPath("$.expired").value(true)); - } - // --- RSVP tests --- @Test diff --git a/backend/src/test/java/de/fete/application/service/EventServiceTest.java b/backend/src/test/java/de/fete/application/service/EventServiceTest.java index c3c3055..0225866 100644 --- a/backend/src/test/java/de/fete/application/service/EventServiceTest.java +++ b/backend/src/test/java/de/fete/application/service/EventServiceTest.java @@ -1,7 +1,6 @@ package de.fete.application.service; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -53,8 +52,7 @@ class EventServiceTest { "Come celebrate!", TODAY.plusDays(90).atStartOfDay(ZONE).toOffsetDateTime(), ZONE, - "Berlin", - TODAY.plusDays(120) + "Berlin" ); Event result = eventService.createEvent(command); @@ -75,8 +73,7 @@ class EventServiceTest { var command = new CreateEventCommand( "Test", null, - TODAY.plusDays(10).atStartOfDay(ZONE).toOffsetDateTime(), ZONE, null, - TODAY.plusDays(11) + TODAY.plusDays(10).atStartOfDay(ZONE).toOffsetDateTime(), ZONE, null ); eventService.createEvent(command); @@ -87,86 +84,19 @@ class EventServiceTest { } @Test - void expiryDateTodayThrowsException() { - var command = new CreateEventCommand( - "Test", null, - TODAY.plusDays(10).atStartOfDay(ZONE).toOffsetDateTime(), ZONE, null, - TODAY - ); - - assertThatThrownBy(() -> eventService.createEvent(command)) - .isInstanceOf(ExpiryDateInPastException.class); - } - - @Test - void expiryDateInPastThrowsException() { - var command = new CreateEventCommand( - "Test", null, - TODAY.plusDays(10).atStartOfDay(ZONE).toOffsetDateTime(), ZONE, null, - TODAY.minusDays(5) - ); - - assertThatThrownBy(() -> eventService.createEvent(command)) - .isInstanceOf(ExpiryDateInPastException.class); - } - - @Test - void expiryDateTomorrowSucceeds() { + void expiryDateIsEventDatePlusSevenDays() { when(eventRepository.save(any(Event.class))) .thenAnswer(invocation -> invocation.getArgument(0)); + var eventDate = TODAY.plusDays(10); var command = new CreateEventCommand( "Test", null, - TODAY.plusDays(1).atStartOfDay(ZONE).toOffsetDateTime(), ZONE, null, - TODAY.plusDays(2) + eventDate.atStartOfDay(ZONE).toOffsetDateTime(), ZONE, null ); Event result = eventService.createEvent(command); - 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)); + assertThat(result.getExpiryDate()).isEqualTo(eventDate.plusDays(7)); } // --- GetEventUseCase tests (T004) --- @@ -207,8 +137,7 @@ class EventServiceTest { var command = new CreateEventCommand( "Test", null, TODAY.plusDays(10).atStartOfDay(ZONE).toOffsetDateTime(), - ZoneId.of("America/New_York"), null, - TODAY.plusDays(11) + ZoneId.of("America/New_York"), null ); Event result = eventService.createEvent(command); diff --git a/frontend/e2e/event-create.spec.ts b/frontend/e2e/event-create.spec.ts index aac9ceb..3a073eb 100644 --- a/frontend/e2e/event-create.spec.ts +++ b/frontend/e2e/event-create.spec.ts @@ -9,7 +9,6 @@ test.describe('US-1: Create an event', () => { await expect(page.getByText('Title is required.')).toBeVisible() await expect(page.getByText('Date and time are required.')).toBeVisible() - await expect(page.getByText('Expiry date is required.')).toBeVisible() }) test('creates an event and redirects to event detail page', async ({ page }) => { @@ -19,7 +18,6 @@ test.describe('US-1: Create an event', () => { await page.getByLabel(/description/i).fill('Bring your own drinks') await page.getByLabel(/date/i).first().fill('2026-04-15T18:00') await page.getByLabel(/location/i).fill('Central Park') - await page.getByLabel(/expiry/i).fill('2026-06-15') await page.getByRole('button', { name: /create event/i }).click() @@ -31,7 +29,6 @@ test.describe('US-1: Create an event', () => { await page.getByLabel(/title/i).fill('Summer BBQ') await page.getByLabel(/date/i).first().fill('2026-04-15T18:00') - await page.getByLabel(/expiry/i).fill('2026-06-15') await page.getByRole('button', { name: /create event/i }).click() await expect(page).toHaveURL(/\/events\/.+/) @@ -59,7 +56,6 @@ test.describe('US-1: Create an event', () => { await page.goto('/create') await page.getByLabel(/title/i).fill('Test') await page.getByLabel(/date/i).first().fill('2026-04-15T18:00') - await page.getByLabel(/expiry/i).fill('2026-06-15') await page.getByRole('button', { name: /create event/i }).click() diff --git a/frontend/e2e/event-rsvp.spec.ts b/frontend/e2e/event-rsvp.spec.ts index c954e5b..7d903cd 100644 --- a/frontend/e2e/event-rsvp.spec.ts +++ b/frontend/e2e/event-rsvp.spec.ts @@ -9,7 +9,6 @@ const fullEvent = { timezone: 'Europe/Berlin', location: 'Central Park, NYC', attendeeCount: 12, - expired: false, } test.describe('US1: RSVP submission flow', () => { @@ -170,16 +169,4 @@ test.describe('US1: RSVP submission flow', () => { await expect(page.getByText("You're attending!")).not.toBeVisible() }) - test('does not show RSVP bar on expired event', async ({ page, network }) => { - network.use( - http.get('*/api/events/:token', () => { - return HttpResponse.json({ ...fullEvent, expired: true }) - }), - ) - - await page.goto(`/events/${fullEvent.eventToken}`) - - await expect(page.getByText('This event has ended.')).toBeVisible() - await expect(page.getByRole('button', { name: "I'm attending" })).not.toBeVisible() - }) }) diff --git a/frontend/e2e/event-view.spec.ts b/frontend/e2e/event-view.spec.ts index e25c054..77cead3 100644 --- a/frontend/e2e/event-view.spec.ts +++ b/frontend/e2e/event-view.spec.ts @@ -9,7 +9,6 @@ const fullEvent = { timezone: 'Europe/Berlin', location: 'Central Park, NYC', attendeeCount: 12, - expired: false, } test.describe('US-1: View event details', () => { @@ -52,20 +51,6 @@ test.describe('US-1: View event details', () => { }) }) -test.describe('US-2: View expired event', () => { - test('shows "event has ended" banner for expired event', async ({ page, network }) => { - network.use( - http.get('*/api/events/:token', () => { - return HttpResponse.json({ ...fullEvent, expired: true }) - }), - ) - - await page.goto(`/events/${fullEvent.eventToken}`) - - await expect(page.getByText('This event has ended.')).toBeVisible() - }) -}) - test.describe('US-4: Event not found', () => { test('shows "event not found" for unknown token', async ({ page, network }) => { network.use( diff --git a/frontend/e2e/home-events.spec.ts b/frontend/e2e/home-events.spec.ts index d8a4cfc..13bff36 100644 --- a/frontend/e2e/home-events.spec.ts +++ b/frontend/e2e/home-events.spec.ts @@ -7,7 +7,6 @@ const futureEvent1: StoredEvent = { eventToken: 'future-aaa', title: 'Summer BBQ', dateTime: '2027-06-15T18:00:00Z', - expiryDate: '2027-06-16T00:00:00Z', organizerToken: 'org-token-1', } @@ -15,7 +14,6 @@ const futureEvent2: StoredEvent = { eventToken: 'future-bbb', title: 'Team Meeting', dateTime: '2027-01-10T09:00:00Z', - expiryDate: '2027-01-11T00:00:00Z', rsvpToken: 'rsvp-token-1', rsvpName: 'Alice', } @@ -24,7 +22,6 @@ const pastEvent: StoredEvent = { eventToken: 'past-ccc', title: 'New Year Party', dateTime: '2025-01-01T00:00:00Z', - expiryDate: '2025-01-02T00:00:00Z', } function seedEvents(events: StoredEvent[]): string { @@ -85,7 +82,6 @@ test.describe('US4: Past Events Appear Faded', () => { location: '', timezone: 'UTC', attendeeCount: 0, - expired: true, }) }), ) @@ -199,13 +195,11 @@ test.describe('Temporal Grouping: Section Headers', () => { eventToken: 'today-1', title: 'Today Standup', dateTime: new Date(now.getFullYear(), now.getMonth(), now.getDate(), 18, 0, 0).toISOString(), - expiryDate: '', } const laterEvent: StoredEvent = { eventToken: 'later-1', title: 'Future Conference', dateTime: new Date(now.getFullYear() + 1, 0, 15, 10, 0, 0).toISOString(), - expiryDate: '', } await page.addInitScript(seedEvents([todayEvent, laterEvent, pastEvent])) await page.goto('/') @@ -245,7 +239,6 @@ test.describe('Temporal Grouping: Section Headers', () => { eventToken: 'today-emph', title: 'Emphasis Test', dateTime: new Date(now.getFullYear(), now.getMonth(), now.getDate(), 20, 0, 0).toISOString(), - expiryDate: '', } await page.addInitScript(seedEvents([todayEvent])) await page.goto('/') @@ -262,7 +255,6 @@ test.describe('Temporal Grouping: Date Subheaders', () => { eventToken: 'today-sub', title: 'No Subheader Test', dateTime: new Date(now.getFullYear(), now.getMonth(), now.getDate(), 19, 0, 0).toISOString(), - expiryDate: '', } await page.addInitScript(seedEvents([todayEvent])) await page.goto('/') @@ -355,7 +347,6 @@ test.describe('US1: View My Events', () => { location: '', timezone: 'UTC', attendeeCount: 0, - expired: false, }) }), ) diff --git a/frontend/src/components/__tests__/EventList.spec.ts b/frontend/src/components/__tests__/EventList.spec.ts index 4fab9d9..2a2a865 100644 --- a/frontend/src/components/__tests__/EventList.spec.ts +++ b/frontend/src/components/__tests__/EventList.spec.ts @@ -15,11 +15,11 @@ const router = createRouter({ const NOW = new Date(2026, 2, 11, 12, 0, 0) const mockEvents = [ - { eventToken: 'past-1', title: 'Past Event', dateTime: '2026-03-01T10:00:00', expiryDate: '' }, - { eventToken: 'later-1', title: 'Later Event', dateTime: '2027-06-15T10:00:00', expiryDate: '' }, - { eventToken: 'today-1', title: 'Today Event', dateTime: '2026-03-11T18:00:00', expiryDate: '' }, - { eventToken: 'week-1', title: 'This Week Event', dateTime: '2026-03-13T10:00:00', expiryDate: '' }, - { eventToken: 'nextweek-1', title: 'Next Week Event', dateTime: '2026-03-16T10:00:00', expiryDate: '' }, + { eventToken: 'past-1', title: 'Past Event', dateTime: '2026-03-01T10:00:00' }, + { eventToken: 'later-1', title: 'Later Event', dateTime: '2027-06-15T10:00:00' }, + { eventToken: 'today-1', title: 'Today Event', dateTime: '2026-03-11T18:00:00' }, + { eventToken: 'week-1', title: 'This Week Event', dateTime: '2026-03-13T10:00:00' }, + { eventToken: 'nextweek-1', title: 'Next Week Event', dateTime: '2026-03-16T10:00:00' }, ] vi.mock('../../composables/useEventStorage', () => ({ diff --git a/frontend/src/components/__tests__/useEventGrouping.spec.ts b/frontend/src/components/__tests__/useEventGrouping.spec.ts index 92a7750..ccbceba 100644 --- a/frontend/src/components/__tests__/useEventGrouping.spec.ts +++ b/frontend/src/components/__tests__/useEventGrouping.spec.ts @@ -6,7 +6,6 @@ function makeEvent(overrides: Partial & { dateTime: string }): Stor return { eventToken: `evt-${Math.random().toString(36).slice(2, 8)}`, title: 'Test Event', - expiryDate: '', ...overrides, } } diff --git a/frontend/src/composables/__tests__/useEventStorage.spec.ts b/frontend/src/composables/__tests__/useEventStorage.spec.ts index 0cf740c..0ee521a 100644 --- a/frontend/src/composables/__tests__/useEventStorage.spec.ts +++ b/frontend/src/composables/__tests__/useEventStorage.spec.ts @@ -43,7 +43,6 @@ describe('useEventStorage', () => { organizerToken: 'org-456', title: 'Birthday', dateTime: '2026-06-15T20:00:00+02:00', - expiryDate: '2026-07-15', }) const events = getStoredEvents() @@ -61,7 +60,6 @@ describe('useEventStorage', () => { organizerToken: 'org-456', title: 'Test', dateTime: '2026-06-15T20:00:00+02:00', - expiryDate: '2026-07-15', }) expect(getOrganizerToken('abc-123')).toBe('org-456') @@ -79,14 +77,12 @@ describe('useEventStorage', () => { eventToken: 'event-1', title: 'First', dateTime: '2026-06-15T20:00:00+02:00', - expiryDate: '2026-07-15', }) saveCreatedEvent({ eventToken: 'event-2', title: 'Second', dateTime: '2026-07-15T20:00:00+02:00', - expiryDate: '2026-08-15', }) const events = getStoredEvents() @@ -102,14 +98,12 @@ describe('useEventStorage', () => { eventToken: 'abc-123', title: 'Old Title', dateTime: '2026-06-15T20:00:00+02:00', - expiryDate: '2026-07-15', }) saveCreatedEvent({ eventToken: 'abc-123', title: 'New Title', dateTime: '2026-06-15T20:00:00+02:00', - expiryDate: '2026-07-15', }) const events = getStoredEvents() @@ -124,7 +118,6 @@ describe('useEventStorage', () => { eventToken: 'abc-123', title: 'Birthday', dateTime: '2026-06-15T20:00:00+02:00', - expiryDate: '2026-07-15', }) saveRsvp('abc-123', 'rsvp-token-1', 'Max', 'Birthday', '2026-06-15T20:00:00+02:00') @@ -154,7 +147,6 @@ describe('useEventStorage', () => { eventToken: 'abc-123', title: 'Test', dateTime: '2026-06-15T20:00:00+02:00', - expiryDate: '2026-07-15', }) expect(getRsvp('abc-123')).toBeUndefined() @@ -172,14 +164,12 @@ describe('useEventStorage', () => { eventToken: 'event-1', title: 'First', dateTime: '2026-06-15T20:00:00+02:00', - expiryDate: '2026-07-15', }) saveCreatedEvent({ eventToken: 'event-2', title: 'Second', dateTime: '2026-07-15T20:00:00+02:00', - expiryDate: '2026-08-15', }) removeEvent('event-1') @@ -196,7 +186,6 @@ describe('useEventStorage', () => { eventToken: 'event-1', title: 'First', dateTime: '2026-06-15T20:00:00+02:00', - expiryDate: '2026-07-15', }) removeEvent('nonexistent') @@ -220,8 +209,7 @@ describe('isValidStoredEvent', () => { eventToken: 'abc-123', title: 'Birthday', dateTime: '2026-06-15T20:00:00+02:00', - expiryDate: '2026-07-15', - }), + }), ).toBe(true) }) diff --git a/frontend/src/composables/useEventStorage.ts b/frontend/src/composables/useEventStorage.ts index 99dfb9f..b790f73 100644 --- a/frontend/src/composables/useEventStorage.ts +++ b/frontend/src/composables/useEventStorage.ts @@ -3,7 +3,6 @@ export interface StoredEvent { organizerToken?: string title: string dateTime: string - expiryDate: string rsvpToken?: string rsvpName?: string } @@ -66,7 +65,7 @@ export function useEventStorage() { existing.rsvpToken = rsvpToken existing.rsvpName = rsvpName } else { - events.push({ eventToken, title, dateTime, expiryDate: '', rsvpToken, rsvpName }) + events.push({ eventToken, title, dateTime, rsvpToken, rsvpName }) } writeEvents(events) } diff --git a/frontend/src/views/EventCreateView.vue b/frontend/src/views/EventCreateView.vue index 5d7363e..fcbf49a 100644 --- a/frontend/src/views/EventCreateView.vue +++ b/frontend/src/views/EventCreateView.vue @@ -65,21 +65,6 @@ {{ errors.location }} -
- - - {{ errors.expiryDate }} -
- @@ -90,7 +75,7 @@