diff --git a/lib/providers/routines.dart b/lib/providers/routines.dart index 7e94a8c4..0cd67895 100644 --- a/lib/providers/routines.dart +++ b/lib/providers/routines.dart @@ -386,7 +386,7 @@ class RoutinesProvider with ChangeNotifier { baseProvider.makeUrl( _routinesUrlPath, id: workout.id, - objectMethod: 'log_data', + objectMethod: 'logs', query: {'id': base.id!.toString()}, ), ); diff --git a/lib/widgets/routines/forms/day.dart b/lib/widgets/routines/forms/day.dart index 1206f77c..07566696 100644 --- a/lib/widgets/routines/forms/day.dart +++ b/lib/widgets/routines/forms/day.dart @@ -199,6 +199,7 @@ class _DayFormWidgetState extends State { key: ValueKey('day-title-${widget.day.id!}'), ), SwitchListTile( + key: const Key('field-is-rest-day'), title: Text(i18n.isRestDay), subtitle: Text(i18n.isRestDayHelp), value: isRestDay, @@ -262,16 +263,19 @@ class _DayFormWidgetState extends State { }, ), SwitchListTile( + key: const Key('field-need-logs-to-advance'), title: Text(i18n.needsLogsToAdvance), subtitle: Text(i18n.needsLogsToAdvanceHelp), value: needLogsToAdvance, contentPadding: const EdgeInsets.all(4), - onChanged: (value) { - setState(() { - needLogsToAdvance = value; - }); - widget.day.needLogsToAdvance = value; - }, + onChanged: widget.day.isRest + ? null + : (value) { + setState(() { + needLogsToAdvance = value; + }); + widget.day.needLogsToAdvance = value; + }, ), const SizedBox(height: 5), ElevatedButton( @@ -284,9 +288,7 @@ class _DayFormWidgetState extends State { _form.currentState!.save(); try { - Provider.of(context, listen: false).editDay( - widget.day, - ); + Provider.of(context, listen: false).editDay(widget.day); } catch (error) { await showDialog( context: context, diff --git a/test/fixtures/routines/slot_entry.json b/test/fixtures/routines/slot_entry.json new file mode 100644 index 00000000..dcce1053 --- /dev/null +++ b/test/fixtures/routines/slot_entry.json @@ -0,0 +1,132 @@ +{ + "id": 143, + "slot": 140, + "exercise": 294, + "order": 2, + "comment": "lorem ipsum", + "type": "normal", + "class_name": null, + "config": null, + "repetition_unit": 1, + "repetition_rounding": "1.25", + "reps_configs": [ + { + "id": 139, + "slot_entry": 143, + "iteration": 1, + "value": "2.00", + "operation": "r", + "step": "na", + "need_log_to_apply": false, + "repeat": false, + "requirements": null + } + ], + "max_reps_configs": [ + { + "id": 1, + "slot_entry": 143, + "iteration": 1, + "value": "5.00", + "operation": "r", + "step": "na", + "need_log_to_apply": false, + "repeat": false, + "requirements": null + } + ], + "weight_unit": 1, + "weight_rounding": "2.50", + "weight_configs": [ + { + "id": 10, + "slot_entry": 143, + "iteration": 1, + "value": "11.00", + "operation": "r", + "step": "na", + "need_log_to_apply": false, + "repeat": false, + "requirements": null + } + ], + "max_weight_configs": [ + { + "id": 1, + "slot_entry": 143, + "iteration": 1, + "value": "14.00", + "operation": "r", + "step": "na", + "need_log_to_apply": false, + "repeat": false, + "requirements": null + } + ], + "set_nr_configs": [ + { + "id": 143, + "slot_entry": 143, + "iteration": 1, + "value": 1, + "operation": "r", + "step": "na", + "need_log_to_apply": false, + "repeat": false, + "requirements": null + } + ], + "max_set_nr_configs": [ + { + "id": 2, + "slot_entry": 143, + "iteration": 1, + "value": 2, + "operation": "r", + "step": "na", + "need_log_to_apply": false, + "repeat": false, + "requirements": null + } + ], + "rir_configs": [ + { + "id": 1, + "slot_entry": 143, + "iteration": 1, + "value": "1.0", + "operation": "r", + "step": "na", + "need_log_to_apply": false, + "repeat": false, + "requirements": null + } + ], + "max_rir_configs": [], + "rest_configs": [ + { + "id": 138, + "slot_entry": 143, + "iteration": 1, + "value": 100, + "operation": "r", + "step": "na", + "need_log_to_apply": false, + "repeat": false, + "requirements": null + } + ], + "max_rest_configs": [ + { + "id": 1, + "slot_entry": 143, + "iteration": 1, + "value": 150, + "operation": "r", + "step": "na", + "need_log_to_apply": false, + "repeat": false, + "requirements": null + } + ] +} \ No newline at end of file diff --git a/test/workout/day_form_test.dart b/test/workout/day_form_test.dart new file mode 100644 index 00000000..4d853043 --- /dev/null +++ b/test/workout/day_form_test.dart @@ -0,0 +1,106 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020, 2021 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +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/consts.dart'; +import 'package:wger/models/workouts/day.dart'; +import 'package:wger/providers/routines.dart'; +import 'package:wger/widgets/routines/forms/day.dart'; + +import '../../test_data/routines.dart'; +import 'routine_edit_test.mocks.dart'; + +@GenerateMocks([RoutinesProvider]) +void main() { + late MockRoutinesProvider mockRoutinesProvider; + + setUp(() { + mockRoutinesProvider = MockRoutinesProvider(); + when(mockRoutinesProvider.editDay(any)).thenAnswer((_) async => getTestRoutine().days[0]); + }); + + Widget renderWidget() { + return ChangeNotifierProvider.value( + value: mockRoutinesProvider, + child: MaterialApp( + locale: const Locale('en'), + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, + home: Scaffold( + body: SingleChildScrollView( + child: DayFormWidget(routineId: 125, day: getTestRoutine().days[0]), + ), + ), + ), + ); + } + + group('DayFormWidget test', () { + testWidgets('Fields are disabled for rest days', (WidgetTester tester) async { + await tester.pumpWidget(renderWidget()); + await tester.pumpAndSettle(); + await tester.tap(find.byKey(const Key('field-is-rest-day'))); + await tester.pumpAndSettle(); + + final nameField = find.byKey(const Key('field-name')); + final TextFormField nameTextField = tester.widget(nameField); + expect(nameTextField.enabled, isFalse); + + final descriptionField = find.byKey(const Key('field-description')); + final TextFormField descriptionTextField = tester.widget(descriptionField); + expect(descriptionTextField.enabled, isFalse); + + final switchListTileFinder = find.byKey(const Key('field-need-logs-to-advance')); + final SwitchListTile switchListTile = tester.widget(switchListTileFinder); + expect(switchListTile.onChanged, isNull); + }); + + testWidgets('Call server', (WidgetTester tester) async { + await tester.pumpWidget(renderWidget()); + await tester.pumpAndSettle(); + + final nameField = find.byKey(const Key('field-name')); + await tester.enterText(nameField, ''); + await tester.enterText(nameField, 'Day 1'); + + final descriptionField = find.byKey(const Key('field-description')); + await tester.enterText(descriptionField, ''); + await tester.enterText(descriptionField, 'Day 1 description'); + + await tester.tap(find.byKey(const Key(SUBMIT_BUTTON_KEY_NAME))); + await tester.pumpAndSettle(); + + verify( + mockRoutinesProvider.editDay( + argThat( + isA() + .having((d) => d.routineId, 'routineId', 125) + .having((d) => d.id, 'id', 1) + .having((d) => d.name, 'name', 'Day 1') + .having((d) => d.description, 'description', 'Day 1 description'), + ), + ), + ); + }); + }); +} diff --git a/test/workout/day_form_test.mocks.dart b/test/workout/day_form_test.mocks.dart new file mode 100644 index 00000000..8b2078ba --- /dev/null +++ b/test/workout/day_form_test.mocks.dart @@ -0,0 +1,489 @@ +// Mocks generated by Mockito 5.4.5 from annotations +// in wger/test/workout/day_form_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i13; +import 'dart:ui' as _i17; + +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i16; +import 'package:wger/models/exercises/exercise.dart' as _i15; +import 'package:wger/models/workouts/base_config.dart' as _i9; +import 'package:wger/models/workouts/day.dart' as _i6; +import 'package:wger/models/workouts/day_data.dart' as _i14; +import 'package:wger/models/workouts/log.dart' as _i11; +import 'package:wger/models/workouts/repetition_unit.dart' as _i4; +import 'package:wger/models/workouts/routine.dart' as _i5; +import 'package:wger/models/workouts/session.dart' as _i10; +import 'package:wger/models/workouts/slot.dart' as _i7; +import 'package:wger/models/workouts/slot_entry.dart' as _i8; +import 'package:wger/models/workouts/weight_unit.dart' as _i3; +import 'package:wger/providers/base_provider.dart' as _i2; +import 'package:wger/providers/routines.dart' as _i12; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: must_be_immutable +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeWgerBaseProvider_0 extends _i1.SmartFake implements _i2.WgerBaseProvider { + _FakeWgerBaseProvider_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); +} + +class _FakeWeightUnit_1 extends _i1.SmartFake implements _i3.WeightUnit { + _FakeWeightUnit_1(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); +} + +class _FakeRepetitionUnit_2 extends _i1.SmartFake implements _i4.RepetitionUnit { + _FakeRepetitionUnit_2(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); +} + +class _FakeRoutine_3 extends _i1.SmartFake implements _i5.Routine { + _FakeRoutine_3(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); +} + +class _FakeDay_4 extends _i1.SmartFake implements _i6.Day { + _FakeDay_4(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); +} + +class _FakeSlot_5 extends _i1.SmartFake implements _i7.Slot { + _FakeSlot_5(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); +} + +class _FakeSlotEntry_6 extends _i1.SmartFake implements _i8.SlotEntry { + _FakeSlotEntry_6(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); +} + +class _FakeBaseConfig_7 extends _i1.SmartFake implements _i9.BaseConfig { + _FakeBaseConfig_7(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); +} + +class _FakeWorkoutSession_8 extends _i1.SmartFake implements _i10.WorkoutSession { + _FakeWorkoutSession_8(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); +} + +class _FakeLog_9 extends _i1.SmartFake implements _i11.Log { + _FakeLog_9(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); +} + +/// A class which mocks [RoutinesProvider]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { + MockRoutinesProvider() { + _i1.throwOnMissingStub(this); + } + + @override + _i2.WgerBaseProvider get baseProvider => (super.noSuchMethod( + Invocation.getter(#baseProvider), + returnValue: _FakeWgerBaseProvider_0( + this, + Invocation.getter(#baseProvider), + ), + ) as _i2.WgerBaseProvider); + + @override + List<_i5.Routine> get items => (super.noSuchMethod( + Invocation.getter(#items), + returnValue: <_i5.Routine>[], + ) as List<_i5.Routine>); + + @override + List<_i3.WeightUnit> get weightUnits => (super.noSuchMethod( + Invocation.getter(#weightUnits), + returnValue: <_i3.WeightUnit>[], + ) as List<_i3.WeightUnit>); + + @override + _i3.WeightUnit get defaultWeightUnit => (super.noSuchMethod( + Invocation.getter(#defaultWeightUnit), + returnValue: _FakeWeightUnit_1( + this, + Invocation.getter(#defaultWeightUnit), + ), + ) as _i3.WeightUnit); + + @override + List<_i4.RepetitionUnit> get repetitionUnits => (super.noSuchMethod( + Invocation.getter(#repetitionUnits), + returnValue: <_i4.RepetitionUnit>[], + ) as List<_i4.RepetitionUnit>); + + @override + _i4.RepetitionUnit get defaultRepetitionUnit => (super.noSuchMethod( + Invocation.getter(#defaultRepetitionUnit), + returnValue: _FakeRepetitionUnit_2( + this, + Invocation.getter(#defaultRepetitionUnit), + ), + ) as _i4.RepetitionUnit); + + @override + bool get hasListeners => + (super.noSuchMethod(Invocation.getter(#hasListeners), returnValue: false) as bool); + + @override + void clear() => super.noSuchMethod( + Invocation.method(#clear, []), + returnValueForMissingStub: null, + ); + + @override + _i3.WeightUnit findWeightUnitById(int? id) => (super.noSuchMethod( + Invocation.method(#findWeightUnitById, [id]), + returnValue: _FakeWeightUnit_1( + this, + Invocation.method(#findWeightUnitById, [id]), + ), + ) as _i3.WeightUnit); + + @override + _i4.RepetitionUnit findRepetitionUnitById(int? id) => (super.noSuchMethod( + Invocation.method(#findRepetitionUnitById, [id]), + returnValue: _FakeRepetitionUnit_2( + this, + Invocation.method(#findRepetitionUnitById, [id]), + ), + ) as _i4.RepetitionUnit); + + @override + List<_i5.Routine> getPlans() => (super.noSuchMethod( + Invocation.method(#getPlans, []), + returnValue: <_i5.Routine>[], + ) as List<_i5.Routine>); + + @override + _i5.Routine findById(int? id) => (super.noSuchMethod( + Invocation.method(#findById, [id]), + returnValue: _FakeRoutine_3( + this, + Invocation.method(#findById, [id]), + ), + ) as _i5.Routine); + + @override + int findIndexById(int? id) => (super.noSuchMethod( + Invocation.method(#findIndexById, [id]), + returnValue: 0, + ) as int); + + @override + void setCurrentPlan(int? id) => super.noSuchMethod( + Invocation.method(#setCurrentPlan, [id]), + returnValueForMissingStub: null, + ); + + @override + void resetCurrentRoutine() => super.noSuchMethod( + Invocation.method(#resetCurrentRoutine, []), + returnValueForMissingStub: null, + ); + + @override + _i13.Future fetchAndSetAllRoutinesFull() => (super.noSuchMethod( + Invocation.method(#fetchAndSetAllRoutinesFull, []), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future fetchAndSetAllPlansSparse() => (super.noSuchMethod( + Invocation.method(#fetchAndSetAllPlansSparse, []), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + void setExercisesAndUnits(List<_i14.DayData>? entries) => super.noSuchMethod( + Invocation.method(#setExercisesAndUnits, [entries]), + returnValueForMissingStub: null, + ); + + @override + _i13.Future<_i5.Routine> fetchAndSetRoutineSparse(int? planId) => (super.noSuchMethod( + Invocation.method(#fetchAndSetRoutineSparse, [planId]), + returnValue: _i13.Future<_i5.Routine>.value( + _FakeRoutine_3( + this, + Invocation.method(#fetchAndSetRoutineSparse, [planId]), + ), + ), + ) as _i13.Future<_i5.Routine>); + + @override + _i13.Future<_i5.Routine> fetchAndSetRoutineFull(int? routineId) => (super.noSuchMethod( + Invocation.method(#fetchAndSetRoutineFull, [routineId]), + returnValue: _i13.Future<_i5.Routine>.value( + _FakeRoutine_3( + this, + Invocation.method(#fetchAndSetRoutineFull, [routineId]), + ), + ), + ) as _i13.Future<_i5.Routine>); + + @override + _i13.Future<_i5.Routine> addRoutine(_i5.Routine? routine) => (super.noSuchMethod( + Invocation.method(#addRoutine, [routine]), + returnValue: _i13.Future<_i5.Routine>.value( + _FakeRoutine_3(this, Invocation.method(#addRoutine, [routine])), + ), + ) as _i13.Future<_i5.Routine>); + + @override + _i13.Future editRoutine(_i5.Routine? routine) => (super.noSuchMethod( + Invocation.method(#editRoutine, [routine]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future deleteRoutine(int? id) => (super.noSuchMethod( + Invocation.method(#deleteRoutine, [id]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future> fetchLogData( + _i5.Routine? workout, + _i15.Exercise? base, + ) => + (super.noSuchMethod( + Invocation.method(#fetchLogData, [workout, base]), + returnValue: _i13.Future>.value( + {}, + ), + ) as _i13.Future>); + + @override + _i13.Future fetchAndSetRepetitionUnits() => (super.noSuchMethod( + Invocation.method(#fetchAndSetRepetitionUnits, []), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future fetchAndSetWeightUnits() => (super.noSuchMethod( + Invocation.method(#fetchAndSetWeightUnits, []), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future fetchAndSetUnits() => (super.noSuchMethod( + Invocation.method(#fetchAndSetUnits, []), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future<_i6.Day> addDay(_i6.Day? day, {dynamic refresh = false}) => (super.noSuchMethod( + Invocation.method(#addDay, [day], {#refresh: refresh}), + returnValue: _i13.Future<_i6.Day>.value( + _FakeDay_4( + this, + Invocation.method(#addDay, [day], {#refresh: refresh}), + ), + ), + ) as _i13.Future<_i6.Day>); + + @override + _i13.Future editDay(_i6.Day? day) => (super.noSuchMethod( + Invocation.method(#editDay, [day]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future editDays(List<_i6.Day>? days) => (super.noSuchMethod( + Invocation.method(#editDays, [days]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future deleteDay(int? dayId) => (super.noSuchMethod( + Invocation.method(#deleteDay, [dayId]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future<_i7.Slot> addSlot(_i7.Slot? slot) => (super.noSuchMethod( + Invocation.method(#addSlot, [slot]), + returnValue: _i13.Future<_i7.Slot>.value( + _FakeSlot_5(this, Invocation.method(#addSlot, [slot])), + ), + ) as _i13.Future<_i7.Slot>); + + @override + _i13.Future deleteSlot(int? slotId) => (super.noSuchMethod( + Invocation.method(#deleteSlot, [slotId]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future editSlot(_i7.Slot? slot) => (super.noSuchMethod( + Invocation.method(#editSlot, [slot]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future editSlots(List<_i7.Slot>? slots) => (super.noSuchMethod( + Invocation.method(#editSlots, [slots]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future<_i8.SlotEntry> addSlotEntry(_i8.SlotEntry? entry) => (super.noSuchMethod( + Invocation.method(#addSlotEntry, [entry]), + returnValue: _i13.Future<_i8.SlotEntry>.value( + _FakeSlotEntry_6(this, Invocation.method(#addSlotEntry, [entry])), + ), + ) as _i13.Future<_i8.SlotEntry>); + + @override + _i13.Future deleteSlotEntry(int? id) => (super.noSuchMethod( + Invocation.method(#deleteSlotEntry, [id]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future editSlotEntry(_i8.SlotEntry? entry) => (super.noSuchMethod( + Invocation.method(#editSlotEntry, [entry]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod( + Invocation.method(#getConfigUrl, [type]), + returnValue: _i16.dummyValue( + this, + Invocation.method(#getConfigUrl, [type]), + ), + ) as String); + + @override + _i13.Future<_i9.BaseConfig> editConfig( + _i9.BaseConfig? config, + _i8.ConfigType? type, + ) => + (super.noSuchMethod( + Invocation.method(#editConfig, [config, type]), + returnValue: _i13.Future<_i9.BaseConfig>.value( + _FakeBaseConfig_7( + this, + Invocation.method(#editConfig, [config, type]), + ), + ), + ) as _i13.Future<_i9.BaseConfig>); + + @override + _i13.Future<_i9.BaseConfig> addConfig( + _i9.BaseConfig? config, + _i8.ConfigType? type, + ) => + (super.noSuchMethod( + Invocation.method(#addConfig, [config, type]), + returnValue: _i13.Future<_i9.BaseConfig>.value( + _FakeBaseConfig_7( + this, + Invocation.method(#addConfig, [config, type]), + ), + ), + ) as _i13.Future<_i9.BaseConfig>); + + @override + _i13.Future deleteConfig(int? id, _i8.ConfigType? type) => (super.noSuchMethod( + Invocation.method(#deleteConfig, [id, type]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future handleConfig( + _i8.SlotEntry? entry, + String? input, + _i8.ConfigType? type, + ) => + (super.noSuchMethod( + Invocation.method(#handleConfig, [entry, input, type]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future fetchSessionData() => (super.noSuchMethod( + Invocation.method(#fetchSessionData, []), + returnValue: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future<_i10.WorkoutSession> addSession(_i10.WorkoutSession? session) => (super.noSuchMethod( + Invocation.method(#addSession, [session]), + returnValue: _i13.Future<_i10.WorkoutSession>.value( + _FakeWorkoutSession_8( + this, + Invocation.method(#addSession, [session]), + ), + ), + ) as _i13.Future<_i10.WorkoutSession>); + + @override + _i13.Future<_i11.Log> addLog(_i11.Log? log) => (super.noSuchMethod( + Invocation.method(#addLog, [log]), + returnValue: _i13.Future<_i11.Log>.value( + _FakeLog_9(this, Invocation.method(#addLog, [log])), + ), + ) as _i13.Future<_i11.Log>); + + @override + _i13.Future deleteLog(_i11.Log? log) => (super.noSuchMethod( + Invocation.method(#deleteLog, [log]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( + Invocation.method(#addListener, [listener]), + returnValueForMissingStub: null, + ); + + @override + void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( + Invocation.method(#removeListener, [listener]), + returnValueForMissingStub: null, + ); + + @override + void dispose() => super.noSuchMethod( + Invocation.method(#dispose, []), + returnValueForMissingStub: null, + ); + + @override + void notifyListeners() => super.noSuchMethod( + Invocation.method(#notifyListeners, []), + returnValueForMissingStub: null, + ); +} diff --git a/test/workout/goldens/routine_logs_screen_detail.png b/test/workout/goldens/routine_logs_screen_detail.png new file mode 100644 index 00000000..6da113f0 Binary files /dev/null and b/test/workout/goldens/routine_logs_screen_detail.png differ diff --git a/test/workout/goldens/routine_screen_detail.png b/test/workout/goldens/routine_screen_detail.png new file mode 100644 index 00000000..ce2201b5 Binary files /dev/null and b/test/workout/goldens/routine_screen_detail.png differ diff --git a/test/workout/routine_logs_screen_test.dart b/test/workout/routine_logs_screen_test.dart new file mode 100644 index 00000000..ad8cda1d --- /dev/null +++ b/test/workout/routine_logs_screen_test.dart @@ -0,0 +1,87 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020, 2021 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:golden_toolkit/golden_toolkit.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:provider/provider.dart'; +import 'package:wger/providers/routines.dart'; +import 'package:wger/screens/routine_logs_screen.dart'; +import 'package:wger/screens/routine_screen.dart'; + +import '../../test_data/routines.dart'; +import 'routine_logs_screen_test.mocks.dart'; + +@GenerateMocks([RoutinesProvider]) +void main() { + final mockRoutinesProvider = MockRoutinesProvider(); + + setUp(() { + when(mockRoutinesProvider.fetchAndSetRoutineFull(any)) + .thenAnswer((_) => Future.value(getTestRoutine())); + }); + + Widget renderWidget({locale = 'en'}) { + final key = GlobalKey(); + + return ChangeNotifierProvider( + create: (context) => mockRoutinesProvider, + child: MaterialApp( + locale: Locale(locale), + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, + navigatorKey: key, + home: TextButton( + onPressed: () => key.currentState!.push( + MaterialPageRoute( + settings: RouteSettings(arguments: getTestRoutine()), + builder: (_) => const WorkoutLogsScreen(), + ), + ), + child: const SizedBox(), + ), + routes: { + RoutineScreen.routeName: (ctx) => const WorkoutLogsScreen(), + }, + ), + ); + } + + testGoldens('Test the widgets on the routine logs screen', (WidgetTester tester) async { + await loadAppFonts(); + await tester.pumpWidget(renderWidget()); + await tester.tap(find.byType(TextButton)); + await tester.pumpAndSettle(); + + await screenMatchesGolden(tester, 'routine_logs_screen_detail'); + + // expect(find.text('3 day workout'), findsOneWidget); + + // expect(find.text('first day'), findsOneWidget); + // expect(find.text('chest, shoulders'), findsOneWidget); + + // The second day is repeated + // expect(find.text('second day'), findsNWidgets(2)); + // expect(find.text('legs'), findsNWidgets(2)); + + // expect(find.byType(Card), findsNWidgets(3)); + }); +} diff --git a/test/workout/routine_logs_screen_test.mocks.dart b/test/workout/routine_logs_screen_test.mocks.dart new file mode 100644 index 00000000..943b73df --- /dev/null +++ b/test/workout/routine_logs_screen_test.mocks.dart @@ -0,0 +1,489 @@ +// Mocks generated by Mockito 5.4.5 from annotations +// in wger/test/workout/routine_logs_screen_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i13; +import 'dart:ui' as _i17; + +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i16; +import 'package:wger/models/exercises/exercise.dart' as _i15; +import 'package:wger/models/workouts/base_config.dart' as _i9; +import 'package:wger/models/workouts/day.dart' as _i6; +import 'package:wger/models/workouts/day_data.dart' as _i14; +import 'package:wger/models/workouts/log.dart' as _i11; +import 'package:wger/models/workouts/repetition_unit.dart' as _i4; +import 'package:wger/models/workouts/routine.dart' as _i5; +import 'package:wger/models/workouts/session.dart' as _i10; +import 'package:wger/models/workouts/slot.dart' as _i7; +import 'package:wger/models/workouts/slot_entry.dart' as _i8; +import 'package:wger/models/workouts/weight_unit.dart' as _i3; +import 'package:wger/providers/base_provider.dart' as _i2; +import 'package:wger/providers/routines.dart' as _i12; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: must_be_immutable +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeWgerBaseProvider_0 extends _i1.SmartFake implements _i2.WgerBaseProvider { + _FakeWgerBaseProvider_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); +} + +class _FakeWeightUnit_1 extends _i1.SmartFake implements _i3.WeightUnit { + _FakeWeightUnit_1(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); +} + +class _FakeRepetitionUnit_2 extends _i1.SmartFake implements _i4.RepetitionUnit { + _FakeRepetitionUnit_2(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); +} + +class _FakeRoutine_3 extends _i1.SmartFake implements _i5.Routine { + _FakeRoutine_3(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); +} + +class _FakeDay_4 extends _i1.SmartFake implements _i6.Day { + _FakeDay_4(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); +} + +class _FakeSlot_5 extends _i1.SmartFake implements _i7.Slot { + _FakeSlot_5(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); +} + +class _FakeSlotEntry_6 extends _i1.SmartFake implements _i8.SlotEntry { + _FakeSlotEntry_6(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); +} + +class _FakeBaseConfig_7 extends _i1.SmartFake implements _i9.BaseConfig { + _FakeBaseConfig_7(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); +} + +class _FakeWorkoutSession_8 extends _i1.SmartFake implements _i10.WorkoutSession { + _FakeWorkoutSession_8(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); +} + +class _FakeLog_9 extends _i1.SmartFake implements _i11.Log { + _FakeLog_9(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); +} + +/// A class which mocks [RoutinesProvider]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { + MockRoutinesProvider() { + _i1.throwOnMissingStub(this); + } + + @override + _i2.WgerBaseProvider get baseProvider => (super.noSuchMethod( + Invocation.getter(#baseProvider), + returnValue: _FakeWgerBaseProvider_0( + this, + Invocation.getter(#baseProvider), + ), + ) as _i2.WgerBaseProvider); + + @override + List<_i5.Routine> get items => (super.noSuchMethod( + Invocation.getter(#items), + returnValue: <_i5.Routine>[], + ) as List<_i5.Routine>); + + @override + List<_i3.WeightUnit> get weightUnits => (super.noSuchMethod( + Invocation.getter(#weightUnits), + returnValue: <_i3.WeightUnit>[], + ) as List<_i3.WeightUnit>); + + @override + _i3.WeightUnit get defaultWeightUnit => (super.noSuchMethod( + Invocation.getter(#defaultWeightUnit), + returnValue: _FakeWeightUnit_1( + this, + Invocation.getter(#defaultWeightUnit), + ), + ) as _i3.WeightUnit); + + @override + List<_i4.RepetitionUnit> get repetitionUnits => (super.noSuchMethod( + Invocation.getter(#repetitionUnits), + returnValue: <_i4.RepetitionUnit>[], + ) as List<_i4.RepetitionUnit>); + + @override + _i4.RepetitionUnit get defaultRepetitionUnit => (super.noSuchMethod( + Invocation.getter(#defaultRepetitionUnit), + returnValue: _FakeRepetitionUnit_2( + this, + Invocation.getter(#defaultRepetitionUnit), + ), + ) as _i4.RepetitionUnit); + + @override + bool get hasListeners => + (super.noSuchMethod(Invocation.getter(#hasListeners), returnValue: false) as bool); + + @override + void clear() => super.noSuchMethod( + Invocation.method(#clear, []), + returnValueForMissingStub: null, + ); + + @override + _i3.WeightUnit findWeightUnitById(int? id) => (super.noSuchMethod( + Invocation.method(#findWeightUnitById, [id]), + returnValue: _FakeWeightUnit_1( + this, + Invocation.method(#findWeightUnitById, [id]), + ), + ) as _i3.WeightUnit); + + @override + _i4.RepetitionUnit findRepetitionUnitById(int? id) => (super.noSuchMethod( + Invocation.method(#findRepetitionUnitById, [id]), + returnValue: _FakeRepetitionUnit_2( + this, + Invocation.method(#findRepetitionUnitById, [id]), + ), + ) as _i4.RepetitionUnit); + + @override + List<_i5.Routine> getPlans() => (super.noSuchMethod( + Invocation.method(#getPlans, []), + returnValue: <_i5.Routine>[], + ) as List<_i5.Routine>); + + @override + _i5.Routine findById(int? id) => (super.noSuchMethod( + Invocation.method(#findById, [id]), + returnValue: _FakeRoutine_3( + this, + Invocation.method(#findById, [id]), + ), + ) as _i5.Routine); + + @override + int findIndexById(int? id) => (super.noSuchMethod( + Invocation.method(#findIndexById, [id]), + returnValue: 0, + ) as int); + + @override + void setCurrentPlan(int? id) => super.noSuchMethod( + Invocation.method(#setCurrentPlan, [id]), + returnValueForMissingStub: null, + ); + + @override + void resetCurrentRoutine() => super.noSuchMethod( + Invocation.method(#resetCurrentRoutine, []), + returnValueForMissingStub: null, + ); + + @override + _i13.Future fetchAndSetAllRoutinesFull() => (super.noSuchMethod( + Invocation.method(#fetchAndSetAllRoutinesFull, []), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future fetchAndSetAllPlansSparse() => (super.noSuchMethod( + Invocation.method(#fetchAndSetAllPlansSparse, []), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + void setExercisesAndUnits(List<_i14.DayData>? entries) => super.noSuchMethod( + Invocation.method(#setExercisesAndUnits, [entries]), + returnValueForMissingStub: null, + ); + + @override + _i13.Future<_i5.Routine> fetchAndSetRoutineSparse(int? planId) => (super.noSuchMethod( + Invocation.method(#fetchAndSetRoutineSparse, [planId]), + returnValue: _i13.Future<_i5.Routine>.value( + _FakeRoutine_3( + this, + Invocation.method(#fetchAndSetRoutineSparse, [planId]), + ), + ), + ) as _i13.Future<_i5.Routine>); + + @override + _i13.Future<_i5.Routine> fetchAndSetRoutineFull(int? routineId) => (super.noSuchMethod( + Invocation.method(#fetchAndSetRoutineFull, [routineId]), + returnValue: _i13.Future<_i5.Routine>.value( + _FakeRoutine_3( + this, + Invocation.method(#fetchAndSetRoutineFull, [routineId]), + ), + ), + ) as _i13.Future<_i5.Routine>); + + @override + _i13.Future<_i5.Routine> addRoutine(_i5.Routine? routine) => (super.noSuchMethod( + Invocation.method(#addRoutine, [routine]), + returnValue: _i13.Future<_i5.Routine>.value( + _FakeRoutine_3(this, Invocation.method(#addRoutine, [routine])), + ), + ) as _i13.Future<_i5.Routine>); + + @override + _i13.Future editRoutine(_i5.Routine? routine) => (super.noSuchMethod( + Invocation.method(#editRoutine, [routine]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future deleteRoutine(int? id) => (super.noSuchMethod( + Invocation.method(#deleteRoutine, [id]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future> fetchLogData( + _i5.Routine? workout, + _i15.Exercise? base, + ) => + (super.noSuchMethod( + Invocation.method(#fetchLogData, [workout, base]), + returnValue: _i13.Future>.value( + {}, + ), + ) as _i13.Future>); + + @override + _i13.Future fetchAndSetRepetitionUnits() => (super.noSuchMethod( + Invocation.method(#fetchAndSetRepetitionUnits, []), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future fetchAndSetWeightUnits() => (super.noSuchMethod( + Invocation.method(#fetchAndSetWeightUnits, []), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future fetchAndSetUnits() => (super.noSuchMethod( + Invocation.method(#fetchAndSetUnits, []), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future<_i6.Day> addDay(_i6.Day? day, {dynamic refresh = false}) => (super.noSuchMethod( + Invocation.method(#addDay, [day], {#refresh: refresh}), + returnValue: _i13.Future<_i6.Day>.value( + _FakeDay_4( + this, + Invocation.method(#addDay, [day], {#refresh: refresh}), + ), + ), + ) as _i13.Future<_i6.Day>); + + @override + _i13.Future editDay(_i6.Day? day) => (super.noSuchMethod( + Invocation.method(#editDay, [day]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future editDays(List<_i6.Day>? days) => (super.noSuchMethod( + Invocation.method(#editDays, [days]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future deleteDay(int? dayId) => (super.noSuchMethod( + Invocation.method(#deleteDay, [dayId]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future<_i7.Slot> addSlot(_i7.Slot? slot) => (super.noSuchMethod( + Invocation.method(#addSlot, [slot]), + returnValue: _i13.Future<_i7.Slot>.value( + _FakeSlot_5(this, Invocation.method(#addSlot, [slot])), + ), + ) as _i13.Future<_i7.Slot>); + + @override + _i13.Future deleteSlot(int? slotId) => (super.noSuchMethod( + Invocation.method(#deleteSlot, [slotId]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future editSlot(_i7.Slot? slot) => (super.noSuchMethod( + Invocation.method(#editSlot, [slot]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future editSlots(List<_i7.Slot>? slots) => (super.noSuchMethod( + Invocation.method(#editSlots, [slots]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future<_i8.SlotEntry> addSlotEntry(_i8.SlotEntry? entry) => (super.noSuchMethod( + Invocation.method(#addSlotEntry, [entry]), + returnValue: _i13.Future<_i8.SlotEntry>.value( + _FakeSlotEntry_6(this, Invocation.method(#addSlotEntry, [entry])), + ), + ) as _i13.Future<_i8.SlotEntry>); + + @override + _i13.Future deleteSlotEntry(int? id) => (super.noSuchMethod( + Invocation.method(#deleteSlotEntry, [id]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future editSlotEntry(_i8.SlotEntry? entry) => (super.noSuchMethod( + Invocation.method(#editSlotEntry, [entry]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod( + Invocation.method(#getConfigUrl, [type]), + returnValue: _i16.dummyValue( + this, + Invocation.method(#getConfigUrl, [type]), + ), + ) as String); + + @override + _i13.Future<_i9.BaseConfig> editConfig( + _i9.BaseConfig? config, + _i8.ConfigType? type, + ) => + (super.noSuchMethod( + Invocation.method(#editConfig, [config, type]), + returnValue: _i13.Future<_i9.BaseConfig>.value( + _FakeBaseConfig_7( + this, + Invocation.method(#editConfig, [config, type]), + ), + ), + ) as _i13.Future<_i9.BaseConfig>); + + @override + _i13.Future<_i9.BaseConfig> addConfig( + _i9.BaseConfig? config, + _i8.ConfigType? type, + ) => + (super.noSuchMethod( + Invocation.method(#addConfig, [config, type]), + returnValue: _i13.Future<_i9.BaseConfig>.value( + _FakeBaseConfig_7( + this, + Invocation.method(#addConfig, [config, type]), + ), + ), + ) as _i13.Future<_i9.BaseConfig>); + + @override + _i13.Future deleteConfig(int? id, _i8.ConfigType? type) => (super.noSuchMethod( + Invocation.method(#deleteConfig, [id, type]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future handleConfig( + _i8.SlotEntry? entry, + String? input, + _i8.ConfigType? type, + ) => + (super.noSuchMethod( + Invocation.method(#handleConfig, [entry, input, type]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future fetchSessionData() => (super.noSuchMethod( + Invocation.method(#fetchSessionData, []), + returnValue: _i13.Future.value(), + ) as _i13.Future); + + @override + _i13.Future<_i10.WorkoutSession> addSession(_i10.WorkoutSession? session) => (super.noSuchMethod( + Invocation.method(#addSession, [session]), + returnValue: _i13.Future<_i10.WorkoutSession>.value( + _FakeWorkoutSession_8( + this, + Invocation.method(#addSession, [session]), + ), + ), + ) as _i13.Future<_i10.WorkoutSession>); + + @override + _i13.Future<_i11.Log> addLog(_i11.Log? log) => (super.noSuchMethod( + Invocation.method(#addLog, [log]), + returnValue: _i13.Future<_i11.Log>.value( + _FakeLog_9(this, Invocation.method(#addLog, [log])), + ), + ) as _i13.Future<_i11.Log>); + + @override + _i13.Future deleteLog(_i11.Log? log) => (super.noSuchMethod( + Invocation.method(#deleteLog, [log]), + returnValue: _i13.Future.value(), + returnValueForMissingStub: _i13.Future.value(), + ) as _i13.Future); + + @override + void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( + Invocation.method(#addListener, [listener]), + returnValueForMissingStub: null, + ); + + @override + void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( + Invocation.method(#removeListener, [listener]), + returnValueForMissingStub: null, + ); + + @override + void dispose() => super.noSuchMethod( + Invocation.method(#dispose, []), + returnValueForMissingStub: null, + ); + + @override + void notifyListeners() => super.noSuchMethod( + Invocation.method(#notifyListeners, []), + returnValueForMissingStub: null, + ); +} diff --git a/test/workout/routine_screen_test.dart b/test/workout/routine_screen_test.dart index 99a6fec9..46c302d8 100644 --- a/test/workout/routine_screen_test.dart +++ b/test/workout/routine_screen_test.dart @@ -20,6 +20,7 @@ import 'package:drift/native.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:golden_toolkit/golden_toolkit.dart'; import 'package:mockito/annotations.dart'; import 'package:provider/provider.dart'; import 'package:wger/database/exercises/exercise_database.dart'; @@ -65,11 +66,14 @@ void main() { ); } - testWidgets('Test the widgets on the routine screen', (WidgetTester tester) async { + testGoldens('Test the widgets on the routine screen', (WidgetTester tester) async { + await loadAppFonts(); await tester.pumpWidget(renderWidget()); await tester.tap(find.byType(TextButton)); await tester.pumpAndSettle(); + await screenMatchesGolden(tester, 'routine_screen_detail'); + expect(find.text('3 day workout'), findsOneWidget); expect(find.text('first day'), findsOneWidget); diff --git a/test/workout/slot_entry_model_test.dart b/test/workout/slot_entry_model_test.dart new file mode 100644 index 00000000..5853ea8c --- /dev/null +++ b/test/workout/slot_entry_model_test.dart @@ -0,0 +1,51 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020, 2021 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import 'dart:convert'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:wger/models/workouts/slot_entry.dart'; + +import '../fixtures/fixture_reader.dart'; + +void main() { + test('Checks that the data is correctly read from the server', () { + final apiResponse = fixture('routines/slot_entry.json'); + + final slotEntry = SlotEntry.fromJson(json.decode(apiResponse)); + expect(slotEntry.id, 143); + expect(slotEntry.slotId, 140); + expect(slotEntry.order, 2); + expect(slotEntry.config, null); + expect(slotEntry.repetitionUnitId, 1); + expect(slotEntry.repetitionRounding, 1.25); + expect(slotEntry.weightUnitId, 1); + expect(slotEntry.weightRounding, 2.5); + expect(slotEntry.repsConfigs.length, 1); + expect(slotEntry.repsConfigs[0].id, 139); + expect(slotEntry.maxRepsConfigs.length, 1); + expect(slotEntry.weightConfigs.length, 1); + expect(slotEntry.maxWeightConfigs.length, 1); + expect(slotEntry.nrOfSetsConfigs.length, 1); + expect(slotEntry.maxNrOfSetsConfigs.length, 1); + expect(slotEntry.rirConfigs.length, 1); + expect(slotEntry.maxRirConfigs.length, 0); + expect(slotEntry.restTimeConfigs.length, 1); + expect(slotEntry.maxRestTimeConfigs.length, 1); + }); +}