From e81717b62e3ce6539d5d76a55b57b5116f398ff5 Mon Sep 17 00:00:00 2001 From: Cohen Adair Date: Tue, 27 Jun 2023 18:36:28 -0500 Subject: [PATCH] #836: Add auto-set checkbox to SaveTripPage --- mobile/lib/i18n/english_strings.dart | 15 +- mobile/lib/i18n/strings.dart | 5 + mobile/lib/pages/save_trip_page.dart | 80 +++--- mobile/lib/user_preference_manager.dart | 7 + mobile/test/mocks/mocks.mocks.dart | 14 + mobile/test/pages/save_trip_page_test.dart | 303 +++++++-------------- 6 files changed, 167 insertions(+), 257 deletions(-) diff --git a/mobile/lib/i18n/english_strings.dart b/mobile/lib/i18n/english_strings.dart index e037f7d6..085d24f9 100644 --- a/mobile/lib/i18n/english_strings.dart +++ b/mobile/lib/i18n/english_strings.dart @@ -367,6 +367,9 @@ Map> get englishStrings => { "Are you sure you want to delete trip %s? This cannot be undone.", "saveTripPage_editTitle": "Edit Trip", "saveTripPage_newTitle": "New Trip", + "saveTripPage_autoSetTitle": "Auto-set Fields", + "saveTripPage_autoSetDescription": + "Automatically set applicable fields when catches are selected.", "saveTripPage_startDate": "Start Date", "saveTripPage_startTime": "Start Time", "saveTripPage_startDateTime": "Start Date and Time", @@ -1128,10 +1131,14 @@ Map> get englishStrings => { "changeLog_2.4.0_4": "Added \"Sunny\" as a sky condition", "changeLog_2.4.0_5": "Note fields can now include blank lines", "changeLog_2.4.0_6": "Note fields are no longer truncated to 4 lines", - "changeLog_2.4.1_1": "Fixed a crash while fetching atmosphere and weather data", + "changeLog_2.4.1_1": + "Fixed a crash while fetching atmosphere and weather data", "changeLog_2.4.1_2": "Fixed a rare crash while adding a catch", - "changeLog_2.4.1_3": "Fixed an issue where the fishing spot was reset while adding a catch", - "changeLog_2.4.1_4": "A trip's catches per species, bait, and fishing spot will now only update after selecting catches if they weren't already set", - "changeLog_2.4.1_5": "Several general stability improvements and crash fixes", + "changeLog_2.4.1_3": + "Fixed an issue where the fishing spot was reset while adding a catch", + "changeLog_2.4.1_4": + "When adding trips, you are now given the option to override existing input fields with data from selected catches", + "changeLog_2.4.1_5": + "Several general stability improvements and crash fixes", }, }; diff --git a/mobile/lib/i18n/strings.dart b/mobile/lib/i18n/strings.dart index c0ff8263..d23b50dc 100644 --- a/mobile/lib/i18n/strings.dart +++ b/mobile/lib/i18n/strings.dart @@ -207,6 +207,11 @@ class Strings { String get saveTripPageNewTitle => _string("saveTripPage_newTitle"); + String get saveTripPageAutoSetTitle => _string("saveTripPage_autoSetTitle"); + + String get saveTripPageAutoSetDescription => + _string("saveTripPage_autoSetDescription"); + String get saveTripPageStartDate => _string("saveTripPage_startDate"); String get saveTripPageStartTime => _string("saveTripPage_startTime"); diff --git a/mobile/lib/pages/save_trip_page.dart b/mobile/lib/pages/save_trip_page.dart index fe5ef590..2fc45d70 100644 --- a/mobile/lib/pages/save_trip_page.dart +++ b/mobile/lib/pages/save_trip_page.dart @@ -82,12 +82,6 @@ class SaveTripPageState extends State { final Set _catchImages = {}; List _customEntityValues = []; - bool _userDidChangeStartTime = false; - bool _userDidChangeEndTime = false; - bool _userDidChangeCatchesPerFishingSpot = false; - bool _userDidChangeCatchesPerAngler = false; - bool _userDidChangeCatchesPerBait = false; - bool _userDidChangeCatchesPerSpecies = false; Trip? get _oldTrip => widget.oldTrip; @@ -293,6 +287,7 @@ class SaveTripPageState extends State { title: Text(_isEditing ? Strings.of(context).saveTripPageEditTitle : Strings.of(context).saveTripPageNewTitle), + header: _buildAutoPopulateFieldsHeader(), padding: insetsZero, runSpacing: 0, fields: _fields, @@ -306,6 +301,15 @@ class SaveTripPageState extends State { ); } + Widget _buildAutoPopulateFieldsHeader() { + return CheckboxInput( + label: Strings.of(context).saveTripPageAutoSetTitle, + description: Strings.of(context).saveTripPageAutoSetDescription, + value: _userPreferenceManager.autoSetTripFields, + onChanged: (value) => _userPreferenceManager.setAutoSetTripFields(value), + ); + } + Widget _buildField(Id id) { if (id == _idStartTimestamp) { return _buildStartTime(); @@ -347,8 +351,8 @@ class SaveTripPageState extends State { child: _DateTimeAllDayPicker( controller: _startTimestampController, dateLabel: Strings.of(context).saveTripPageStartDate, - timeLabel: Strings.of(context).saveTripPageStartDate, - onChange: () => setState(() => _userDidChangeStartTime = true), + timeLabel: Strings.of(context).saveTripPageStartTime, + onChange: () => setState(() {}), ), ); } @@ -359,8 +363,8 @@ class SaveTripPageState extends State { child: _DateTimeAllDayPicker( controller: _endTimestampController, dateLabel: Strings.of(context).saveTripPageEndDate, - timeLabel: Strings.of(context).saveTripPageEndDate, - onChange: () => setState(() => _userDidChangeEndTime = true), + timeLabel: Strings.of(context).saveTripPageEndTime, + onChange: () => setState(() {}), ), ); } @@ -402,7 +406,6 @@ class SaveTripPageState extends State { delegate: FishingSpotQuantityPickerInputDelegate( manager: _fishingSpotManager, controller: _fishingSpotCatchesController, - didUpdateValue: () => _userDidChangeCatchesPerFishingSpot = true, ), ); } @@ -414,7 +417,6 @@ class SaveTripPageState extends State { manager: _anglerManager, controller: _anglerCatchesController, listPageBuilder: (settings) => AnglerListPage(pickerSettings: settings), - didUpdateValue: () => _userDidChangeCatchesPerAngler = true, ), ); } @@ -425,7 +427,6 @@ class SaveTripPageState extends State { delegate: BaitQuantityPickerInputDelegate( baitManager: _baitManager, controller: _baitCatchesController, - didUpdateValue: () => _userDidChangeCatchesPerBait = true, ), ); } @@ -438,7 +439,6 @@ class SaveTripPageState extends State { controller: _speciesCatchesController, listPageBuilder: (settings) => SpeciesListPage(pickerSettings: settings), - didUpdateValue: () => _userDidChangeCatchesPerSpecies = true, ), ); } @@ -544,22 +544,22 @@ class SaveTripPageState extends State { /// the time if "All day" checkboxes are checked. This will _not_ overwrite any /// changes the user made to the time. void _updateTimestampControllersIfNeeded(List catches) { - if (!_userDidChangeStartTime) { - var startDateTime = catches.last.dateTime(context); - if (_startTimestampController.isMidnight) { - _startTimestampController.date = startDateTime; - } else { - _startTimestampController.value = startDateTime; - } + if (!_userPreferenceManager.autoSetTripFields) { + return; } - if (!_userDidChangeEndTime) { - var endDateTime = catches.first.dateTime(context); - if (_endTimestampController.isMidnight) { - _endTimestampController.date = endDateTime; - } else { - _endTimestampController.value = endDateTime; - } + var startDateTime = catches.last.dateTime(context); + if (_startTimestampController.isMidnight) { + _startTimestampController.date = startDateTime; + } else { + _startTimestampController.value = startDateTime; + } + + var endDateTime = catches.first.dateTime(context); + if (_endTimestampController.isMidnight) { + _endTimestampController.date = endDateTime; + } else { + _endTimestampController.value = endDateTime; } } @@ -567,6 +567,10 @@ class SaveTripPageState extends State { /// This will _not_ overwrite any changes the user made to the catches per /// entity values. void _updateCatchesPerEntityControllersIfNeeded(List catches) { + if (!_userPreferenceManager.autoSetTripFields) { + return; + } + var catchesPerAngler = []; var catchesPerBait = []; var catchesPerFishingSpot = []; @@ -591,22 +595,10 @@ class SaveTripPageState extends State { } } - // Only update fields if the user hasn't already changed them. - if (!_userDidChangeCatchesPerAngler) { - _anglerCatchesController.value = catchesPerAngler.toSet(); - } - - if (!_userDidChangeCatchesPerBait) { - _baitCatchesController.value = catchesPerBait.toSet(); - } - - if (!_userDidChangeCatchesPerFishingSpot) { - _fishingSpotCatchesController.value = catchesPerFishingSpot.toSet(); - } - - if (!_userDidChangeCatchesPerSpecies) { - _speciesCatchesController.value = catchesPerSpecies.toSet(); - } + _anglerCatchesController.value = catchesPerAngler.toSet(); + _baitCatchesController.value = catchesPerBait.toSet(); + _fishingSpotCatchesController.value = catchesPerFishingSpot.toSet(); + _speciesCatchesController.value = catchesPerSpecies.toSet(); } /// Adds body of water values based on the given catches. This will add to diff --git a/mobile/lib/user_preference_manager.dart b/mobile/lib/user_preference_manager.dart index 63e9fbd5..1f587f8c 100644 --- a/mobile/lib/user_preference_manager.dart +++ b/mobile/lib/user_preference_manager.dart @@ -17,6 +17,7 @@ class UserPreferenceManager extends PreferenceManager { static const _keyBaitVariantFieldIds = "bait_variant_field_ids"; static const _keyCatchFieldIds = "catch_field_ids"; static const _keyTripFieldIds = "trip_field_ids"; + static const _keyTripAutoSetFields = "trip_auto_set_fields"; static const _keyCatchLengthSystem = "catch_length_system"; static const _keyCatchWeightSystem = "catch_weight_system"; static const _keyWaterDepthSystem = "water_depth_system"; @@ -74,6 +75,12 @@ class UserPreferenceManager extends PreferenceManager { List get tripFieldIds => idList(_keyTripFieldIds); + // ignore: avoid_positional_boolean_parameters + Future setAutoSetTripFields(bool autoFetch) => + put(_keyTripAutoSetFields, autoFetch); + + bool get autoSetTripFields => preferences[_keyTripAutoSetFields] ?? true; + Future setCatchLengthSystem(MeasurementSystem? system) => put(_keyCatchLengthSystem, system?.value); diff --git a/mobile/test/mocks/mocks.mocks.dart b/mobile/test/mocks/mocks.mocks.dart index d334fb85..ed477009 100644 --- a/mobile/test/mocks/mocks.mocks.dart +++ b/mobile/test/mocks/mocks.mocks.dart @@ -9961,6 +9961,11 @@ class MockUserPreferenceManager extends _i1.Mock returnValue: <_i5.Id>[], ) as List<_i5.Id>); @override + bool get autoSetTripFields => (super.noSuchMethod( + Invocation.getter(#autoSetTripFields), + returnValue: false, + ) as bool); + @override _i5.MeasurementSystem get catchLengthSystem => (super.noSuchMethod( Invocation.getter(#catchLengthSystem), returnValue: _FakeMeasurementSystem_90( @@ -10200,6 +10205,15 @@ class MockUserPreferenceManager extends _i1.Mock returnValueForMissingStub: _i2.Future.value(), ) as _i2.Future); @override + _i2.Future setAutoSetTripFields(bool? autoFetch) => (super.noSuchMethod( + Invocation.method( + #setAutoSetTripFields, + [autoFetch], + ), + returnValue: _i2.Future.value(), + returnValueForMissingStub: _i2.Future.value(), + ) as _i2.Future); + @override _i2.Future setCatchLengthSystem(_i5.MeasurementSystem? system) => (super.noSuchMethod( Invocation.method( diff --git a/mobile/test/pages/save_trip_page_test.dart b/mobile/test/pages/save_trip_page_test.dart index b49d0a52..eeb9f046 100644 --- a/mobile/test/pages/save_trip_page_test.dart +++ b/mobile/test/pages/save_trip_page_test.dart @@ -288,6 +288,7 @@ void main() { .thenReturn(Unit.inch_of_mercury); when(appManager.userPreferenceManager.windSpeedSystem) .thenReturn(MeasurementSystem.metric); + when(appManager.userPreferenceManager.autoSetTripFields).thenReturn(true); appManager.stubCurrentTime(dateTime(2021, 2, 1, 10, 30)); @@ -473,10 +474,10 @@ void main() { // Verify "All Day" checkboxes are checked. var checkboxes = - tester.widgetList(find.byType(PaddedCheckbox)); - expect(checkboxes.length, 2); - expect(checkboxes.first.checked, isTrue); - expect(checkboxes.last.checked, isTrue); + tester.widgetList(find.byType(PaddedCheckbox)).toList(); + expect(checkboxes.length, 3); // First checkbox is for auto-set fields. + expect(checkboxes[1].checked, isTrue); + expect(checkboxes[2].checked, isTrue); }); testWidgets("Checking All Day sets time of day to 0", (tester) async { @@ -487,8 +488,8 @@ void main() { appManager: appManager, )); - await tapAndSettle(tester, find.byType(PaddedCheckbox).first); - await tapAndSettle(tester, find.byType(PaddedCheckbox).last); + await tapAndSettle(tester, find.byType(PaddedCheckbox).at(1)); + await tapAndSettle(tester, find.byType(PaddedCheckbox).at(2)); await tapAndSettle(tester, find.text("SAVE")); var result = verify(appManager.tripManager.addOrUpdate( @@ -558,7 +559,8 @@ void main() { expect(trip.catchesPerBait.isEmpty, isTrue); }); - testWidgets("Per entity updated when catches are picked", (tester) async { + testWidgets("Per entity not automatically updated if auto-set is off", + (tester) async { when(appManager.anglerManager.entityExists(any)).thenReturn(true); when(appManager.anglerManager.entity(any)) .thenReturn(Angler(id: randomId())); @@ -585,6 +587,7 @@ void main() { // Empty result shows all fields. when(appManager.userPreferenceManager.tripFieldIds).thenReturn([]); + when(appManager.userPreferenceManager.autoSetTripFields).thenReturn(false); var catches = [ Catch( @@ -620,238 +623,78 @@ void main() { result.called(1); var trip = result.captured.first as Trip; - expect(trip.catchesPerAngler.isNotEmpty, isTrue); - expect(trip.catchesPerFishingSpot.isNotEmpty, isTrue); - expect(trip.catchesPerSpecies.isNotEmpty, isTrue); - expect(trip.catchesPerBait.isNotEmpty, isTrue); + expect(trip.catchesPerAngler.isEmpty, isTrue); + expect(trip.catchesPerFishingSpot.isEmpty, isTrue); + expect(trip.catchesPerSpecies.isEmpty, isTrue); + expect(trip.catchesPerBait.isEmpty, isTrue); }); - testWidgets("Per angler not automatically updated if set by user", - (tester) async { - var angler = Angler( - name: "Me", - id: randomId(), - ); + testWidgets("Per entity updated when catches are picked", (tester) async { when(appManager.anglerManager.entityExists(any)).thenReturn(true); - when(appManager.anglerManager.entity(any)).thenReturn(angler); + when(appManager.anglerManager.entity(any)) + .thenReturn(Angler(id: randomId())); when(appManager.anglerManager.displayName(any, any)).thenReturn("Me"); - when(appManager.anglerManager.listSortedByDisplayName(any)) - .thenReturn([angler]); - when(appManager.anglerManager.id(any)).thenReturn(angler.id); - when(appManager.catchManager.catches( - any, - filter: anyNamed("filter"), - opt: anyNamed("opt"), - )).thenReturn([ - Catch( - id: randomId(), - timestamp: Int64(dateTime(2020, 1, 1, 5).millisecondsSinceEpoch), - anglerId: randomId(), - ), - ]); - - await tester.pumpWidget(Testable( - (_) => const SaveTripPage(), - appManager: appManager, - )); - - // Pick an angler so quantity text fields are shown. - await ensureVisibleAndSettle(tester, find.text("Catches Per Angler")); - await tapAndSettle(tester, find.text("Catches Per Angler")); - await tapAndSettle(tester, find.text("Me")); - await tapAndSettle(tester, find.byType(PaddedCheckbox).first); - await tapAndSettle(tester, find.byType(BackButton)); - - // Enter a quantity value. - await enterTextFieldAndSettle(tester, "0", "10"); - expect(find.text("10"), findsOneWidget); - - // Select a catch to trigger auto updates. - await ensureVisibleAndSettle(tester, find.text("No catches")); - await tapAndSettle(tester, find.text("No catches")); - await tapAndSettle(tester, find.byType(PaddedCheckbox).first); - await tapAndSettle(tester, find.byType(BackButton)); - - // Verify quantity for "Me" didn't change. - expect(find.text("10"), findsOneWidget); - expect(find.text("1"), findsNothing); - }); - - testWidgets("Per bait not automatically updated if set by user", - (tester) async { - var bait = Bait( - id: randomId(), - name: "Bait", - ); when(appManager.baitManager.entityExists(any)).thenReturn(true); - when(appManager.baitManager.entity(any)).thenReturn(bait); + when(appManager.baitManager.entity(any)).thenReturn(Bait(id: randomId())); when(appManager.baitManager.displayName(any, any)).thenReturn("Bait"); - when(appManager.baitManager.attachmentDisplayValue(any, any)) - .thenReturn("Bait"); - when(appManager.baitManager.listSortedByDisplayName(any)) - .thenReturn([bait]); - when(appManager.baitManager.filteredList(any, any)).thenReturn([bait]); - when(appManager.baitManager.attachmentList()) - .thenReturn([BaitAttachment(baitId: bait.id)]); - when(appManager.baitManager.id(any)).thenReturn(bait.id); - when(appManager.baitManager.numberOfCatchQuantities(any)).thenReturn(0); - when(appManager.baitCategoryManager.listSortedByDisplayName(any)) - .thenReturn([]); - - when(appManager.catchManager.catches( - any, - filter: anyNamed("filter"), - opt: anyNamed("opt"), - )).thenReturn([ - Catch( - id: randomId(), - timestamp: Int64(dateTime(2020, 1, 1, 5).millisecondsSinceEpoch), - baits: [ - BaitAttachment(baitId: bait.id), - ], - ), - ]); - - await tester.pumpWidget(Testable( - (_) => const SaveTripPage(), - appManager: appManager, - )); - - // Pick an angler so quantity text fields are shown. - await ensureVisibleAndSettle(tester, find.text("Catches Per Bait")); - await tapAndSettle(tester, find.text("Catches Per Bait")); - await tapAndSettle(tester, find.text("Bait")); - await tapAndSettle(tester, find.byType(PaddedCheckbox).first); - await tapAndSettle(tester, find.byType(BackButton)); - // Enter a quantity value. - await enterTextFieldAndSettle(tester, "0", "10"); - expect(find.text("10"), findsOneWidget); - - // Select a catch to trigger auto updates. - await ensureVisibleAndSettle(tester, find.text("No catches")); - await tapAndSettle(tester, find.text("No catches")); - await tapAndSettle(tester, find.byType(PaddedCheckbox).first); - await tapAndSettle(tester, find.byType(BackButton)); - - // Verify quantity for "Bait" didn't change. - expect(find.text("10"), findsOneWidget); - expect(find.text("1"), findsNothing); - }); - - testWidgets("Per fishing spot not automatically updated if set by user", - (tester) async { - var spot = FishingSpot( - id: randomId(), - name: "Spot", - ); when(appManager.fishingSpotManager.entityExists(any)).thenReturn(true); - when(appManager.fishingSpotManager.entity(any)).thenReturn(spot); + when(appManager.fishingSpotManager.entity(any)) + .thenReturn(FishingSpot(id: randomId())); when(appManager.fishingSpotManager.displayName( any, any, useLatLngFallback: anyNamed("useLatLngFallback"), - includeLatLngLabels: anyNamed("includeLatLngLabels"), includeBodyOfWater: anyNamed("includeBodyOfWater"), )).thenReturn("Spot"); - when(appManager.fishingSpotManager.listSortedByDisplayName(any)) - .thenReturn([spot]); - when(appManager.fishingSpotManager.filteredList(any, any)) - .thenReturn([spot]); - when(appManager.fishingSpotManager.id(any)).thenReturn(spot.id); - when(appManager.bodyOfWaterManager.listSortedByDisplayName(any)) - .thenReturn([]); - when(appManager.catchManager.catches( - any, - filter: anyNamed("filter"), - opt: anyNamed("opt"), - )).thenReturn([ + when(appManager.speciesManager.entityExists(any)).thenReturn(true); + when(appManager.speciesManager.entity(any)) + .thenReturn(Species(id: randomId())); + when(appManager.speciesManager.displayName(any, any)).thenReturn("Species"); + + // Empty result shows all fields. + when(appManager.userPreferenceManager.tripFieldIds).thenReturn([]); + + var catches = [ Catch( id: randomId(), timestamp: Int64(dateTime(2020, 1, 1, 5).millisecondsSinceEpoch), + anglerId: randomId(), fishingSpotId: randomId(), + speciesId: randomId(), + baits: [BaitAttachment(baitId: randomId())], ), - ]); - - await tester.pumpWidget(Testable( - (_) => const SaveTripPage(), - appManager: appManager, - )); - - // Pick an angler so quantity text fields are shown. - await ensureVisibleAndSettle(tester, find.text("Catches Per Fishing Spot")); - await tapAndSettle(tester, find.text("Catches Per Fishing Spot")); - await tapAndSettle(tester, find.text("Spot")); - await tapAndSettle(tester, find.byType(PaddedCheckbox).first); - await tapAndSettle(tester, find.byType(BackButton)); - - // Enter a quantity value. - await enterTextFieldAndSettle(tester, "0", "10"); - expect(find.text("10"), findsOneWidget); - - // Select a catch to trigger auto updates. - await ensureVisibleAndSettle(tester, find.text("No catches")); - await tapAndSettle(tester, find.text("No catches")); - await tapAndSettle(tester, find.byType(PaddedCheckbox).first); - await tapAndSettle(tester, find.byType(BackButton)); - - // Verify quantity for "Spot" didn't change. - expect(find.text("10"), findsOneWidget); - expect(find.text("1"), findsNothing); - }); - - testWidgets("Per species spot not automatically updated if set by user", - (tester) async { - var species = Species( - name: "Trout", - id: randomId(), - ); - when(appManager.speciesManager.entityExists(any)).thenReturn(true); - when(appManager.speciesManager.entity(any)).thenReturn(species); - when(appManager.speciesManager.displayName(any, any)).thenReturn("Trout"); - when(appManager.speciesManager.listSortedByDisplayName(any)) - .thenReturn([species]); - when(appManager.speciesManager.id(any)).thenReturn(species.id); - + ]; when(appManager.catchManager.catches( any, filter: anyNamed("filter"), opt: anyNamed("opt"), - )).thenReturn([ - Catch( - id: randomId(), - timestamp: Int64(dateTime(2020, 1, 1, 5).millisecondsSinceEpoch), - speciesId: randomId(), - ), - ]); + )).thenReturn(catches); await tester.pumpWidget(Testable( (_) => const SaveTripPage(), appManager: appManager, )); - // Pick an angler so quantity text fields are shown. - await ensureVisibleAndSettle(tester, find.text("Catches Per Species")); - await tapAndSettle(tester, find.text("Catches Per Species")); - await tapAndSettle(tester, find.text("Trout")); - await tapAndSettle(tester, find.byType(PaddedCheckbox).first); - await tapAndSettle(tester, find.byType(BackButton)); - - // Enter a quantity value. - await enterTextFieldAndSettle(tester, "0", "10"); - expect(find.text("10"), findsOneWidget); - // Select a catch to trigger auto updates. - await ensureVisibleAndSettle(tester, find.text("No catches")); await tapAndSettle(tester, find.text("No catches")); await tapAndSettle(tester, find.byType(PaddedCheckbox).first); await tapAndSettle(tester, find.byType(BackButton)); - // Verify quantity for "Trout" didn't change. - expect(find.text("10"), findsOneWidget); - expect(find.text("1"), findsNothing); + // Save changes, and verify per entities are set. + await tapAndSettle(tester, find.text("SAVE")); + + var result = verify(appManager.tripManager + .addOrUpdate(captureAny, imageFiles: anyNamed("imageFiles"))); + result.called(1); + + var trip = result.captured.first as Trip; + expect(trip.catchesPerAngler.isNotEmpty, isTrue); + expect(trip.catchesPerFishingSpot.isNotEmpty, isTrue); + expect(trip.catchesPerSpecies.isNotEmpty, isTrue); + expect(trip.catchesPerBait.isNotEmpty, isTrue); }); testWidgets("Bodies of water not updated on picked if not showing", @@ -1205,30 +1048,36 @@ void main() { expect(find.text("3:00 PM"), findsOneWidget); }); - testWidgets("Time is not updated if catches picked is empty", (tester) async { + testWidgets("Time is not updated when auto-set is off", (tester) async { appManager.stubCurrentTime(dateTime(2020, 1, 1, 3, 30)); var catches = [ Catch( id: randomId(), timestamp: Int64(dateTime(2020, 1, 1, 5).millisecondsSinceEpoch), + timeZone: defaultTimeZone, ), Catch( id: randomId(), timestamp: Int64(dateTime(2020, 2, 1, 8).millisecondsSinceEpoch), + timeZone: defaultTimeZone, ), Catch( id: randomId(), timestamp: Int64(dateTime(2020, 3, 1, 15).millisecondsSinceEpoch), + timeZone: defaultTimeZone, ), ]; when(appManager.catchManager.catches( any, filter: anyNamed("filter"), + opt: anyNamed("opt"), )).thenReturn(catches); when(appManager.catchManager.id(any)) .thenAnswer((invocation) => invocation.positionalArguments.first.id); + when(appManager.userPreferenceManager.autoSetTripFields).thenReturn(false); + await tester.pumpWidget(Testable( (_) => const SaveTripPage(), appManager: appManager, @@ -1239,15 +1088,51 @@ void main() { await ensureVisibleAndSettle(tester, find.text("No catches")); await tapAndSettle(tester, find.text("No catches")); + await tapAndSettle(tester, findManageableListItemCheckbox(tester, "All")); await tapAndSettle(tester, find.byType(BackButton)); expect(find.text("Jan 1, 2020"), findsNWidgets(2)); expect(find.text("3:30 AM"), findsNWidgets(2)); }); - testWidgets("Time is not updated when catches are picked if set by the user", - (tester) async { - // TODO + testWidgets("Time is not updated if catches picked is empty", (tester) async { + appManager.stubCurrentTime(dateTime(2020, 1, 1, 3, 30)); + + var catches = [ + Catch( + id: randomId(), + timestamp: Int64(dateTime(2020, 1, 1, 5).millisecondsSinceEpoch), + ), + Catch( + id: randomId(), + timestamp: Int64(dateTime(2020, 2, 1, 8).millisecondsSinceEpoch), + ), + Catch( + id: randomId(), + timestamp: Int64(dateTime(2020, 3, 1, 15).millisecondsSinceEpoch), + ), + ]; + when(appManager.catchManager.catches( + any, + filter: anyNamed("filter"), + )).thenReturn(catches); + when(appManager.catchManager.id(any)) + .thenAnswer((invocation) => invocation.positionalArguments.first.id); + + await tester.pumpWidget(Testable( + (_) => const SaveTripPage(), + appManager: appManager, + )); + + expect(find.text("Jan 1, 2020"), findsNWidgets(2)); + expect(find.text("3:30 AM"), findsNWidgets(2)); + + await ensureVisibleAndSettle(tester, find.text("No catches")); + await tapAndSettle(tester, find.text("No catches")); + await tapAndSettle(tester, find.byType(BackButton)); + + expect(find.text("Jan 1, 2020"), findsNWidgets(2)); + expect(find.text("3:30 AM"), findsNWidgets(2)); }); testWidgets("Only date is updated when catches picked and all-day is checked", @@ -1284,8 +1169,8 @@ void main() { expect(find.text("Jan 1, 2020"), findsNWidgets(2)); expect(find.text("3:30 AM"), findsNWidgets(2)); - await tapAndSettle(tester, find.byType(Checkbox).first); - await tapAndSettle(tester, find.byType(Checkbox).last); + await tapAndSettle(tester, find.byType(Checkbox).at(1)); + await tapAndSettle(tester, find.byType(Checkbox).at(2)); expect(find.text("12:00 AM"), findsNWidgets(2));