diff --git a/lib/screens/profile/pin_entry_dialog.dart b/lib/screens/profile/pin_entry_dialog.dart index 5469a898..d3d75df9 100644 --- a/lib/screens/profile/pin_entry_dialog.dart +++ b/lib/screens/profile/pin_entry_dialog.dart @@ -57,14 +57,16 @@ class _PinEntryDialogState extends State with SingleTickerProvid super.dispose(); } + bool get _isCurrentRoute => mounted && ModalRoute.of(context)?.isCurrent == true; + void _submit(String pin) { - if (_completed) return; + if (_completed || !_isCurrentRoute) return; _completed = true; Navigator.of(context).pop(pin); } void _cancel() { - if (_completed) return; + if (_completed || !_isCurrentRoute) return; _completed = true; Navigator.of(context).pop(); } diff --git a/test/widgets/pin_entry_dialog_test.dart b/test/widgets/pin_entry_dialog_test.dart index 149d64a5..48da4898 100644 --- a/test/widgets/pin_entry_dialog_test.dart +++ b/test/widgets/pin_entry_dialog_test.dart @@ -126,6 +126,68 @@ void main() { expect(find.byType(PinEntryDialog), findsNothing); }); + testWidgets('mobile auto-submit after external dismiss does not pop route below PIN dialog', (tester) async { + TvDetectionService.debugSetAppleTVOverride(false); + final navigatorKey = GlobalKey(); + String? pinResult = 'unchanged'; + bool? boolRouteResult; + + await tester.pumpWidget( + MaterialApp( + navigatorKey: navigatorKey, + theme: ThemeData(platform: TargetPlatform.iOS), + home: Builder( + builder: (context) { + return Scaffold( + body: TextButton( + onPressed: () async { + boolRouteResult = await Navigator.of(context).push( + MaterialPageRoute( + builder: (routeContext) { + return Scaffold( + body: Column( + children: [ + const Text('External Bool Route'), + TextButton( + onPressed: () async { + pinResult = await showPinEntryDialog(routeContext, 'Protected Profile'); + }, + child: const Text('Open External PIN'), + ), + ], + ), + ); + }, + ), + ); + }, + child: const Text('Open External Bool Route'), + ), + ); + }, + ), + ), + ); + + await tester.tap(find.text('Open External Bool Route')); + await tester.pumpAndSettle(); + await tester.tap(find.text('Open External PIN')); + await tester.pumpAndSettle(); + + final field = find.byType(TextField); + await tester.showKeyboard(field); + await tester.enterText(field, '1234'); + navigatorKey.currentState!.pop(); + await tester.pump(); + await tester.pumpAndSettle(); + + expect(tester.takeException(), isNull); + expect(pinResult, isNull); + expect(boolRouteResult, isNull); + expect(find.text('External Bool Route'), findsOneWidget); + expect(find.byType(PinEntryDialog), findsNothing); + }); + testWidgets('D-pad keypad enters and submits PIN', (tester) async { TvDetectionService.debugSetAppleTVOverride(true); String? result;