Commit a1403ea

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2024-09-22 17:59:13
Allow deleting added weights (#433)
* implement delete button in weight list * test delete button in weight list * respect settings * test respects confirm deletion settings
1 parent 68ef21c
Changed files (3)
app
lib
features
measurement_list
test
features
measurement_list
app/lib/features/measurement_list/weight_list.dart
@@ -1,3 +1,4 @@
+import 'package:blood_pressure_app/components/confirm_deletion_dialoge.dart';
 import 'package:blood_pressure_app/data_util/repository_builder.dart';
 import 'package:blood_pressure_app/model/storage/storage.dart';
 import 'package:flutter/material.dart';
@@ -24,12 +25,21 @@ class WeightList extends StatelessWidget {
           itemCount: records.length,
           itemBuilder: (context, idx) => ListTile(
             title: Text(_buildWeightText(records[idx].weight)),
-            subtitle: Text(format.format(records[idx].time))
+            subtitle: Text(format.format(records[idx].time)),
+            trailing: IconButton(
+              icon: const Icon(Icons.delete),
+              onPressed: () async {
+                final repo = context.read<BodyweightRepository>();
+                if ((!context.read<Settings>().confirmDeletion) || await showConfirmDeletionDialoge(context)) {
+                  await repo.remove(records[idx]);
+                }
+              }
+            ),
           ),
         );
       },
     );
-  }// TODO: delete
+  }
 
   String _buildWeightText(Weight w) {
     String weightStr = w.kg.toStringAsFixed(2);
app/test/features/measurement_list/weight_list_test.dart
@@ -1,6 +1,8 @@
 import 'package:blood_pressure_app/features/measurement_list/weight_list.dart';
 import 'package:blood_pressure_app/model/storage/interval_store.dart';
+import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:flutter/material.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';
 
@@ -42,4 +44,62 @@ void main() {
       lessThan(tester.getCenter(find.textContaining('2000')).dy),
     );
   });
+  testWidgets('deletes elements from repo', (tester) async {
+    final interval = IntervalStorage();
+    interval.changeStepSize(TimeStep.lifetime);
+    final repo = MockBodyweightRepository();
+    await repo.add(BodyweightRecord(time: DateTime(2001), weight: Weight.kg(123.0)));
+
+    await tester.pumpWidget(appBase(
+      weightRepo: repo,
+      intervallStoreManager: IntervalStoreManager(interval, IntervalStorage(), IntervalStorage()),
+      const WeightList(rangeType: IntervalStoreManagerLocation.mainPage),
+    ));
+    final localizations = await AppLocalizations.delegate.load(const Locale('en'))!;
+    await tester.pumpAndSettle();
+
+    expect(find.text('123 kg'), findsOneWidget);
+    expect(find.byIcon(Icons.delete), findsOneWidget);
+    expect(find.text(localizations.confirmDelete), findsNothing);
+    expect(find.text(localizations.btnConfirm), findsNothing);
+
+    await tester.tap(find.byIcon(Icons.delete));
+    await tester.pumpAndSettle();
+
+    expect(find.text(localizations.confirmDelete), findsOneWidget);
+    expect(find.text(localizations.btnConfirm), findsOneWidget);
+
+    await tester.tap(find.text(localizations.btnConfirm));
+    await tester.pumpAndSettle();
+    await tester.pumpAndSettle();
+    await tester.pumpAndSettle();
+    await tester.pumpAndSettle();
+
+    expect(find.text('123 kg'), findsNothing);
+    expect(repo.data, isEmpty);
+  });
+  testWidgets('respects confirm deletion setting', (tester) async {
+    final interval = IntervalStorage();
+    interval.changeStepSize(TimeStep.lifetime);
+    final repo = MockBodyweightRepository();
+    await repo.add(BodyweightRecord(time: DateTime(2001), weight: Weight.kg(123.0)));
+
+    await tester.pumpWidget(appBase(
+      weightRepo: repo,
+      intervallStoreManager: IntervalStoreManager(interval, IntervalStorage(), IntervalStorage()),
+      settings: Settings(confirmDeletion: false),
+      const WeightList(rangeType: IntervalStoreManagerLocation.mainPage),
+    ));
+    final localizations = await AppLocalizations.delegate.load(const Locale('en'))!;
+    await tester.pumpAndSettle();
+
+    expect(find.text('123 kg'), findsOneWidget);
+    expect(find.text(localizations.confirmDelete), findsNothing);
+
+    await tester.tap(find.byIcon(Icons.delete));
+    await tester.pumpAndSettle();
+
+    expect(find.text(localizations.confirmDelete), findsNothing);
+    expect(find.text('123 kg'), findsNothing);
+  });
 }
app/test/util.dart
@@ -230,18 +230,25 @@ class MockHealthDataSore implements HealthDataStore {
 
 class _MockRepo<T> extends Repository<T> {
   List<T> data = [];
+  final contr = StreamController.broadcast();
 
   @override
-  Future<void> add(T value) async => data.add(value);
+  Future<void> add(T value) async {
+    data.add(value);
+    contr.sink.add(null);
+  }
 
   @override
   Future<List<T>> get(DateRange range) async => data;
 
   @override
-  Future<void> remove(T value) async => data.remove(value);
+  Future<void> remove(T value) async {
+    data.remove(value);
+    contr.sink.add(null);
+  }
 
   @override
-  Stream subscribe() => const Stream.empty(); // FIXME
+  Stream subscribe() => contr.stream;
 
   @override
   dynamic noSuchMethod(Invocation invocation) => throw Exception('unexpected call: $invocation');