Files
pangolin/client/test/widget/account_desktop_nav_test.dart
T
wangjia b839c77712 feat(account): IA 重排+邀请入口+删偏好卡+设置/联系 formFactor 门控
账户页重排为:账户信息 → 购买套餐/我的订单/兑换码(三行合一) → 邀请好友(新增,
gift 图标+t.inviteEntry/inviteEntrySub,接 NavView.invite) → 设备(常显)/
设置/联系(仅 mobile,桌面侧栏已有同入口,formFactor 门控避免重复) → 退出。
删语言/主题/协议卡及仅供其用的 _LangSwitch/_PangolinSwitch(l10n getter 保留,
Settings 页仍用)。_NavRow 加可选 subtitle 用于邀请卡副标题。

新增 InviteScreen(client/lib/screens/invite_page.dart)占位屏:邀请码/链接卡
(可复制,值写死 PANGOLIN-DEMO)+ 奖励规则三条 + 我的奖励占位卡,顶部
TODO(spec-2) 标注接口点(邀请码/链接由后端签发,奖励进度来自 /v1/invite)。

顺带修复 desktop_shell.dart 非穷尽 switch 编译错误(NavView 加 invite 后未接线,
整个 client 目前无法编译);notifications 分支占位回落账户页,留给 Task 6 接线。

test/widget/account_ia_test.dart 新增桌面态 IA 结构断言(邀请入口存在/语言不在/
兑换在);account_desktop_nav_test.dart 同步去掉桌面态设置/联系两个失效断言
(改走桌面侧栏,非账户卡),加邀请入口断言。desktop/tablet 账户页 golden 重录。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 17:44:51 +08:00

106 lines
4.2 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// account_desktop_nav_test.dart — 复现 Windows/桌面账户页子导航点击是否切 navView。
//
// 用 debugDefaultTargetPlatformOverride=windows + 宽 surface 让 context.formFactor==desktop
// 渲染 DesktopShell 账户页,点每个 _NavRow,断言 navViewProvider 切到对应子视图。
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pangolin_vpn/bridge/vpn_bridge_mock.dart';
import 'package:pangolin_vpn/bridge/vpn_bridge_provider.dart';
import 'package:pangolin_vpn/l10n/app_text.dart';
import 'package:pangolin_vpn/l10n/strings_zh.dart';
import 'package:pangolin_vpn/pangolin_theme.dart';
import 'package:pangolin_vpn/screens/account_page.dart';
import 'package:pangolin_vpn/services/token_store.dart';
import 'package:pangolin_vpn/shell/desktop_shell.dart';
import 'package:pangolin_vpn/shell/home_shell.dart';
import 'package:pangolin_vpn/state/app_providers.dart';
import 'package:pangolin_vpn/state/auth_provider.dart';
import 'package:pangolin_vpn/state/navigation_provider.dart';
import '../helpers/harness.dart';
final AppText t = StringsZh();
class _NullTokenStore implements TokenStore {
const _NullTokenStore();
@override
Future<void> saveTokens({required String access, required String refresh}) async {}
@override
Future<String?> loadAccessToken() async => null;
@override
Future<String?> loadRefreshToken() async => null;
@override
Future<void> clear() async {}
@override
Future<void> markOnboarded() async {}
@override
Future<bool> isOnboarded() async => true;
@override
Future<void> saveLastEmail(String email) async {}
@override
Future<String?> loadLastEmail() async => null;
}
/// 在桌面态渲染 DesktopShell(起始 account 视图),点账户卡里 [label] 那一行,
/// 返回点击后的 navViewProvider 值。
Future<NavView> _tapRow(WidgetTester tester, String label) async {
debugDefaultTargetPlatformOverride = TargetPlatform.windows;
tester.view.physicalSize = const Size(920, 1400);
tester.view.devicePixelRatio = 1.0;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
try {
await tester.pumpWidget(ProviderScope(
overrides: [
tokenStoreProvider.overrideWithValue(const _NullTokenStore()),
vpnBridgeProvider.overrideWithValue(VpnBridgeMock()),
appTextProvider.overrideWithValue(t),
navViewProvider.overrideWith((ref) => NavView.account),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: PangolinTheme.light,
home: const HomeShell(),
),
));
await tester.pumpAndSettle();
expect(find.byType(DesktopShell), findsOneWidget);
expect(find.byType(AccountPage), findsOneWidget);
// 侧栏与账户卡可能共享同一文案(设置/联系我们),故限定在 AccountPage 内。
final row = find.descendant(of: find.byType(AccountPage), matching: find.text(label));
expect(row, findsOneWidget, reason: '账户卡里应有且仅有一行「$label');
final container = ProviderScope.containerOf(tester.element(find.byType(HomeShell)));
expect(container.read(navViewProvider), NavView.account);
await tester.tap(row);
await tester.pump();
return container.read(navViewProvider);
} finally {
debugDefaultTargetPlatformOverride = null;
}
}
void main() {
setUpAll(disableGoogleFontsFetching);
// 注:设置/联系已从桌面态账户卡移除(IA 重构后仅 mobile/tablet 在账户页下钻,
// 桌面走侧栏 NavSidebar 的 t.settingsTitle/t.contactTitle 入口,非本文件覆盖范围)。
testWidgets('desktop account -> redeem', (tester) async {
expect(await _tapRow(tester, t.redeemEntry), NavView.redeem);
});
testWidgets('desktop account -> orders', (tester) async {
expect(await _tapRow(tester, t.ordersTitle), NavView.orders);
});
testWidgets('desktop account -> devices', (tester) async {
expect(await _tapRow(tester, t.myDevices), NavView.devices);
});
testWidgets('desktop account -> invite', (tester) async {
expect(await _tapRow(tester, t.inviteEntry), NavView.invite);
});
}