import 'package:flutter/material.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:meshcore_sar_app/l10n/app_localizations.dart'; import 'package:meshcore_sar_app/providers/connection_provider.dart'; import 'package:meshcore_sar_app/widgets/connection_dialog.dart'; import 'package:provider/provider.dart'; class _FakeConnectionProvider extends ConnectionProvider { int startScanCalls = 0; int stopScanCalls = 0; bool _isScanning = false; @override bool get isScanning => _isScanning; @override List get scannedDevices => const []; @override String? get error => null; @override Future startScan() async { startScanCalls += 1; _isScanning = true; notifyListeners(); } @override Future stopScan() async { stopScanCalls += 1; _isScanning = false; notifyListeners(); } } class _ConnectableFakeConnectionProvider extends ConnectionProvider { int connectCalls = 0; @override List get scannedDevices => [ ScannedDevice(device: BluetoothDevice.fromId('test-device'), rssi: -55), ]; @override String? get error => null; @override Future connect(BluetoothDevice device) async { connectCalls += 1; return true; } } void main() { testWidgets('BLE scan waits for explicit user action', (tester) async { final connectionProvider = _FakeConnectionProvider(); await tester.pumpWidget( ChangeNotifierProvider.value( value: connectionProvider, child: MaterialApp( localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, home: const Scaffold(body: ConnectionDialog()), ), ), ); await tester.pump(); expect(connectionProvider.startScanCalls, 0); expect( find.text('Press scan to search for nearby devices'), findsOneWidget, ); expect(find.text('Scan'), findsOneWidget); await tester.tap(find.widgetWithText(FilledButton, 'Scan')); await tester.pump(); expect(connectionProvider.stopScanCalls, 1); expect(connectionProvider.startScanCalls, 1); }); testWidgets('successful BLE connect closes the dialog immediately', ( tester, ) async { final connectionProvider = _ConnectableFakeConnectionProvider(); await tester.pumpWidget( ChangeNotifierProvider.value( value: connectionProvider, child: MaterialApp( localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, home: Builder( builder: (context) => Scaffold( body: Center( child: FilledButton( onPressed: () { showModalBottomSheet( context: context, isScrollControlled: true, builder: (_) => const ConnectionDialog(), ); }, child: const Text('Open'), ), ), ), ), ), ), ); await tester.tap(find.text('Open')); await tester.pumpAndSettle(); expect(find.byType(ConnectionDialog), findsOneWidget); await tester.tap(find.widgetWithText(FilledButton, 'Connect')); await tester.pumpAndSettle(); expect(connectionProvider.connectCalls, 1); expect(find.byType(ConnectionDialog), findsNothing); }); }