Commit 8995fff

derdilla <82763757+derdilla@users.noreply.github.com>
2025-09-20 12:05:11
Fix input form being unsubmitable without visble time sub-form (#601)
* Fix input form failing to validate when settings.allowManualTimeInput is false * Add automated test for fix * Update date time form tests There was an implementation change in the material library which caused 2 tests to fail.
1 parent d931148
Changed files (4)
app/lib/features/input/forms/add_entry_form.dart
@@ -108,7 +108,11 @@ class AddEntryFormState extends FormStateBase<AddEntryFormValue, AddEntryForm>
 
   @override
   bool validate() {
-    final timeFormValidation = _timeForm.currentState?.validate();
+    final settings = context.read<Settings>();
+
+    final timeFormValidation = settings.allowManualTimeInput
+      ? _timeForm.currentState?.validate()
+      : true;
     final noteFormValidation = _noteForm.currentState?.validate();
     final bpFormValidation = _bpForm.currentState?.validate();
     final weightFormValidation = _weightForm.currentState?.validate();
@@ -132,7 +136,7 @@ class AddEntryFormState extends FormStateBase<AddEntryFormValue, AddEntryForm>
   AddEntryFormValue? save() {
     logger.fine('Calling save');
     if (!validate()) return null;
-    final time = _timeForm.currentState!.save()!;
+    final time = _timeForm.currentState?.save() ?? DateTime.now();
     Note? note;
     BloodPressureRecord? record = _lastSavedPressure;
     BodyweightRecord? weight = _lastSavedWeight;
app/lib/features/input/forms/date_time_form.dart
@@ -1,7 +1,7 @@
 import 'package:blood_pressure_app/features/input/forms/form_base.dart';
+import 'package:blood_pressure_app/l10n/app_localizations.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:flutter/material.dart';
-import 'package:blood_pressure_app/l10n/app_localizations.dart';
 import 'package:intl/intl.dart';
 import 'package:provider/provider.dart';
 
app/test/features/input/forms/add_entry_form_test.dart
@@ -567,6 +567,30 @@ void main() {
     await tester.pumpAndSettle();
     expect(find.byType(AlertDialog), findsNothing);
   });
+
+  testWidgets('saves measurement when time input is hidden', (tester) async {
+    final key = GlobalKey<AddEntryFormState>();
+    await tester.pumpWidget(materialApp(AddEntryForm(key: key),
+        settings: Settings(allowManualTimeInput: false),
+    ));
+
+    final fields = find.byType(TextField);
+    await tester.enterText(fields.at(0), '123'); // sys
+    await tester.enterText(fields.at(1), '45'); // dia
+    await tester.enterText(fields.at(2), '67'); // pul
+
+    expect(key.currentState!.validate(), true);
+    final res = key.currentState!.save();
+    expect(res, isNotNull);
+    expect(res?.record, isNotNull);
+    expect(res?.record?.sys?.mmHg, 123);
+    expect(res?.record?.dia?.mmHg, 45);
+    expect(res?.record?.pul, 67);
+    expect(res?.record?.time
+        .difference(DateTime.now())
+        .inMinutes
+        .abs(), lessThan(5));
+  });
 }
 
 /// A mock ble cubit that never does anything.
app/test/features/input/forms/date_time_form_test.dart
@@ -1,6 +1,6 @@
 import 'package:blood_pressure_app/features/input/forms/date_time_form.dart';
-import 'package:flutter/material.dart';
 import 'package:blood_pressure_app/l10n/app_localizations.dart';
+import 'package:flutter/material.dart';
 import 'package:flutter_test/flutter_test.dart';
 import 'package:intl/intl.dart';
 
@@ -38,7 +38,11 @@ void main() {
     await tester.tap(find.text(timeOfDayFormated));
     await tester.pumpAndSettle();
     expect(find.byType(TimePickerDialog), findsOneWidget);
-    final dialCenter = tester.getCenter(find.byKey(const ValueKey<String>('time-picker-dial')));
+    final Finder customPaintFinder = find.descendant(
+      of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_Dial'),
+      matching: find.byType(CustomPaint),
+    );
+    final dialCenter = tester.getCenter(customPaintFinder);
     await tester.tapAt(Offset(dialCenter.dx, dialCenter.dy + 10)); // 6 AM
     await tester.pumpAndSettle();
     await tester.tapAt(Offset(dialCenter.dx - 10, dialCenter.dy));  // 45
@@ -64,7 +68,11 @@ void main() {
 
     await tester.tap(find.text(DateFormat('HH:mm').format(initialTime)));
     await tester.pumpAndSettle();
-    final dialCenter = tester.getCenter(find.byKey(const ValueKey<String>('time-picker-dial')));
+    final Finder customPaintFinder = find.descendant(
+      of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_Dial'),
+      matching: find.byType(CustomPaint),
+    );
+    final dialCenter = tester.getCenter(customPaintFinder);
     await tester.tapAt(Offset(dialCenter.dx - 3, dialCenter.dy - 9.5));
     await tester.tap(find.text('PM')); // 11 PM
     await tester.pumpAndSettle();