@@ -457,6 +457,52 @@ struct MeetingFormViewModelTests {
457457 #expect( viewModel. startDateRange. lowerBound == dateProviderMock. now. addingTimeInterval ( - 86_400 ) )
458458 }
459459
460+ @Test ( " editing an expired non-recurring meeting preserves its dates but prevents submission " )
461+ func editMode_ExpiredNonRecurringMeeting( ) async {
462+ let original = makeEditableMeeting (
463+ start: dateProviderMock. now. addingTimeInterval ( - 3 * 86_400 ) ,
464+ recurrence: nil
465+ )
466+ let viewModel = makeViewModel ( mode: . edit( original) )
467+
468+ #expect( viewModel. startDate == original. start)
469+ #expect( viewModel. startDatePickerRange. contains ( viewModel. startDate) )
470+
471+ await viewModel. submit ( )
472+
473+ #expect( viewModel. hasExpiredStartDateError)
474+ #expect( !viewModel. isLoading)
475+ let rejectedArguments = updateMeetingUseCaseMock
476+ . invokeMeetingMeetingTitleStringStartTimeDateEndTimeDateRecurrenceMeetingRecurrenceParticipantsMeetingMemberMeetingReceivedArguments
477+ #expect( rejectedArguments == nil )
478+ }
479+
480+ @Test ( " saving rechecks the current window and allows retry after correcting the start time " )
481+ func submit_EditModeStartDateExpiresWhileEditing( ) async {
482+ let original = makeEditableMeeting ( start: dateProviderMock. now. addingTimeInterval ( - 86_400 ) )
483+ let viewModel = makeViewModel ( mode: . edit( original) )
484+ dateProviderMock. now = dateProviderMock. now. addingTimeInterval ( 1 )
485+
486+ #expect( viewModel. startDatePickerRange. contains ( viewModel. startDate) )
487+ await viewModel. submit ( )
488+
489+ #expect( viewModel. hasExpiredStartDateError)
490+ let rejectedArguments = updateMeetingUseCaseMock
491+ . invokeMeetingMeetingTitleStringStartTimeDateEndTimeDateRecurrenceMeetingRecurrenceParticipantsMeetingMemberMeetingReceivedArguments
492+ #expect( rejectedArguments == nil )
493+
494+ viewModel. startDate = dateProviderMock. now
495+ updateMeetingUseCaseMock
496+ . invokeMeetingMeetingTitleStringStartTimeDateEndTimeDateRecurrenceMeetingRecurrenceParticipantsMeetingMemberMeetingReturnValue =
497+ meeting
498+ await viewModel. submit ( )
499+
500+ #expect( !viewModel. hasExpiredStartDateError)
501+ let savedArguments = updateMeetingUseCaseMock
502+ . invokeMeetingMeetingTitleStringStartTimeDateEndTimeDateRecurrenceMeetingRecurrenceParticipantsMeetingMemberMeetingReceivedArguments
503+ #expect( savedArguments? . startTime == dateProviderMock. now)
504+ }
505+
460506 @Test ( " editing preserves and submits recurring start times within 24 hours " , arguments: [ 0.0 , 3600.0 , 86_400.0 ] )
461507 func editMode_RecentRecurringMeetingPreservesDates( secondsAgo: TimeInterval ) async throws {
462508 let original = makeEditableMeeting ( start: dateProviderMock. now. addingTimeInterval ( - secondsAgo) )
0 commit comments