From 1ecbfa88d1aa8fc076727c1bc6cd6a0658dfcd49 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Fri, 18 Apr 2025 00:20:39 +0200 Subject: [PATCH] Correctly set the start and end time to null, if this is what comes from the API --- lib/helpers/json.dart | 8 +++++ lib/models/nutrition/meal.dart | 2 +- lib/models/nutrition/meal.g.dart | 2 +- lib/models/workouts/session.dart | 4 +-- lib/models/workouts/session.g.dart | 4 +-- lib/widgets/nutrition/forms.dart | 2 +- lib/widgets/routines/gym_mode/gym_mode.dart | 9 +++--- .../routines/gym_mode/session_page.dart | 9 +++--- .../workout/gym_mode_session_screen_test.dart | 32 +++++++++++++++++-- 9 files changed, 55 insertions(+), 17 deletions(-) diff --git a/lib/helpers/json.dart b/lib/helpers/json.dart index 7e97c37f..f10c1f80 100644 --- a/lib/helpers/json.dart +++ b/lib/helpers/json.dart @@ -62,6 +62,14 @@ TimeOfDay stringToTime(String? time) { return TimeOfDay.fromDateTime(DateTime.parse('2020-01-01 $out')); } +TimeOfDay? stringToTimeNull(String? time) { + if (time == null) { + return null; + } + + return TimeOfDay.fromDateTime(DateTime.parse('2020-01-01 $time')); +} + /* * Converts a datetime to time. */ diff --git a/lib/models/nutrition/meal.dart b/lib/models/nutrition/meal.dart index ecb3ca3f..3e98c9e8 100644 --- a/lib/models/nutrition/meal.dart +++ b/lib/models/nutrition/meal.dart @@ -35,7 +35,7 @@ class Meal { @JsonKey(name: 'plan') late int planId; - @JsonKey(toJson: timeToString, fromJson: stringToTime) + @JsonKey(toJson: timeToString, fromJson: stringToTimeNull) TimeOfDay? time; @JsonKey(name: 'name') diff --git a/lib/models/nutrition/meal.g.dart b/lib/models/nutrition/meal.g.dart index 2258775c..ee2b1a63 100644 --- a/lib/models/nutrition/meal.g.dart +++ b/lib/models/nutrition/meal.g.dart @@ -8,7 +8,7 @@ part of 'meal.dart'; Meal _$MealFromJson(Map json) => Meal( id: (json['id'] as num?)?.toInt(), - time: stringToTime(json['time'] as String?), + time: stringToTimeNull(json['time'] as String?), name: json['name'] as String?, )..planId = (json['plan'] as num).toInt(); diff --git a/lib/models/workouts/session.dart b/lib/models/workouts/session.dart index 7eaf1a9c..78ef47c4 100644 --- a/lib/models/workouts/session.dart +++ b/lib/models/workouts/session.dart @@ -42,10 +42,10 @@ class WorkoutSession { @JsonKey(required: false, defaultValue: '') late String notes; - @JsonKey(required: true, name: 'time_start', toJson: timeToString, fromJson: stringToTime) + @JsonKey(required: true, name: 'time_start', toJson: timeToString, fromJson: stringToTimeNull) late TimeOfDay? timeStart; - @JsonKey(required: true, name: 'time_end', toJson: timeToString, fromJson: stringToTime) + @JsonKey(required: true, name: 'time_end', toJson: timeToString, fromJson: stringToTimeNull) late TimeOfDay? timeEnd; @JsonKey(required: false, includeToJson: false, defaultValue: []) diff --git a/lib/models/workouts/session.g.dart b/lib/models/workouts/session.g.dart index fb6781c4..63444c65 100644 --- a/lib/models/workouts/session.g.dart +++ b/lib/models/workouts/session.g.dart @@ -16,8 +16,8 @@ WorkoutSession _$WorkoutSessionFromJson(Map json) { routineId: (json['routine'] as num).toInt(), impression: json['impression'] == null ? 2 : int.parse(json['impression'] as String), notes: json['notes'] as String? ?? '', - timeStart: stringToTime(json['time_start'] as String?), - timeEnd: stringToTime(json['time_end'] as String?), + timeStart: stringToTimeNull(json['time_start'] as String?), + timeEnd: stringToTimeNull(json['time_end'] as String?), logs: (json['logs'] as List?) ?.map((e) => Log.fromJson(e as Map)) .toList() ?? diff --git a/lib/widgets/nutrition/forms.dart b/lib/widgets/nutrition/forms.dart index db3e372b..60d32967 100644 --- a/lib/widgets/nutrition/forms.dart +++ b/lib/widgets/nutrition/forms.dart @@ -74,7 +74,7 @@ class MealForm extends StatelessWidget { } }, onSaved: (newValue) { - _meal.time = stringToTime(newValue); + _meal.time = stringToTimeNull(newValue); }, ), TextFormField( diff --git a/lib/widgets/routines/gym_mode/gym_mode.dart b/lib/widgets/routines/gym_mode/gym_mode.dart index baf1ba2d..44abd86b 100644 --- a/lib/widgets/routines/gym_mode/gym_mode.dart +++ b/lib/widgets/routines/gym_mode/gym_mode.dart @@ -75,11 +75,12 @@ class _GymModeState extends ConsumerState { final validUntil = ref.read(gymStateProvider).validUntil; final currentPage = ref.read(gymStateProvider).currentPage; final savedDayId = ref.read(gymStateProvider).dayId; - final newDayId = widget._dayDataGym.day!.id!; - final shouldReset = - widget._dayDataGym.day!.id != savedDayId || validUntil.isBefore(DateTime.now()); - widget._logger.fine('Day ID mismatch or expired validUntil date. Resetting to page 0.'); + + final shouldReset = newDayId != savedDayId || validUntil.isBefore(DateTime.now()); + if (shouldReset) { + widget._logger.fine('Day ID mismatch or expired validUntil date. Resetting to page 0.'); + } final initialPage = shouldReset ? 0 : currentPage; WidgetsBinding.instance.addPostFrameCallback((_) { diff --git a/lib/widgets/routines/gym_mode/session_page.dart b/lib/widgets/routines/gym_mode/session_page.dart index 2c0a0dee..93ac2b14 100644 --- a/lib/widgets/routines/gym_mode/session_page.dart +++ b/lib/widgets/routines/gym_mode/session_page.dart @@ -35,11 +35,12 @@ class SessionPage extends StatefulWidget { late WorkoutSession _session; final PageController _controller; final Map _exercisePages; + final TimeOfDay _start; SessionPage( this._routine, this._controller, - start, + this._start, this._exercisePages, ) { _session = _routine.sessions.map((sessionApi) => sessionApi.session).firstWhere( @@ -49,7 +50,7 @@ class SessionPage extends StatefulWidget { impression: DEFAULT_IMPRESSION, date: clock.now(), timeEnd: TimeOfDay.now(), - timeStart: start, + timeStart: _start, ), ); } @@ -72,8 +73,8 @@ class _SessionPageState extends State { void initState() { super.initState(); - timeStartController.text = timeToString(widget._session.timeStart)!; - timeEndController.text = timeToString(widget._session.timeEnd)!; + timeStartController.text = timeToString(widget._session.timeStart ?? widget._start)!; + timeEndController.text = timeToString(widget._session.timeEnd ?? TimeOfDay.now())!; notesController.text = widget._session.notes; selectedImpression[widget._session.impression - 1] = true; diff --git a/test/workout/gym_mode_session_screen_test.dart b/test/workout/gym_mode_session_screen_test.dart index 098437c1..3b36bee2 100644 --- a/test/workout/gym_mode_session_screen_test.dart +++ b/test/workout/gym_mode_session_screen_test.dart @@ -22,7 +22,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:provider/provider.dart'; +import 'package:wger/helpers/json.dart'; import 'package:wger/l10n/generated/app_localizations.dart'; +import 'package:wger/models/workouts/routine.dart'; import 'package:wger/providers/routines.dart'; import 'package:wger/widgets/routines/gym_mode/session_page.dart'; @@ -32,8 +34,11 @@ import 'gym_mode_session_screen_test.mocks.dart'; @GenerateMocks([RoutinesProvider]) void main() { final mockRoutinesProvider = MockRoutinesProvider(); + late Routine testRoutine; - final testRoutine = getTestRoutine(); + setUp(() { + testRoutine = getTestRoutine(); + }); Widget renderSessionPage({locale = 'en'}) { return ChangeNotifierProvider( @@ -46,7 +51,7 @@ void main() { body: SessionPage( testRoutine, PageController(), - const TimeOfDay(hour: 12, minute: 34), + const TimeOfDay(hour: 13, minute: 35), const {}, ), ), @@ -65,6 +70,29 @@ void main() { }); }); + testWidgets('Test that data from session is loaded - null times', (WidgetTester tester) async { + testRoutine.sessions[0].session.timeStart = null; + testRoutine.sessions[0].session.timeEnd = null; + final timeNow = timeToString(TimeOfDay.now())!; + + withClock(Clock.fixed(DateTime(2021, 5, 1)), () async { + await tester.pumpWidget(renderSessionPage()); + expect(find.text('13:35'), findsOneWidget); + expect(find.text(timeNow), findsOneWidget); + }); + }); + + testWidgets('Test correct default data (no existing session)', (WidgetTester tester) async { + testRoutine.sessions = []; + final timeNow = timeToString(TimeOfDay.now())!; + + await tester.pumpWidget(renderSessionPage()); + expect(find.text('13:35'), findsOneWidget); + expect(find.text(timeNow), findsOneWidget); + final toggleButtons = tester.widget(find.byType(ToggleButtons)); + expect(toggleButtons.isSelected[1], isTrue); + }); + testWidgets('Test that correct data is send to server', (WidgetTester tester) async { withClock(Clock.fixed(DateTime(2021, 5, 1)), () async { await tester.pumpWidget(renderSessionPage());