main
  1import 'package:blood_pressure_app/features/input/add_entry_dialogue.dart';
  2import 'package:blood_pressure_app/features/input/forms/add_entry_form.dart';
  3import 'package:blood_pressure_app/features/settings/tiles/color_picker_list_tile.dart';
  4import 'package:blood_pressure_app/model/storage/settings_store.dart';
  5import 'package:flutter/material.dart';
  6import 'package:blood_pressure_app/l10n/app_localizations.dart';
  7import 'package:flutter_test/flutter_test.dart';
  8import 'package:health_data_store/health_data_store.dart';
  9
 10import '../../model/export_import/record_formatter_test.dart';
 11import '../../util.dart';
 12
 13void main() {
 14  testWidgets('respects bottomAppBars', (tester) async {
 15    final settings = Settings(bottomAppBars: false);
 16    await tester.pumpWidget(materialApp(const AddEntryDialogue(),
 17      settings: settings
 18    ));
 19    final initialHeights = tester.getCenter(find.byType(AppBar)).dy;
 20
 21    settings.bottomAppBars = true;
 22    await tester.pump();
 23
 24    expect(tester.getCenter(find.byType(AppBar)).dy, greaterThan(initialHeights));
 25  });
 26
 27  // TODO: update these old tests
 28  testWidgets('should show everything on initial page', (tester) async {
 29    await tester.pumpWidget(materialApp(const AddEntryDialogue()));
 30    expect(tester.takeException(), isNull);
 31
 32    expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 33    expect(find.text('SAVE'), findsOneWidget);
 34    expect(find.byIcon(Icons.close), findsOneWidget);
 35    expect(find.text('Systolic'), findsWidgets);
 36    expect(find.text('Diastolic'), findsWidgets);
 37    expect(find.text('Pulse'), findsWidgets);
 38    expect(find.byType(ColorSelectionListTile), findsOneWidget);
 39  },);
 40  testWidgets('should prefill initialRecord values', (tester) async {
 41    await tester.pumpWidget(materialApp(
 42      AddEntryDialogue(
 43        initialRecord: mockEntryPos(
 44          DateTime.now(), 123, 56, 43, 'Test note', Colors.teal,
 45        ).asAddEntry,
 46        availableMeds: const [],
 47      ),
 48    ),);
 49    await tester.pumpAndSettle();
 50    expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 51    expect(find.text('SAVE'), findsOneWidget);
 52    expect(find.byIcon(Icons.close), findsOneWidget);
 53    expect(find.text('Test note'), findsOneWidget);
 54    expect(find.text('123'), findsOneWidget);
 55    expect(find.text('56'), findsOneWidget);
 56    expect(find.text('43'), findsOneWidget);
 57    expect(find.byType(ColorSelectionListTile), findsOneWidget);
 58    tester.widget<ColorSelectionListTile>(find.byType(ColorSelectionListTile)).initialColor == Colors.teal;
 59  });
 60  testWidgets('should return null on cancel', (tester) async {
 61    dynamic result = 'result before save';
 62    await loadDialoge(tester, (context) async
 63    => result = await showAddEntryDialogue(context,
 64        medRepo(),
 65        mockEntry(sys: 123, dia: 56, pul: 43, note: 'Test note', pin: Colors.teal).asAddEntry));
 66    expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 67
 68    expect(find.byType(AddEntryDialogue), findsOneWidget);
 69    await tester.tap(find.byIcon(Icons.close));
 70    await tester.pumpAndSettle();
 71    expect(find.byType(AddEntryDialogue), findsNothing);
 72
 73    expect(result, null);
 74  });
 75  testWidgets('should not allow invalid values', (tester) async {
 76    final mRep = medRepo();
 77    await loadDialoge(tester, (context) => showAddEntryDialogue(context, mRep));
 78    final localizations = await AppLocalizations.delegate.load(const Locale('en'));
 79
 80    expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 81
 82    expect(find.byType(AddEntryDialogue), findsOneWidget);
 83    expect(find.text(localizations.errNaN), findsNothing);
 84    expect(find.text(localizations.errLt30), findsNothing);
 85    expect(find.text(localizations.errUnrealistic), findsNothing);
 86    expect(find.text(localizations.errDiaGtSys), findsNothing);
 87
 88    await tester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextField)), '123');
 89    await tester.enterText(find.ancestor(of: find.text('Diastolic').first, matching: find.byType(TextField)), '67');
 90
 91    await tester.tap(find.text('SAVE'));
 92    await tester.pumpAndSettle();
 93    expect(find.byType(AddEntryDialogue), findsOneWidget);
 94    expect(find.text(localizations.errNaN), findsOneWidget);
 95    expect(find.text(localizations.errLt30), findsNothing);
 96    expect(find.text(localizations.errUnrealistic), findsNothing);
 97    expect(find.text(localizations.errDiaGtSys), findsNothing);
 98
 99    await tester.enterText(find.ancestor(of: find.text('Pulse').first, matching: find.byType(TextField)), '20');
100    await tester.tap(find.text('SAVE'));
101    await tester.pumpAndSettle();
102    expect(find.byType(AddEntryDialogue), findsOneWidget);
103    expect(find.text(localizations.errNaN), findsNothing);
104    expect(find.text(localizations.errLt30), findsOneWidget);
105    expect(find.text(localizations.errUnrealistic), findsNothing);
106    expect(find.text(localizations.errDiaGtSys), findsNothing);
107
108    await tester.enterText(find.ancestor(of: find.text('Pulse').first, matching: find.byType(TextField)), '60');
109    await tester.enterText(find.ancestor(of: find.text('Diastolic').first, matching: find.byType(TextField)), '500');
110    await tester.tap(find.text('SAVE'));
111    await tester.pumpAndSettle();
112    expect(find.byType(AddEntryDialogue), findsOneWidget);
113    expect(find.text(localizations.errNaN), findsNothing);
114    expect(find.text(localizations.errLt30), findsNothing);
115    expect(find.text(localizations.errUnrealistic), findsOneWidget);
116    expect(find.text(localizations.errDiaGtSys), findsNothing);
117
118    await tester.enterText(find.ancestor(of: find.text('Diastolic').first, matching: find.byType(TextField)), '100');
119    await tester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextField)), '90');
120    await tester.tap(find.text('SAVE'));
121    await tester.pumpAndSettle();
122    expect(find.byType(AddEntryDialogue), findsOneWidget);
123    expect(find.text(localizations.errNaN), findsNothing);
124    expect(find.text(localizations.errLt30), findsNothing);
125    expect(find.text(localizations.errUnrealistic), findsNothing);
126    expect(find.text(localizations.errDiaGtSys), findsOneWidget);
127
128
129    await tester.enterText(find.ancestor(of: find.text('Diastolic').first, matching: find.byType(TextField)), '78');
130    await tester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextField)), '123');
131    await tester.tap(find.text('SAVE'));
132    await tester.pumpAndSettle();
133    expect(find.byType(AddEntryDialogue), findsNothing);
134    expect(find.text(localizations.errNaN), findsNothing);
135    expect(find.text(localizations.errLt30), findsNothing);
136    expect(find.text(localizations.errUnrealistic), findsNothing);
137    expect(find.text(localizations.errDiaGtSys), findsNothing);
138  });
139  testWidgets('should allow invalid values when setting is set', (tester) async {
140    final mRep = medRepo();
141    await loadDialoge(tester, (context) => showAddEntryDialogue(context, mRep),
142      settings: Settings(validateInputs: false, allowMissingValues: true),
143    );
144    expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
145
146    await tester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextField)), '2');
147    await tester.enterText(find.ancestor(of: find.text('Diastolic').first, matching: find.byType(TextField)), '500');
148    await tester.tap(find.text('SAVE'));
149    await tester.pumpAndSettle();
150    expect(find.byType(AddEntryDialogue), findsNothing);
151  });
152  testWidgets('should start with sys input focused', (tester) async {
153    final mRep = medRepo();
154    await loadDialoge(tester, (context) =>
155        showAddEntryDialogue(context, mRep, mockEntry(sys: 12).asAddEntry));
156    expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
157
158    final primaryFocus = FocusManager.instance.primaryFocus;
159    expect(primaryFocus?.context?.widget, isNotNull);
160    final focusedTextField = find.ancestor(
161      of: find.byWidget(primaryFocus!.context!.widget),
162      matching: find.byType(TextField),
163    );
164    expect(focusedTextField, findsOneWidget);
165    final field = tester.widget<TextField>(focusedTextField);
166    expect(field.controller?.text, '12');
167  });
168  testWidgets('should focus next on input finished', (tester) async {
169    final mRep = medRepo();
170    await loadDialoge(tester, (context) =>
171        showAddEntryDialogue(context, mRep, mockEntry(sys: 12, dia: 3, pul: 4, note: 'note').asAddEntry),);
172    expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
173
174    await tester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextField)), '123');
175
176    final firstFocused = FocusManager.instance.primaryFocus;
177    expect(firstFocused?.context?.widget, isNotNull);
178    final focusedTextField = find.ancestor(
179      of: find.byWidget(firstFocused!.context!.widget),
180      matching: find.byType(TextField),
181    );
182    expect(focusedTextField, findsOneWidget);
183    expect(focusedTextField.evaluate().first.widget, isA<TextField>()
184        .having((p0) => p0.controller?.text, 'diastolic content', '3'),);
185
186    await tester.enterText(find.ancestor(of: find.text('Diastolic').first, matching: find.byType(TextField)), '78');
187
188    final secondFocused = FocusManager.instance.primaryFocus;
189    expect(secondFocused?.context?.widget, isNotNull);
190    final secondFocusedTextField = find.ancestor(
191      of: find.byWidget(secondFocused!.context!.widget),
192      matching: find.byType(TextField),
193    );
194    expect(secondFocusedTextField, findsOneWidget);
195    expect(secondFocusedTextField.evaluate().first.widget, isA<TextField>()
196        .having((p0) => p0.controller?.text, 'pulse content', '4'),);
197
198    await tester.enterText(find.ancestor(of: find.text('Pulse').first, matching: find.byType(TextField)), '60');
199
200    final thirdFocused = FocusManager.instance.primaryFocus;
201    expect(thirdFocused?.context?.widget, isNotNull);
202    final thirdFocusedTextField = find.ancestor(
203      of: find.byWidget(thirdFocused!.context!.widget),
204      matching: find.byType(TextField),
205    );
206    expect(thirdFocusedTextField, findsOneWidget);
207    expect(find.descendant(of: thirdFocusedTextField, matching: find.text('Note (optional)')), findsOneWidget);
208  });
209}