Commit f768bf8

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2023-12-31 10:00:22
fix entering values
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent e1461f7
Changed files (2)
lib
components
test
lib/components/dialoges/add_measurement_dialoge.dart
@@ -29,6 +29,7 @@ class AddEntryDialoge extends StatefulWidget {
   ///
   /// When this is null the timestamp is [DateTime.now] and the other fields
   /// will be empty.
+  ///
   /// When an initial record is set medicine input is not possible because it is
   /// saved separately.
   final BloodPressureRecord? initialRecord;
@@ -64,7 +65,7 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
   /// Last [FormState.save]d note.
   String? notes;
   
-  /// Index of the medicine intake that can me entered here.
+  /// Index of the selected medicine in `widget.settings.medications`.
   int? medicineId;
 
   /// Whether to show the medication dosis input
@@ -112,7 +113,7 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
     ListTile(
       title: Text(DateFormat(widget.settings.dateFormatString).format(time)),
       trailing: const Icon(Icons.edit),
-      shape: buildListTileBorder(),
+      shape: buildShapeBorder(),
       onTap: () async {
         final messenger = ScaffoldMessenger.of(context);
         var selectedTime = await showDateTimePicker(
@@ -200,7 +201,8 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
     );
   }
 
-  RoundedRectangleBorder buildListTileBorder([Color? color]) => RoundedRectangleBorder(
+  /// Build the border all fields have.
+  RoundedRectangleBorder buildShapeBorder([Color? color]) => RoundedRectangleBorder(
     side: BorderSide(
       width: 2,
       color: color ?? Theme.of(context).primaryColor
@@ -224,8 +226,8 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
             );
           }
           BloodPressureRecord? record;
-          if (systolic != null && diastolic != null && pulse != null
-              && notes != null && needlePin != null) {
+          if (systolic != null || diastolic != null || pulse != null
+              || notes != null || needlePin != null) {
             record = BloodPressureRecord(time, systolic, diastolic, pulse, notes ?? '', needlePin: needlePin);
           }
 
@@ -293,7 +295,7 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
                 });
               },
               initialColor: needlePin?.color ?? Colors.transparent,
-              shape: buildListTileBorder(needlePin?.color)
+              shape: buildShapeBorder(needlePin?.color)
             ),
             if (widget.settings.medications.isNotEmpty && widget.initialRecord == null)
               Padding(
@@ -301,41 +303,35 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
                 child: Row(
                   children: [
                     Expanded(
-                      child: Ink(
-                        padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 4),
-                        decoration: ShapeDecoration(
-                          shape: buildListTileBorder()
-                        ),
-                        child: DropdownButton(
-                          isExpanded: true,
-                          value: widget.settings.medications
-                              .where((e) => e.id == medicineId).firstOrNull,
-                          underline: const SizedBox.shrink(),
-                          items: [
-                            for (final e in widget.settings.medications)
-                              DropdownMenuItem(
-                                value: e,
-                                child: Text(e.designation),
-                              ),
+                      child: DropdownButtonFormField(
+                        isExpanded: true,
+                        value: widget.settings.medications
+                            .where((e) => e.id == medicineId).firstOrNull,
+                        decoration: getInputDecoration(null),
+                        items: [
+                          for (final e in widget.settings.medications)
                             DropdownMenuItem(
-                              value: null,
-                              child: Text(localizations.noMedication),
-                            )
-                          ],
-                          onChanged: (v) {
-                            setState(() {
-                              if (v != null) {
-                                _showMedicineDosisInput = true;
-                                medicineId = v.id;
-                                medicineDosis = v.defaultDosis;
-                              } else {
-                                _showMedicineDosisInput = false;
-                                medicineId = null;
-                              }
-                              Material.of(context).markNeedsPaint();
-                            });
-                          }
-                        ),
+                              value: e,
+                              child: Text(e.designation),
+                            ),
+                          DropdownMenuItem(
+                            value: null,
+                            child: Text(localizations.noMedication),
+                          )
+                        ],
+                        onChanged: (v) {
+                          setState(() {
+                            if (v != null) {
+                              _showMedicineDosisInput = true;
+                              medicineId = v.id;
+                              medicineDosis = v.defaultDosis;
+                            } else {
+                              _showMedicineDosisInput = false;
+                              medicineId = null;
+                            }
+                            Material.of(context).markNeedsPaint();
+                          });
+                        }
                       ),
                     ),
                     if (_showMedicineDosisInput)
test/ui/components/add_measurement_dialoge_test.dart
@@ -127,7 +127,7 @@ void main() {
   });
   group('showAddEntryDialoge', () {
     testWidgets('should return null on cancel', (widgetTester) async {
-      dynamic result = 'not null';
+      dynamic result = 'result before save';
       await loadDialoge(widgetTester, (context) async
         => result = await showAddEntryDialoge(context, Settings(),
           mockRecord(sys: 123, dia: 56, pul: 43, note: 'Test note', pin: Colors.teal)));
@@ -141,7 +141,7 @@ void main() {
       expect(result, null);
     });
     testWidgets('should return values on edit cancel', (widgetTester) async {
-      dynamic result = 'not null';
+      dynamic result = 'result before save';
       final record = mockRecord(sys: 123, dia: 56, pul: 43, note: 'Test note', pin: Colors.teal);
       await loadDialoge(widgetTester, (context) async
         => result = await showAddEntryDialoge(context, Settings(), record));
@@ -159,7 +159,7 @@ void main() {
           (record.creationTime, record.systolic, record.diastolic, record.pulse, record.notes, record.needlePin!.color)));
     });
     testWidgets('should be able to input records', (WidgetTester widgetTester) async {
-      dynamic result = 'not null';
+      dynamic result = 'result before save';
       await loadDialoge(widgetTester, (context) async
         => result = await showAddEntryDialoge(context, Settings()));
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
@@ -187,10 +187,63 @@ void main() {
         .having((p0) => p0.needlePin?.color, 'needlePin', Colors.red)
       );
     });
+    testWidgets('should allow value only', (WidgetTester widgetTester) async {
+      dynamic result = 'result before save';
+      await loadDialoge(widgetTester, (context) async
+      => result = await showAddEntryDialoge(context, Settings()));
+      expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
+      final localizations = await AppLocalizations.delegate.load(const Locale('en'));
+
+      await widgetTester.enterText(find.ancestor(of: find.text(localizations.sysLong).first,
+          matching: find.byType(TextFormField)), '123');
+      await widgetTester.enterText(find.ancestor(of: find.text(localizations.diaLong).first,
+          matching: find.byType(TextFormField)), '67');
+      await widgetTester.enterText(find.ancestor(of: find.text(localizations.pulLong).first,
+          matching: find.byType(TextFormField)), '89');
+
+      expect(find.text(localizations.btnSave), findsOneWidget);
+      await widgetTester.tap(find.text(localizations.btnSave));
+      await widgetTester.pumpAndSettle();
+
+      expect(result?.$2, isNull);
+      expect(result?.$1, isA<BloodPressureRecord>()
+          .having((p0) => p0.systolic, 'systolic', 123)
+          .having((p0) => p0.diastolic, 'diastolic', 67)
+          .having((p0) => p0.pulse, 'pulse', 89)
+          .having((p0) => p0.notes, 'notes', '')
+          .having((p0) => p0.needlePin?.color, 'needlePin', null)
+      );
+    });
+    testWidgets('should allow note only', (WidgetTester widgetTester) async {
+      dynamic result = 'result before save';
+      await loadDialoge(widgetTester, (context) async
+      => result = await showAddEntryDialoge(context, Settings(
+        allowMissingValues: true,
+        validateInputs: false
+      )));
+      expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
+
+      final localizations = await AppLocalizations.delegate.load(const Locale('en'));
+      await widgetTester.enterText(find.ancestor(of: find.text(localizations.addNote).first,
+          matching: find.byType(TextFormField)), 'test note');
+
+      expect(find.text(localizations.btnSave), findsOneWidget);
+      await widgetTester.tap(find.text(localizations.btnSave));
+      await widgetTester.pumpAndSettle();
+
+      expect(result?.$2, isNull);
+      expect(result?.$1, isA<BloodPressureRecord>()
+          .having((p0) => p0.systolic, 'systolic', null)
+          .having((p0) => p0.diastolic, 'diastolic', null)
+          .having((p0) => p0.pulse, 'pulse', null)
+          .having((p0) => p0.notes, 'notes', 'test note')
+          .having((p0) => p0.needlePin?.color, 'needlePin', null)
+      );
+    });
     testWidgets('should be able to input medicines', (WidgetTester widgetTester) async {
       final med2 = mockMedicine(designation: 'medication2', defaultDosis: 31.415);
 
-      dynamic result = 'not null';
+      dynamic result = 'result before save';
       await loadDialoge(widgetTester, (context) async
       => result = await showAddEntryDialoge(context, Settings(
         medications: [
@@ -426,6 +479,5 @@ void main() {
       expect(fourthFocusedTextFormField, findsOneWidget);
       expect(find.descendant(of: fourthFocusedTextFormField, matching: find.text('Systolic')), findsWidgets);
     });
-    // TODO: test medicine_intake
   });
 }
\ No newline at end of file