PopScope 的 canPop 写的是 !_loggingOut,平时即为 true,所以原生返回手势会 直接把 HomePage 弹出、落回 Login Page;同时因为 didPop==true,回调里的 退登分支根本不会执行 —— 一个原因同时造成「回到登录页」和「账号没退出」, 留下一个会话仍在线的半退出状态。 改为 canPop:false 把根路由锁死在主页,返回意图交给 _exitApp:非 iOS 平台 走 SystemNavigator.pop 结束应用(iOS 不允许程序化退出,根路由也没有返回手势)。 AppBar 的退出按钮与风险操作完成后的 onExitToTitle 仍走 _performLogoutAndExit, 那两处是明确要回主标题。 新增回归用例:把 HomePage push 在占位根路由之上,触发 handlePopRoute, 断言 HomePage 仍在栈上且调用了 SystemNavigator.pop。
45 lines
1.6 KiB
Dart
45 lines
1.6 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
import 'package:ichino/pages/home_page.dart';
|
||
|
||
/// 主页上的系统返回手势不能把 HomePage 弹掉(那会落回 Login Page,
|
||
/// 而且退登逻辑因为 didPop==true 根本不会跑)。
|
||
void main() {
|
||
testWidgets('主页收到系统返回时结束应用而不是退回上一页', (tester) async {
|
||
final calls = <String>[];
|
||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||
.setMockMethodCallHandler(SystemChannels.platform, (call) async {
|
||
calls.add(call.method);
|
||
return null;
|
||
});
|
||
addTearDown(() {
|
||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||
.setMockMethodCallHandler(SystemChannels.platform, null);
|
||
});
|
||
|
||
await tester.pumpWidget(
|
||
const MaterialApp(home: Text('login-root')),
|
||
);
|
||
|
||
final navigator = tester.state<NavigatorState>(find.byType(Navigator));
|
||
navigator.push(
|
||
MaterialPageRoute(builder: (_) => const HomePage(userId: 1, token: 't')),
|
||
);
|
||
await tester.pumpAndSettle();
|
||
|
||
expect(find.text('login-root'), findsNothing);
|
||
expect(find.byType(HomePage), findsOneWidget);
|
||
|
||
await tester.binding.handlePopRoute();
|
||
await tester.pumpAndSettle();
|
||
|
||
// HomePage 仍在栈上:根路由被锁死。
|
||
expect(find.byType(HomePage), findsOneWidget);
|
||
expect(find.text('login-root'), findsNothing);
|
||
|
||
// 非 iOS 上应当走 SystemNavigator.pop 结束应用。
|
||
expect(calls, contains('SystemNavigator.pop'));
|
||
});
|
||
}
|