diff --git a/app/lib/timetable/timetable_add_event/src/timetable_add_event_dialog_controller.dart b/app/lib/timetable/timetable_add_event/src/timetable_add_event_dialog_controller.dart index dffccf99a..9a640be4c 100644 --- a/app/lib/timetable/timetable_add_event/src/timetable_add_event_dialog_controller.dart +++ b/app/lib/timetable/timetable_add_event/src/timetable_add_event_dialog_controller.dart @@ -66,12 +66,20 @@ class AddEventDialogController extends ChangeNotifier { notifyListeners(); } + bool showEndTimeNotAfterStartTimeError = false; + void maybeClearEndTimeNotAfterStartTimeError() { + if (endTime.isAfter(startTime)) { + showEndTimeNotAfterStartTimeError = false; + } + } + Time _startTime = Time(hour: 11, minute: 00); Time get startTime => _startTime; set startTime(Time value) { _startTime = value; + maybeClearEndTimeNotAfterStartTimeError(); notifyListeners(); } @@ -81,6 +89,7 @@ class AddEventDialogController extends ChangeNotifier { set endTime(Time value) { _endTime = value; + maybeClearEndTimeNotAfterStartTimeError(); notifyListeners(); } @@ -94,6 +103,10 @@ class AddEventDialogController extends ChangeNotifier { showEmptyCourseError = true; hasError = true; } + if (!endTime.isAfter(startTime)) { + showEndTimeNotAfterStartTimeError = true; + hasError = true; + } if (hasError) { notifyListeners(); return false; diff --git a/app/lib/timetable/timetable_add_event/timetable_add_event_dialog.dart b/app/lib/timetable/timetable_add_event/timetable_add_event_dialog.dart index 69e1b2388..a6eea8118 100644 --- a/app/lib/timetable/timetable_add_event/timetable_add_event_dialog.dart +++ b/app/lib/timetable/timetable_add_event/timetable_add_event_dialog.dart @@ -396,7 +396,7 @@ class _DateAndTimePicker extends StatelessWidget { timeFieldKey: EventDialogKeys.endTimeField, time: controller.endTime, showEndNotAfterBeginningError: - !controller.endTime.isAfter(controller.startTime), + controller.showEndTimeNotAfterStartTimeError, isDatePickingEnabled: false, onTimeChanged: (newTime) { controller.endTime = newTime; diff --git a/app/test/timetable/timetable_dialog_test.dart b/app/test/timetable/timetable_dialog_test.dart index 74c1cc635..7c307afa5 100644 --- a/app/test/timetable/timetable_dialog_test.dart +++ b/app/test/timetable/timetable_dialog_test.dart @@ -215,22 +215,55 @@ void main() { expect(find.text(EventDialogErrorStrings.emptyCourse), findsNothing); }); - testWidgets('shows error message if end time is not after start time', + testWidgets( + 'shows "end time not after start time" error message when save was pressed', (tester) async { final dt = createDialogTester(tester); await dt.pumpDialog(isExam: false); await dt.selectStartTime(const TimeOfDay(hour: 13, minute: 15)); await dt.selectEndTime(const TimeOfDay(hour: 13, minute: 15)); + await dt.tapSaveButton(); expect(find.text(EventDialogErrorStrings.endTimeMustBeAfterStartTime), findsOneWidget); + await dt.tapSaveButton(); await dt.selectEndTime(const TimeOfDay(hour: 12, minute: 00)); expect(find.text(EventDialogErrorStrings.endTimeMustBeAfterStartTime), findsOneWidget); }); + testWidgets( + 'doesnt show "end time not after start time" error message when save was not pressed', + (tester) async { + final dt = createDialogTester(tester); + await dt.pumpDialog(isExam: false); + + await dt.selectStartTime(const TimeOfDay(hour: 13, minute: 15)); + await dt.selectEndTime(const TimeOfDay(hour: 13, minute: 15)); + expect(find.text(EventDialogErrorStrings.endTimeMustBeAfterStartTime), + findsNothing); + + await dt.selectEndTime(const TimeOfDay(hour: 12, minute: 00)); + expect(find.text(EventDialogErrorStrings.endTimeMustBeAfterStartTime), + findsNothing); + }); + + testWidgets( + 'removes "end time not after start time" error message when the error is fixed by the user', + (tester) async { + final dt = createDialogTester(tester); + await dt.pumpDialog(isExam: false); - testWidgets('doesnt shows error message if end time after start time', + await dt.selectStartTime(const TimeOfDay(hour: 13, minute: 15)); + await dt.selectEndTime(const TimeOfDay(hour: 10, minute: 30)); + await dt.tapSaveButton(); + await dt.selectEndTime(const TimeOfDay(hour: 15, minute: 30)); + expect(find.text(EventDialogErrorStrings.endTimeMustBeAfterStartTime), + findsNothing); + }); + + testWidgets( + 'doesnt show "end time not after start time" error message when end time is after start time', (tester) async { final dt = createDialogTester(tester); await dt.pumpDialog(isExam: false); diff --git a/app/test_goldens/timetable/timetable_dialog/timetable_dialog_test.dart b/app/test_goldens/timetable/timetable_dialog/timetable_dialog_test.dart index 206f815cc..334f26fe0 100644 --- a/app/test_goldens/timetable/timetable_dialog/timetable_dialog_test.dart +++ b/app/test_goldens/timetable/timetable_dialog/timetable_dialog_test.dart @@ -107,11 +107,11 @@ void main() { theme: testConfig.theme.data, ); - // Set end time before start time to trigger the error message. + // Set end time before start time. await dt.selectStartTime(const TimeOfDay(hour: 12, minute: 0)); await dt.selectEndTime(const TimeOfDay(hour: 10, minute: 0)); - // Triggers empty title and no course chosen error messages. + // Triggers "empty title", "no course chosen" and "end time is before start time" error messages. await dt.tapSaveButton(); await multiScreenGolden(