Commit 40463fb

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2024-04-07 16:17:21
migrate pumpAppRoot test util (26 failing)
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent a650e04
app/lib/components/dialoges/add_measurement_dialoge.dart
@@ -8,7 +8,6 @@ import 'package:blood_pressure_app/model/blood_pressure/record.dart';
 import 'package:blood_pressure_app/model/storage/storage.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:health_data_store/health_data_store.dart' hide BloodPressureRecord;
 import 'package:intl/intl.dart';
@@ -20,6 +19,7 @@ class AddEntryDialoge extends StatefulWidget {
   /// This is usually created through the [showAddEntryDialoge] function.
   const AddEntryDialoge({super.key,
     required this.settings,
+    required this.medRepo,
     this.initialRecord,
   });
 
@@ -35,6 +35,9 @@ class AddEntryDialoge extends StatefulWidget {
   /// saved separately.
   final BloodPressureRecord? initialRecord;
 
+  /// Repository that contains all selectable medicines.
+  final MedicineRepository medRepo;
+
   @override
   State<AddEntryDialoge> createState() => _AddEntryDialogeState();
 }
@@ -106,7 +109,7 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
       _measurementFormActive = true;
     }
 
-    RepositoryProvider.of<MedicineRepository>(context).getAll()
+    widget.medRepo.getAll()
         .then((value) => setState(() => availableMeds.addAll(value)));
 
     sysFocusNode.requestFocus();
@@ -431,6 +434,7 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
 Future<(BloodPressureRecord?, MedicineIntake?)?> showAddEntryDialoge(
     BuildContext context,
     Settings settings,
+    MedicineRepository medRepo,
     [BloodPressureRecord? initialRecord,]) =>
   showDialog<(BloodPressureRecord?, MedicineIntake?)>(
       context: context, builder: (context) =>
@@ -438,6 +442,7 @@ Future<(BloodPressureRecord?, MedicineIntake?)?> showAddEntryDialoge(
         child: AddEntryDialoge(
           settings: settings,
           initialRecord: initialRecord,
+          medRepo: medRepo,
         ),
       ),
   );
app/lib/components/measurement_list/measurement_list_entry.dart
@@ -3,7 +3,9 @@ import 'package:blood_pressure_app/model/blood_pressure/model.dart';
 import 'package:blood_pressure_app/model/blood_pressure/record.dart';
 import 'package:blood_pressure_app/model/storage/storage.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+import 'package:health_data_store/health_data_store.dart' hide BloodPressureRecord;
 import 'package:intl/intl.dart';
 import 'package:provider/provider.dart';
 
@@ -40,6 +42,7 @@ class MeasurementListRow extends StatelessWidget {
                   final model = Provider.of<BloodPressureModel>(context, listen: false);
                   final entry = await showAddEntryDialoge(context,
                     Provider.of<Settings>(context, listen: false),
+                    RepositoryProvider.of<MedicineRepository>(context),
                     record,
                   );
                   if (entry?.$1 != null) {
app/lib/screens/elements/legacy_measurement_list.dart
@@ -7,7 +7,9 @@ import 'package:blood_pressure_app/model/storage/intervall_store.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:blood_pressure_app/screens/elements/blood_pressure_builder.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+import 'package:health_data_store/health_data_store.dart' hide BloodPressureRecord;
 import 'package:intl/intl.dart';
 import 'package:provider/provider.dart';
 
@@ -87,6 +89,7 @@ class LegacyMeasurementsList extends StatelessWidget {
                                 final model = Provider.of<BloodPressureModel>(context, listen: false);
                                 final entry = await showAddEntryDialoge(context,
                                   Provider.of<Settings>(context, listen: false),
+                                  RepositoryProvider.of<MedicineRepository>(context),
                                   data[index],
                                 );
                                 if (entry?.$1 != null) {
app/lib/screens/home_screen.dart
@@ -35,7 +35,10 @@ class AppHome extends StatelessWidget {
         SchedulerBinding.instance.addPostFrameCallback((_) async {
           final model = Provider.of<BloodPressureModel>(context, listen: false);
           final intakes = RepositoryProvider.of<MedicineIntakeRepository>(context);
-          final measurement = await showAddEntryDialoge(context, Provider.of<Settings>(context, listen: false));
+          final measurement = await showAddEntryDialoge(context,
+            Provider.of<Settings>(context, listen: false),
+            RepositoryProvider.of<MedicineRepository>(context),
+          );
           if (measurement == null) return;
           if (measurement.$1 != null) {
             if (context.mounted) {
@@ -113,7 +116,10 @@ class AppHome extends StatelessWidget {
                       onPressed: () async {
                         final model = Provider.of<BloodPressureModel>(context, listen: false);
                         final intakes = RepositoryProvider.of<MedicineIntakeRepository>(context);
-                        final measurement = await showAddEntryDialoge(context, Provider.of<Settings>(context, listen: false));
+                        final measurement = await showAddEntryDialoge(context,
+                          Provider.of<Settings>(context, listen: false),
+                          RepositoryProvider.of<MedicineRepository>(context),
+                        );
                         if (measurement == null) return;
                         if (measurement.$1 != null) {
                           if (context.mounted) {
app/test/model/medicine/medicine_test.dart
@@ -49,7 +49,7 @@ void main() {
 
 final List<Medicine> _meds = [];
 
-/// Creates mock intake.
+/// Creates mock medicine.
 ///
 /// Medicines with the same properties will keep the correct id.
 Medicine mockMedicine({
app/test/ui/components/add_measurement_dialoge_test.dart
@@ -1,6 +1,5 @@
 import 'package:blood_pressure_app/components/dialoges/add_measurement_dialoge.dart';
 import 'package:blood_pressure_app/components/settings/color_picker_list_tile.dart';
-import 'package:blood_pressure_app/model/blood_pressure/medicine/medicine.dart';
 import 'package:blood_pressure_app/model/blood_pressure/medicine/medicine_intake.dart';
 import 'package:blood_pressure_app/model/blood_pressure/needle_pin.dart';
 import 'package:blood_pressure_app/model/blood_pressure/record.dart';
@@ -9,9 +8,9 @@ import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:flutter_test/flutter_test.dart';
+import 'package:health_data_store/health_data_store.dart' hide BloodPressureRecord;
 
 import '../../model/export_import/record_formatter_test.dart';
-import '../../model/medicine/medicine_test.dart';
 import 'settings/color_picker_list_tile_test.dart';
 import 'util.dart';
 
@@ -20,6 +19,7 @@ void main() {
     testWidgets('should show everything on initial page', (tester) async {
       await tester.pumpWidget(materialApp(
         AddEntryDialoge(
+          medRepo: await medRepo(),
           settings: Settings(),
         ),
       ),);
@@ -41,6 +41,7 @@ void main() {
             DateTime.now(), 123, 56, 43, 'Test note',
             needlePin: const MeasurementNeedlePin(Colors.teal),
           ),
+          medRepo: await medRepo(),
         ),
       ),);
       await tester.pumpAndSettle();
@@ -58,9 +59,8 @@ void main() {
     testWidgets('should show medication picker when medications available', (tester) async {
       await tester.pumpWidget(materialApp(
         AddEntryDialoge(
-          settings: Settings(
-            medications: [mockMedicine(designation: 'testmed')],
-          ),
+          settings: Settings(),
+          medRepo: await medRepo([mockMedicine(designation: 'testmed')]),
         ),
       ),);
       await tester.pumpAndSettle();
@@ -78,9 +78,8 @@ void main() {
     testWidgets('should reveal dosis on medication selection', (tester) async {
       await tester.pumpWidget(materialApp(
         AddEntryDialoge(
-          settings: Settings(
-            medications: [mockMedicine(designation: 'testmed')],
-          ),
+          settings: Settings(),
+          medRepo: await medRepo([mockMedicine(designation: 'testmed')]),
         ),
       ),);
       await tester.pumpAndSettle();
@@ -109,9 +108,8 @@ void main() {
     testWidgets('should enter default dosis if available', (tester) async {
       await tester.pumpWidget(materialApp(
         AddEntryDialoge(
-          settings: Settings(
-            medications: [mockMedicine(designation: 'testmed', defaultDosis: 3.1415)],
-          ),
+          settings: Settings(),
+          medRepo: await medRepo([mockMedicine(designation: 'testmed', defaultDosis: 3.1415)]),
         ),
       ),);
       await tester.pumpAndSettle();
@@ -127,9 +125,8 @@ void main() {
     testWidgets('should not quit when the measurement field is incorrectly filled, but a measurement is added', (tester) async {
       await tester.pumpWidget(materialApp(
         AddEntryDialoge(
-          settings: Settings(
-            medications: [mockMedicine(designation: 'testmed', defaultDosis: 3.1415)],
-          ),
+          settings: Settings(),
+          medRepo: await medRepo([mockMedicine(designation: 'testmed', defaultDosis: 3.1415)]),
         ),
       ),);
       await tester.pumpAndSettle();
@@ -161,6 +158,7 @@ void main() {
       dynamic result = 'result before save';
       await loadDialoge(tester, (context) async
       => result = await showAddEntryDialoge(context, Settings(),
+        await medRepo(),
         mockRecord(sys: 123, dia: 56, pul: 43, note: 'Test note', pin: Colors.teal),),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
@@ -175,7 +173,7 @@ void main() {
       dynamic result = 'result before save';
       final record = mockRecord(sys: 123, dia: 56, pul: 43, note: 'Test note', pin: Colors.teal);
       await loadDialoge(tester, (context) async
-      => result = await showAddEntryDialoge(context, Settings(), record),);
+      => result = await showAddEntryDialoge(context, Settings(), await medRepo(), record),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       expect(find.byType(AddEntryDialoge), findsOneWidget);
@@ -192,7 +190,7 @@ void main() {
     testWidgets('should be able to input records', (WidgetTester tester) async {
       dynamic result = 'result before save';
       await loadDialoge(tester, (context) async
-      => result = await showAddEntryDialoge(context, Settings()),);
+      => result = await showAddEntryDialoge(context, Settings(), await medRepo(),),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       await tester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextFormField)), '123');
@@ -221,7 +219,7 @@ void main() {
     testWidgets('should allow value only', (WidgetTester tester) async {
       dynamic result = 'result before save';
       await loadDialoge(tester, (context) async
-      => result = await showAddEntryDialoge(context, Settings()),);
+      => result = await showAddEntryDialoge(context, Settings(), await medRepo(),),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
       final localizations = await AppLocalizations.delegate.load(const Locale('en'));
 
@@ -251,7 +249,7 @@ void main() {
       => result = await showAddEntryDialoge(context, Settings(
         allowMissingValues: true,
         validateInputs: false,
-      ),),);
+      ), await medRepo(),),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       final localizations = await AppLocalizations.delegate.load(const Locale('en'));
@@ -276,12 +274,10 @@ void main() {
 
       dynamic result = 'result before save';
       await loadDialoge(tester, (context) async
-      => result = await showAddEntryDialoge(context, Settings(
-        medications: [
-          mockMedicine(designation: 'medication1'),
-          med2,
-        ],
-      ),),);
+      => result = await showAddEntryDialoge(context, Settings(), await medRepo([
+        mockMedicine(designation: 'medication1'),
+        med2,
+      ],),),);
       final localizations = await AppLocalizations.delegate.load(const Locale('en'));
 
       await tester.tap(find.byType(DropdownButton<Medicine?>));
@@ -313,7 +309,8 @@ void main() {
       );
     });
     testWidgets('should not allow invalid values', (tester) async {
-      await loadDialoge(tester, (context) => showAddEntryDialoge(context, Settings()));
+      final mRep = await medRepo();
+      await loadDialoge(tester, (context) => showAddEntryDialoge(context, Settings(), mRep));
       final localizations = await AppLocalizations.delegate.load(const Locale('en'));
 
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
@@ -376,8 +373,9 @@ void main() {
       expect(find.text(localizations.errDiaGtSys), findsNothing);
     });
     testWidgets('should allow invalid values when setting is set', (tester) async {
+      final mRep = await medRepo();
       await loadDialoge(tester, (context) =>
-          showAddEntryDialoge(context, Settings(validateInputs: false, allowMissingValues: true)),);
+          showAddEntryDialoge(context, Settings(validateInputs: false, allowMissingValues: true), mRep),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       await tester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextFormField)), '2');
@@ -387,15 +385,17 @@ void main() {
       expect(find.byType(AddEntryDialoge), findsNothing);
     });
     testWidgets('should respect settings.allowManualTimeInput', (tester) async {
+      final mRep = await medRepo();
       await loadDialoge(tester, (context) =>
-          showAddEntryDialoge(context, Settings(allowManualTimeInput: false)),);
+          showAddEntryDialoge(context, Settings(allowManualTimeInput: false), mRep),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       expect(find.byIcon(Icons.edit), findsNothing);
     });
     testWidgets('should start with sys input focused', (tester) async {
+      final mRep = await medRepo();
       await loadDialoge(tester, (context) =>
-          showAddEntryDialoge(context, Settings(), mockRecord(sys: 12)),);
+          showAddEntryDialoge(context, Settings(), mRep, mockRecord(sys: 12)),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       final primaryFocus = FocusManager.instance.primaryFocus;
@@ -409,8 +409,9 @@ void main() {
           .having((p0) => p0.initialValue, 'systolic content', '12'),);
     });
     testWidgets('should focus next on input finished', (tester) async {
+      final mRep = await medRepo();
       await loadDialoge(tester, (context) =>
-          showAddEntryDialoge(context, Settings(), mockRecord(sys: 12, dia: 3, pul: 4, note: 'note')),);
+          showAddEntryDialoge(context, Settings(), mRep, mockRecord(sys: 12, dia: 3, pul: 4, note: 'note')),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       await tester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextFormField)), '123');
@@ -451,8 +452,9 @@ void main() {
     });
 
     testWidgets('should focus last input field on backspace pressed in empty input field', (tester) async {
+      final mRep = await medRepo();
       await loadDialoge(tester, (context) =>
-          showAddEntryDialoge(context, Settings(), mockRecord(sys: 12, dia: 3, pul: 4, note: 'note')),);
+          showAddEntryDialoge(context, Settings(), mRep, mockRecord(sys: 12, dia: 3, pul: 4, note: 'note')),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       await tester.enterText(find.ancestor(of: find.text('note').first, matching: find.byType(TextFormField)), '');
@@ -511,11 +513,10 @@ void main() {
       expect(find.descendant(of: fourthFocusedTextFormField, matching: find.text('Systolic')), findsWidgets);
     });
     testWidgets('should allow entering custom dosis', (tester) async {
+      final mRep = await medRepo([mockMedicine(designation: 'testmed')]);
       dynamic result;
       await loadDialoge(tester, (context) async =>
-        result = await showAddEntryDialoge(context, Settings(
-          medications: [mockMedicine(designation: 'testmed')],
-        ),),
+        result = await showAddEntryDialoge(context, Settings(), mRep),
       );
 
       await tester.tap(find.byType(DropdownButton<Medicine?>));
@@ -547,11 +548,10 @@ void main() {
       );
     });
     testWidgets('should allow modifying entered dosis', (tester) async {
+      final mRep = await medRepo([mockMedicine(designation: 'testmed')]);
       dynamic result;
       await loadDialoge(tester, (context) async =>
-        result = await showAddEntryDialoge(context, Settings(
-          medications: [mockMedicine(designation: 'testmed')],
-        ),),
+        result = await showAddEntryDialoge(context, Settings(), mRep),
       );
       final localizations = await AppLocalizations.delegate.load(const Locale('en'));
 
@@ -588,8 +588,9 @@ void main() {
       );
     });
     testWidgets('should not go back to last field when the current field is still filled', (tester) async {
+      final mRep = await medRepo([mockMedicine(designation: 'testmed')]);
       await loadDialoge(tester, (context) =>
-          showAddEntryDialoge(context, Settings(), mockRecord(sys: 12, dia: 3, pul: 4, note: 'note')),);
+          showAddEntryDialoge(context, Settings(), mRep, mockRecord(sys: 12, dia: 3, pul: 4, note: 'note')),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       await tester.enterText(find.ancestor(
app/test/ui/components/measurement_list_entry_test.dart
@@ -62,7 +62,7 @@ void main() {
     expect(find.text('null'), findsNothing);
   });
   testWidgets('should open edit dialoge', (tester) async {
-    await tester.pumpWidget(appBase(MeasurementListRow(
+    await tester.pumpWidget(await appBase(MeasurementListRow(
       settings: Settings(), record: mockRecord(time: DateTime(2023),
         sys:1, dia: 2, pul: 3, note: 'testTxt',),),),);
     expect(find.byIcon(Icons.expand_more), findsOneWidget);
app/test/ui/components/util.dart
@@ -2,11 +2,12 @@ import 'package:blood_pressure_app/model/blood_pressure/medicine/intake_history.
 import 'package:blood_pressure_app/model/blood_pressure/model.dart';
 import 'package:blood_pressure_app/model/storage/storage.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:flutter_test/flutter_test.dart';
+import 'package:health_data_store/health_data_store.dart';
 import 'package:provider/provider.dart';
-
-import '../../ram_only_implementations.dart';
+import 'package:sqflite/sqflite.dart';
 
 /// Create a root material widget with localizations.
 Widget materialApp(Widget child) => MaterialApp(
@@ -17,7 +18,8 @@ Widget materialApp(Widget child) => MaterialApp(
 
 /// Create a root material widget with localizations and all providers but
 /// without a app root.
-Widget appBase(Widget child, {
+@Deprecated('replace with newAppBase')
+Future<Widget> appBase(Widget child, {
   Settings? settings,
   ExportSettings? exportSettings,
   CsvExportSettings? csvExportSettings,
@@ -25,28 +27,83 @@ Widget appBase(Widget child, {
   IntervallStoreManager? intervallStoreManager,
   IntakeHistory? intakeHistory,
   BloodPressureModel? model,
-}) {
-  model ??= RamBloodPressureModel();
+}) async {
+  // TODO: migrate arguments
+  final db = await HealthDataStore.load(await openDatabase(inMemoryDatabasePath));
+
+  final meds = settings?.medications.map((e) => Medicine(
+    designation: e.designation,
+    color: e.color.value,
+    dosis: e.defaultDosis != null ? Weight.mg(e.defaultDosis!) : null),
+  );
+  final medRepo = db.medRepo;
+  meds?.forEach(medRepo.add);
+
+  final intakeRepo = db.intakeRepo;
+  for (final e in intakeHistory?.getIntakes(DateTimeRange(
+      start: DateTime.fromMillisecondsSinceEpoch(0),
+      end: DateTime.fromMillisecondsSinceEpoch(999999999999))) ?? []) {
+    expect(meds, isNotNull);
+    expect(meds, isNotEmpty);
+    final med = meds!.firstWhere((e2) => e2.designation == e.medicine.designation);
+    intakeRepo.add(MedicineIntake(
+      time: e.timestamp,
+      dosis: Weight.mg(e.dosis),
+      medicine: med,
+    ));
+  }
+
+  return newAppBase(child,
+    settings: settings,
+    exportSettings: exportSettings,
+    csvExportSettings: csvExportSettings,
+    pdfExportSettings: pdfExportSettings,
+    intervallStoreManager: intervallStoreManager,
+    medRepo: medRepo,
+    intakeRepo: intakeRepo,
+  );
+
+  // TODO: bpRepo
+}
+/// Creates a the same App as the main method.
+Future<Widget> newAppBase(Widget child,  {
+  Settings? settings,
+  ExportSettings? exportSettings,
+  CsvExportSettings? csvExportSettings,
+  PdfExportSettings? pdfExportSettings,
+  IntervallStoreManager? intervallStoreManager,
+  BloodPressureRepository? bpRepo,
+  MedicineRepository? medRepo,
+  MedicineIntakeRepository? intakeRepo,
+}) async {
   settings ??= Settings();
   exportSettings ??= ExportSettings();
   csvExportSettings ??= CsvExportSettings();
   pdfExportSettings ??= PdfExportSettings();
-  intakeHistory ??= IntakeHistory([]);
   intervallStoreManager ??= IntervallStoreManager(IntervallStorage(), IntervallStorage(), IntervallStorage());
-  return MultiProvider(
+
+  HealthDataStore? db;
+  if  (bpRepo != null || medRepo != null || intakeRepo != null) {
+    db = await HealthDataStore.load(await openDatabase(inMemoryDatabasePath));
+  }
+
+  return MultiProvider(providers: [
+    ChangeNotifierProvider(create: (_) => settings),
+    ChangeNotifierProvider(create: (_) => exportSettings),
+    ChangeNotifierProvider(create: (_) => csvExportSettings),
+    ChangeNotifierProvider(create: (_) => pdfExportSettings),
+    ChangeNotifierProvider(create: (_) => intervallStoreManager),
+  ], child: MultiRepositoryProvider(
     providers: [
-      ChangeNotifierProvider(create: (_) => settings),
-      ChangeNotifierProvider(create: (_) => exportSettings),
-      ChangeNotifierProvider(create: (_) => csvExportSettings),
-      ChangeNotifierProvider(create: (_) => pdfExportSettings),
-      ChangeNotifierProvider(create: (_) => intakeHistory),
-      ChangeNotifierProvider(create: (_) => intervallStoreManager),
-      ChangeNotifierProvider<BloodPressureModel>(create: (_) => model!),
+      RepositoryProvider(create: (context) => bpRepo ?? db!.bpRepo),
+      RepositoryProvider(create: (context) => medRepo ?? db!.medRepo),
+      RepositoryProvider(create: (context) => intakeRepo ?? db!.intakeRepo),
     ],
-    child: materialApp(child),
-  );
+    child: child,
+  ),);
 }
 
+
 /// Open a dialoge through a button press.
 ///
 /// Example usage:
@@ -63,3 +120,39 @@ Future<void> loadDialoge(WidgetTester tester, void Function(BuildContext context
   await tester.tap(find.text(dialogeStarterText));
   await tester.pumpAndSettle();
 }
+
+/// Get empty mock med repo.
+Future<MedicineRepository>  medRepo([List<Medicine>? meds]) async  {
+  final db = await HealthDataStore.load(await openDatabase(inMemoryDatabasePath));
+  final repo = db.medRepo;
+  if (meds != null) {
+    for (final med in meds) {
+      await repo.add(med);
+    }
+  }
+  return repo;
+}
+
+final List<Medicine> _meds = [];
+
+/// Creates mock Medicine.
+///
+/// Medicines with the same properties will keep the correct id.
+Medicine mockMedicine({
+  Color color = Colors.black,
+  String designation = '',
+  double? defaultDosis,
+}) {
+  final matchingMeds = _meds.where((med) => med.dosis?.mg == defaultDosis
+    && med.color == color.value
+    && med.designation == designation,
+  );
+  if (matchingMeds.isNotEmpty) return matchingMeds.first;
+  final med = Medicine(
+    designation: designation,
+    color: color.value,
+    dosis: defaultDosis == null ? null : Weight.mg(defaultDosis),
+  );
+  _meds.add(med);
+  return med;
+}
app/test/ui/navigation_test.dart
@@ -13,11 +13,9 @@ import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:blood_pressure_app/screens/settings_screen.dart';
 import 'package:blood_pressure_app/screens/statistics_screen.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:flutter_test/flutter_test.dart';
-import 'package:health_data_store/health_data_store.dart';
-import 'package:provider/provider.dart';
-import 'package:sqflite/sqflite.dart';
+
+import 'components/util.dart';
 
 void main() {
   group('start page', () {
@@ -66,7 +64,6 @@ void main() {
 }
 
 /// Creates a the same App as the main method.
-@Deprecated('replaced by [newPumpAppRoot]')
 Future<void> pumpAppRoot(WidgetTester tester, {
   Settings? settings,
   ExportSettings? exportSettings,
@@ -76,79 +73,15 @@ Future<void> pumpAppRoot(WidgetTester tester, {
   IntakeHistory? intakeHistory,
   BloodPressureModel? model,
 }) async {
-  // TODO: migrate arguments
-  final db = await HealthDataStore.load(await openDatabase(inMemoryDatabasePath));
-
-  final meds = settings?.medications?.map((e) => Medicine(
-      designation: e.designation,
-      color: e.color.value,
-      dosis: e.defaultDosis != null ? Weight.mg(e.defaultDosis!) : null));
-  final medRepo = db.medRepo;
-  meds?.forEach(medRepo.add);
-
-  final intakeRepo = db.intakeRepo;
-  for (final e in intakeHistory?.getIntakes(DateTimeRange(
-      start: DateTime.fromMillisecondsSinceEpoch(0),
-      end: DateTime.fromMillisecondsSinceEpoch(999999999999))) ?? []) {
-    expect(meds, isNotNull);
-    expect(meds, isNotEmpty);
-    final med = meds!.firstWhere((e2) => e2.designation == e.medicine.designation);
-    intakeRepo.add(MedicineIntake(
-      time: e.timestamp,
-      dosis: Weight.mg(e.dosis),
-      medicine: med,
-    ));
-  }
-
-  // TODO: bpRepo
-
-  await newPumpAppRoot(tester,
+  await tester.pumpWidget(await appBase(const AppRoot(),
     settings: settings,
     exportSettings: exportSettings,
     csvExportSettings: csvExportSettings,
     pdfExportSettings: pdfExportSettings,
     intervallStoreManager: intervallStoreManager,
-    medRepo: medRepo,
-    intakeRepo: intakeRepo,
-  );
-}
-
-/// Creates a the same App as the main method.
-Future<void> newPumpAppRoot(WidgetTester tester, {
-  Settings? settings,
-  ExportSettings? exportSettings,
-  CsvExportSettings? csvExportSettings,
-  PdfExportSettings? pdfExportSettings,
-  IntervallStoreManager? intervallStoreManager,
-  BloodPressureRepository? bpRepo,
-  MedicineRepository? medRepo,
-  MedicineIntakeRepository? intakeRepo,
-}) async {
-  settings ??= Settings();
-  exportSettings ??= ExportSettings();
-  csvExportSettings ??= CsvExportSettings();
-  pdfExportSettings ??= PdfExportSettings();
-  intervallStoreManager ??= IntervallStoreManager(IntervallStorage(), IntervallStorage(), IntervallStorage());
-
-  HealthDataStore? db;
-  if  (bpRepo != null || medRepo != null || intakeRepo != null) {
-    db = await HealthDataStore.load(await openDatabase(inMemoryDatabasePath));
-  }
-
-  await tester.pumpWidget(MultiProvider(providers: [
-    ChangeNotifierProvider(create: (_) => settings),
-    ChangeNotifierProvider(create: (_) => exportSettings),
-    ChangeNotifierProvider(create: (_) => csvExportSettings),
-    ChangeNotifierProvider(create: (_) => pdfExportSettings),
-    ChangeNotifierProvider(create: (_) => intervallStoreManager),
-  ], child: MultiRepositoryProvider(
-    providers: [
-      RepositoryProvider(create: (context) => bpRepo ?? db!.bpRepo),
-      RepositoryProvider(create: (context) => medRepo ?? db!.medRepo),
-      RepositoryProvider(create: (context) => intakeRepo ?? db!.intakeRepo),
-    ],
-    child: const AppRoot(),
-  ),),);
+    intakeHistory: intakeHistory,
+    model: model,
+  ),);
 }
 
 class MockConfigDao implements ConfigDao {