Commit 2c67b37

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2024-05-08 07:46:25
increase bluetooth cubit coverage and fix assertions
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent 153133a
app/lib/bluetooth/ble_read_cubit.dart
@@ -1,6 +1,6 @@
 import 'dart:async';
 
-import 'package:blood_pressure_app/bluetooth/logging.dart';
+import 'package:blood_pressure_app/logging.dart';
 import 'package:collection/collection.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/foundation.dart';
app/lib/bluetooth/bluetooth_cubit.dart
@@ -2,6 +2,7 @@ import 'dart:async';
 import 'dart:io';
 
 import 'package:blood_pressure_app/bluetooth/flutter_blue_plus_mockable.dart';
+import 'package:blood_pressure_app/logging.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:flutter_blue_plus/flutter_blue_plus.dart';
@@ -35,44 +36,52 @@ class BluetoothCubit extends Cubit<BluetoothState> {
     await super.close();
   }
 
-  void _onAdapterStateChanged(BluetoothAdapterState state) {
+  void _onAdapterStateChanged(BluetoothAdapterState state) async {
     _adapterState = state;
     switch (_adapterState) {
       case BluetoothAdapterState.unavailable:
         emit(BluetoothUnfeasible());
       case BluetoothAdapterState.unauthorized:
         emit(BluetoothUnauthorized());
+        await requestPermission();
       case BluetoothAdapterState.on:
         emit(BluetoothReady());
       case BluetoothAdapterState.off:
       case BluetoothAdapterState.turningOff:
       case BluetoothAdapterState.turningOn:
         emit(BluetoothDisabled());
+        await enableBluetooth();
       case BluetoothAdapterState.unknown:
         emit(BluetoothInitial());
     }
+  }
 
-    /// Request the permission to connect to bluetooth devices.
-    Future<bool> requestPermission() async {
-      assert(_adapterState == BluetoothAdapterState.unauthorized, 'No need to '
-          'request permission when device unavailable or already authorized.');
-      assert(await Permission.bluetoothConnect.isGranted, 'Permissions handler'
+  /// Request the permission to connect to bluetooth devices.
+  Future<bool> requestPermission() async {
+    assert(_adapterState == BluetoothAdapterState.unauthorized, 'No need to '
+        'request permission when device unavailable or already authorized.');
+    try {
+      assert(!await Permission.bluetoothConnect.isGranted, 'Permissions handler'
           'should report the same as blue_plus');
       final permission = await Permission.bluetoothConnect.request();
       return permission.isGranted;
+    } catch (error) {
+      Log.err('Failed to request bluetooth permissions', [error]);
+      return false;
     }
 
-    /// Request to enable bluetooth on the device
-    Future<bool> enableBluetooth() async {
-      assert(state is BluetoothDisabled, 'No need to enable bluetooth when '
-          'already enabled or not known to be disabled.');
+  }
+
+  /// Request to enable bluetooth on the device
+  Future<bool> enableBluetooth() async {
+    assert(state is BluetoothDisabled, 'No need to enable bluetooth when '
+        'already enabled or not known to be disabled.');
+    try {
       if (!Platform.isAndroid) return false;
-      try {
-        await _flutterBluePlus.turnOn();
-        return true;
-      } on FlutterBluePlusException {
-        return false;
-      }
+      await _flutterBluePlus.turnOn();
+      return true;
+    } on FlutterBluePlusException {
+      return false;
     }
   }
 }
app/lib/bluetooth/device_scan_cubit.dart
@@ -2,7 +2,7 @@ import 'dart:async';
 
 import 'package:blood_pressure_app/bluetooth/bluetooth_cubit.dart';
 import 'package:blood_pressure_app/bluetooth/flutter_blue_plus_mockable.dart';
-import 'package:blood_pressure_app/bluetooth/logging.dart';
+import 'package:blood_pressure_app/logging.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:collection/collection.dart';
 import 'package:flutter/foundation.dart';
app/lib/bluetooth/logging.dart → app/lib/logging.dart
File renamed without changes
app/test/bluetooth/ble_read_cubit_test.dart
@@ -1,5 +1,5 @@
 import 'package:blood_pressure_app/bluetooth/ble_read_cubit.dart';
-import 'package:blood_pressure_app/bluetooth/logging.dart';
+import 'package:blood_pressure_app/logging.dart';
 import 'package:flutter_blue_plus/flutter_blue_plus.dart';
 import 'package:flutter_test/flutter_test.dart';
 import 'package:mockito/annotations.dart';
app/test/bluetooth/bluetooth_cubit_test.dart
@@ -2,16 +2,21 @@ import 'dart:async';
 
 import 'package:blood_pressure_app/bluetooth/bluetooth_cubit.dart';
 import 'package:blood_pressure_app/bluetooth/flutter_blue_plus_mockable.dart';
+import 'package:blood_pressure_app/logging.dart';
+import 'package:flutter/widgets.dart';
 import 'package:flutter_blue_plus/flutter_blue_plus.dart';
 import 'package:flutter_test/flutter_test.dart';
 import 'package:mockito/annotations.dart';
 import 'package:mockito/mockito.dart';
 
-@GenerateNiceMocks([MockSpec<FlutterBluePlusMockable>()])
+@GenerateNiceMocks([
+  MockSpec<FlutterBluePlusMockable>(),
+])
 import 'bluetooth_cubit_test.mocks.dart';
 
 void main() {
   test('should translate adapter stream to state', () async {
+    WidgetsFlutterBinding.ensureInitialized();
     final bluePlus = MockFlutterBluePlusMockable();
     when(bluePlus.adapterState).thenAnswer((_) =>
       Stream.fromIterable([
@@ -23,6 +28,7 @@ void main() {
         BluetoothAdapterState.turningOn,
         BluetoothAdapterState.on,
     ]));
+    Log.testExpectError = true;
     final cubit = BluetoothCubit(flutterBluePlus: bluePlus);
     expect(cubit.state, isA<BluetoothInitial>());
 
@@ -35,8 +41,6 @@ void main() {
       isA<BluetoothDisabled>(),
       isA<BluetoothReady>(),
     ]));
+    Log.testExpectError = false;
   });
-  // TODO: integration tests ?
-  test('should request permissions', () async {});
-  test('should enable bluetooth', () async {});
 }
app/pubspec.lock
@@ -464,18 +464,18 @@ packages:
     dependency: transitive
     description:
       name: leak_tracker
-      sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
+      sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
       url: "https://pub.dev"
     source: hosted
-    version: "10.0.5"
+    version: "10.0.4"
   leak_tracker_flutter_testing:
     dependency: transitive
     description:
       name: leak_tracker_flutter_testing
-      sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
+      sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
       url: "https://pub.dev"
     source: hosted
-    version: "3.0.5"
+    version: "3.0.3"
   leak_tracker_testing:
     dependency: transitive
     description:
@@ -520,18 +520,18 @@ packages:
     dependency: transitive
     description:
       name: material_color_utilities
-      sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
+      sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
       url: "https://pub.dev"
     source: hosted
-    version: "0.11.1"
+    version: "0.8.0"
   meta:
     dependency: transitive
     description:
       name: meta
-      sha256: "25dfcaf170a0190f47ca6355bdd4552cb8924b430512ff0cafb8db9bd41fe33b"
+      sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
       url: "https://pub.dev"
     source: hosted
-    version: "1.14.0"
+    version: "1.12.0"
   mime:
     dependency: transitive
     description:
@@ -941,10 +941,10 @@ packages:
     dependency: transitive
     description:
       name: test_api
-      sha256: "2419f20b0c8677b2d67c8ac4d1ac7372d862dc6c460cdbb052b40155408cd794"
+      sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
       url: "https://pub.dev"
     source: hosted
-    version: "0.7.1"
+    version: "0.7.0"
   timing:
     dependency: transitive
     description: