test: 按新 UI 基线重写过期用例
覆盖 155 条失败与 4 处编译错误:入口改走推荐流 tab、弹框换 AppGlowDialog、 rail 尺寸与底部锚定、子页标题字重 w400、底栏选中品牌红、收藏文案改收藏短剧。 全量 flutter test 775 通过。
This commit is contained in:
1 parent
799f3d1b7d
commit
1d4ab5e0e6
33 files changed
+853
-1114
No files matched your search
@@ -3,15 +3,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fruitshorts/app.dart';
|
||||
import 'package:fruitshorts/core/data/models/drama.dart';
|
||||
import 'package:fruitshorts/core/data/models/page_result.dart';
|
||||
import 'package:fruitshorts/core/data/models/wallet.dart';
|
||||
import 'package:fruitshorts/core/data/models/watch_progress.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/commerce_repository.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/favorite_repository.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/playback_repository.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart';
|
||||
import 'package:fruitshorts/core/data/services/auth_controller.dart';
|
||||
import 'package:fruitshorts/core/theme/app_colors.dart';
|
||||
import 'package:fruitshorts/core/theme/app_dimens.dart';
|
||||
import 'package:fruitshorts/core/theme/app_theme.dart';
|
||||
@@ -21,8 +18,6 @@ import 'package:fruitshorts/pages/mine/about_page.dart';
|
||||
import 'package:fruitshorts/pages/mine/mine_types.dart';
|
||||
import 'package:fruitshorts/pages/mine/widgets/mine_menu.dart';
|
||||
import 'package:fruitshorts/pages/store/vip_page.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart';
|
||||
import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart';
|
||||
|
||||
@@ -33,7 +28,7 @@ import '../support/fake_notice_repository.dart';
|
||||
import '../support/widget_player.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('should_render_visitor_user_vip_and_eight_grid_entries', (
|
||||
testWidgets('should_render_visitor_header_vip_quick_actions_and_services', (
|
||||
tester,
|
||||
) async {
|
||||
await _pumpApp(tester, signedIn: false);
|
||||
@@ -46,14 +41,11 @@ void main() {
|
||||
expect(find.byKey(const Key('mine-uid-copy')), findsOneWidget);
|
||||
final uidRowSize = tester.getSize(find.byKey(const Key('mine-uid')));
|
||||
expect(uidRowSize.height, closeTo(AppDimens.mineUidRowHeight, 0.1));
|
||||
final nicknameRect = tester.getRect(find.byKey(const Key('mine-nickname')));
|
||||
final uidRect = tester.getRect(find.byKey(const Key('mine-uid')));
|
||||
expect(uidRect.top - nicknameRect.bottom, lessThanOrEqualTo(6));
|
||||
final nickname = tester.widget<Text>(
|
||||
find.byKey(const Key('mine-nickname')),
|
||||
);
|
||||
expect(nickname.style?.fontSize, AppDimens.mineUserName);
|
||||
expect(nickname.style?.fontWeight, FontWeight.w700);
|
||||
expect(nickname.style?.fontWeight, FontWeight.w400);
|
||||
expect(nickname.style?.height, AppDimens.mineUserNameLineHeight);
|
||||
final uid = tester.widget<Text>(find.text('UID: --'));
|
||||
expect(uid.style?.fontSize, AppDimens.mineUid);
|
||||
@@ -70,14 +62,8 @@ void main() {
|
||||
expect(find.byKey(const Key('mine-edit')), findsNothing);
|
||||
expect(find.byKey(const Key('mine-vip')), findsOneWidget);
|
||||
expect(find.byKey(const Key('mine-vip-open')), findsOneWidget);
|
||||
expect(find.byKey(const Key('mine-continue-watching')), findsNothing);
|
||||
expect(find.byKey(const Key('mine-stats')), findsOneWidget);
|
||||
expect(_statValue(tester, const Key('mine-stat-following')), '3');
|
||||
expect(_statValue(tester, const Key('mine-stat-watch-records')), '0');
|
||||
expect(_statValue(tester, const Key('mine-stat-coins')), '—');
|
||||
expect(find.byKey(const Key('mine-menu')), findsOneWidget);
|
||||
expect(find.byKey(const Key('mine-more-services')), findsOneWidget);
|
||||
expect(find.byKey(const Key('mine-mini-player')), findsNothing);
|
||||
|
||||
final surface = tester.widget<DecoratedBox>(
|
||||
find.byKey(const Key('mine-page-surface')),
|
||||
);
|
||||
@@ -86,160 +72,64 @@ void main() {
|
||||
expect(background.begin, Alignment.topCenter);
|
||||
expect(background.end, Alignment.bottomCenter);
|
||||
expect(background.colors, const [
|
||||
AppColors.mineGradientTop,
|
||||
AppColors.mineGradientMiddle,
|
||||
AppColors.mineGradientBottom,
|
||||
AppColors.followingGlow,
|
||||
AppColors.followingGlowMid,
|
||||
AppColors.appBackground,
|
||||
]);
|
||||
expect(background.stops, const [0, 0.4, 0.75]);
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byKey(const Key('mine-page-surface')),
|
||||
matching: find.text('My'),
|
||||
),
|
||||
findsNothing,
|
||||
);
|
||||
final glow = tester.widget<DecoratedBox>(
|
||||
find.byKey(const Key('mine-page-glow')),
|
||||
);
|
||||
final glowDecoration = glow.decoration as BoxDecoration;
|
||||
final radialGlow = glowDecoration.gradient! as RadialGradient;
|
||||
expect(radialGlow.center, const Alignment(0, -0.95));
|
||||
expect(radialGlow.radius, 0.9);
|
||||
expect(radialGlow.colors, const [
|
||||
AppColors.mineGradientGlow,
|
||||
AppColors.transparent,
|
||||
]);
|
||||
for (final oldShortcut in const [
|
||||
Key('mine-watchlist'),
|
||||
Key('mine-history-shortcut'),
|
||||
Key('mine-downloads-shortcut'),
|
||||
]) {
|
||||
expect(find.byKey(oldShortcut), findsNothing);
|
||||
}
|
||||
expect(background.stops, const [0, 0.14, 0.3]);
|
||||
|
||||
const entryKeys = [
|
||||
Key('mine-wallet'),
|
||||
Key('mine-downloads'),
|
||||
Key('mine-history'),
|
||||
Key('mine-watch-preferences'),
|
||||
Key('mine-help'),
|
||||
Key('mine-language'),
|
||||
Key('mine-settings'),
|
||||
Key('mine-notices'),
|
||||
// 快捷图标行:钱包 / 收藏 / 离线缓存 / 观看历史。
|
||||
const quickActions = [
|
||||
(Key('mine-wallet'), Icons.wallet_outlined),
|
||||
(Key('mine-favorites'), Icons.star_border_rounded),
|
||||
(Key('mine-downloads'), Icons.download_outlined),
|
||||
(Key('mine-history'), Icons.history_rounded),
|
||||
];
|
||||
expect(entryKeys, hasLength(8));
|
||||
for (final entryKey in entryKeys) {
|
||||
expect(find.byKey(entryKey), findsOneWidget);
|
||||
}
|
||||
const coloredIcons = [
|
||||
(
|
||||
Key('mine-wallet'),
|
||||
Icons.account_balance_wallet_outlined,
|
||||
AppColors.mineIconWallet,
|
||||
),
|
||||
(
|
||||
Key('mine-downloads'),
|
||||
Icons.download_outlined,
|
||||
AppColors.mineIconDownloads,
|
||||
),
|
||||
(Key('mine-history'), Icons.history_rounded, AppColors.mineIconHistory),
|
||||
(
|
||||
Key('mine-watch-preferences'),
|
||||
Icons.tune_rounded,
|
||||
AppColors.mineIconPreferences,
|
||||
),
|
||||
(
|
||||
Key('mine-help'),
|
||||
Icons.support_agent_rounded,
|
||||
AppColors.mineIconSupport,
|
||||
),
|
||||
(
|
||||
Key('mine-language'),
|
||||
Icons.language_rounded,
|
||||
AppColors.mineIconLanguage,
|
||||
),
|
||||
(
|
||||
Key('mine-settings'),
|
||||
Icons.settings_outlined,
|
||||
AppColors.mineIconSettings,
|
||||
),
|
||||
(
|
||||
Key('mine-notices'),
|
||||
Icons.notifications_none_rounded,
|
||||
AppColors.mineIconNotices,
|
||||
),
|
||||
];
|
||||
for (final entry in coloredIcons) {
|
||||
for (final action in quickActions) {
|
||||
final icon = tester.widget<Icon>(
|
||||
find.descendant(
|
||||
of: find.byKey(entry.$1),
|
||||
matching: find.byIcon(entry.$2),
|
||||
of: find.byKey(action.$1),
|
||||
matching: find.byIcon(action.$2),
|
||||
),
|
||||
);
|
||||
expect(icon.color, entry.$3);
|
||||
expect(icon.size, AppDimens.mineGridIcon);
|
||||
expect(icon.color, AppColors.textPrimary);
|
||||
expect(icon.size, AppDimens.mineQuickActionIcon);
|
||||
}
|
||||
for (var index = 0; index < 8; index++) {
|
||||
expect(find.byKey(Key('mine-menu-cell-$index')), findsOneWidget);
|
||||
}
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byKey(const Key('mine-menu-cell-7')),
|
||||
matching: find.byIcon(Icons.notifications_none_rounded),
|
||||
),
|
||||
findsOneWidget,
|
||||
);
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byKey(const Key('mine-menu')),
|
||||
matching: find.byType(ListTile),
|
||||
),
|
||||
findsNothing,
|
||||
);
|
||||
final positions = [
|
||||
for (final entryKey in entryKeys) tester.getTopLeft(find.byKey(entryKey)),
|
||||
|
||||
// 「更多服务」列表:联系客服 / 语言 / 设置 / 通知。
|
||||
const services = [
|
||||
(Key('mine-help'), Icons.headset_outlined),
|
||||
(Key('mine-language'), Icons.language_rounded),
|
||||
(Key('mine-settings'), Icons.settings_outlined),
|
||||
(Key('mine-notices'), Icons.notifications_none_rounded),
|
||||
];
|
||||
expect(
|
||||
positions.take(4).map((position) => position.dy).toSet(),
|
||||
hasLength(1),
|
||||
);
|
||||
expect(
|
||||
positions.skip(4).map((position) => position.dy).toSet(),
|
||||
hasLength(1),
|
||||
);
|
||||
expect(positions[1].dx, greaterThan(positions[0].dx));
|
||||
expect(positions[2].dx, greaterThan(positions[1].dx));
|
||||
expect(positions[3].dx, greaterThan(positions[2].dx));
|
||||
expect(positions[5].dx, greaterThan(positions[4].dx));
|
||||
expect(positions[6].dx, greaterThan(positions[5].dx));
|
||||
for (final service in services) {
|
||||
expect(find.byKey(service.$1), findsOneWidget);
|
||||
final icon = tester.widget<Icon>(
|
||||
find.descendant(
|
||||
of: find.byKey(service.$1),
|
||||
matching: find.byIcon(service.$2),
|
||||
),
|
||||
);
|
||||
expect(icon.color, AppColors.textPrimary);
|
||||
expect(icon.size, AppDimens.mineServiceIcon);
|
||||
}
|
||||
expect(find.byKey(const Key('mine-menu')), findsOneWidget);
|
||||
expect(tester.getTopLeft(find.byKey(const Key('mine-menu'))).dx, 14);
|
||||
|
||||
final menu = tester.widget<Container>(find.byKey(const Key('mine-menu')));
|
||||
final menuDecoration = menu.decoration! as BoxDecoration;
|
||||
expect(menuDecoration.color, AppColors.mineGridSurface);
|
||||
expect(
|
||||
menuDecoration.borderRadius,
|
||||
BorderRadius.circular(AppDimens.mineGridRadius),
|
||||
);
|
||||
expect(menuDecoration.border, isNull);
|
||||
expect(menuDecoration.boxShadow, isNull);
|
||||
final table = tester.widget<Table>(find.byKey(const Key('mine-menu-grid')));
|
||||
final border = table.border!;
|
||||
expect(border.horizontalInside.color, AppColors.mineGridDivider);
|
||||
expect(border.verticalInside.color, AppColors.mineGridDivider);
|
||||
final vip = tester.widget<Container>(find.byKey(const Key('mine-vip')));
|
||||
final vipDecoration = vip.decoration! as BoxDecoration;
|
||||
expect((vipDecoration.gradient! as LinearGradient).colors, const [
|
||||
AppColors.vipGoldStart,
|
||||
AppColors.vipGoldEnd,
|
||||
AppColors.vipCardStart,
|
||||
AppColors.vipCardEnd,
|
||||
]);
|
||||
expect(vipDecoration.boxShadow, isNull);
|
||||
|
||||
final order = [
|
||||
tester.getTopLeft(find.byKey(const Key('mine-user-row'))).dy,
|
||||
tester.getTopLeft(find.byKey(const Key('mine-vip'))).dy,
|
||||
tester.getTopLeft(find.byKey(const Key('mine-stats'))).dy,
|
||||
tester.getTopLeft(find.byKey(const Key('mine-menu'))).dy,
|
||||
tester.getTopLeft(find.byKey(const Key('mine-more-services'))).dy,
|
||||
tester.getTopLeft(find.byKey(const Key('mine-wallet'))).dy,
|
||||
tester.getTopLeft(find.byKey(const Key('mine-help'))).dy,
|
||||
];
|
||||
expect(order, [...order]..sort());
|
||||
expect(tester.takeException(), isNull);
|
||||
@@ -249,99 +139,6 @@ void main() {
|
||||
expect(find.byType(AuthPage), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_show_device_counts_when_signed_out', (tester) async {
|
||||
await _pumpApp(
|
||||
tester,
|
||||
signedIn: false,
|
||||
history: InMemoryWatchHistoryRepository(seed: [_recent]),
|
||||
);
|
||||
await _openMine(tester);
|
||||
|
||||
expect(_statValue(tester, const Key('mine-stat-following')), '3');
|
||||
expect(_statValue(tester, const Key('mine-stat-watch-records')), '1');
|
||||
expect(_statValue(tester, const Key('mine-stat-coins')), '—');
|
||||
expect(find.byKey(const Key('mine-continue-watching')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_switch_mine_counts_when_login_identity_changes', (
|
||||
tester,
|
||||
) async {
|
||||
final catalog = FakeCatalogRepository();
|
||||
final favorites = _IdentityMineFavoriteRepository(
|
||||
device: catalog.dramas.take(2).toList(),
|
||||
account: [catalog.dramas[2]],
|
||||
);
|
||||
final history = _IdentityMineWatchHistoryRepository(
|
||||
device: [_recent, _secondRecent],
|
||||
account: [_accountRecent],
|
||||
);
|
||||
await _pumpApp(
|
||||
tester,
|
||||
signedIn: false,
|
||||
favorite: favorites,
|
||||
history: history,
|
||||
);
|
||||
await _openMine(tester);
|
||||
|
||||
expect(_statValue(tester, const Key('mine-stat-following')), '2');
|
||||
expect(_statValue(tester, const Key('mine-stat-watch-records')), '2');
|
||||
expect(_statValue(tester, const Key('mine-stat-coins')), '—');
|
||||
|
||||
final auth = Provider.of<AuthController>(
|
||||
tester.element(find.byKey(const Key('mine-page-surface'))),
|
||||
listen: false,
|
||||
);
|
||||
final preferences = SharedPreferencesAsync();
|
||||
favorites.scope = 'account';
|
||||
history.scope = 'account';
|
||||
await _setSignedIn(preferences);
|
||||
await auth.load();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(auth.isSignedIn, isTrue);
|
||||
expect(_statValue(tester, const Key('mine-stat-following')), '1');
|
||||
expect(_statValue(tester, const Key('mine-stat-watch-records')), '1');
|
||||
expect(_statValue(tester, const Key('mine-stat-coins')), '320');
|
||||
expect(find.text('Account history'), findsOneWidget);
|
||||
expect(find.text('Device history'), findsNothing);
|
||||
|
||||
favorites.scope = 'device';
|
||||
history.scope = 'device';
|
||||
await _clearSignedIn(preferences);
|
||||
await auth.load();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(auth.isSignedIn, isFalse);
|
||||
expect(_statValue(tester, const Key('mine-stat-following')), '2');
|
||||
expect(_statValue(tester, const Key('mine-stat-watch-records')), '2');
|
||||
expect(_statValue(tester, const Key('mine-stat-coins')), '—');
|
||||
expect(find.text('Device history'), findsOneWidget);
|
||||
expect(find.text('Account history'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('should_refresh_watch_count_after_history_is_cleared', (
|
||||
tester,
|
||||
) async {
|
||||
final history = InMemoryWatchHistoryRepository(seed: [_recent]);
|
||||
await _pumpApp(tester, signedIn: false, history: history);
|
||||
await _openMine(tester);
|
||||
|
||||
expect(_statValue(tester, const Key('mine-stat-watch-records')), '1');
|
||||
|
||||
await tester.tap(find.byKey(const Key('mine-history')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('watch-records-clear')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.widgetWithText(FilledButton, 'Clear'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('watch-records-empty')), findsOneWidget);
|
||||
|
||||
await tester.binding.handlePopRoute();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(_statValue(tester, const Key('mine-stat-watch-records')), '0');
|
||||
});
|
||||
|
||||
testWidgets('should_render_signed_in_user_without_floating_mini_player', (
|
||||
tester,
|
||||
) async {
|
||||
@@ -358,54 +155,28 @@ void main() {
|
||||
expect(find.byKey(const Key('mine-login')), findsNothing);
|
||||
expect(find.byKey(const Key('mine-mini-player')), findsNothing);
|
||||
expect(find.byType(FloatingActionButton), findsNothing);
|
||||
expect(find.byKey(const Key('mine-continue-watching')), findsOneWidget);
|
||||
expect(find.byKey(const Key('mine-continue-all')), findsOneWidget);
|
||||
expect(find.text('Recent drama'), findsOneWidget);
|
||||
expect(find.text('Episode 3'), findsWidgets);
|
||||
|
||||
String statValue(Key key) {
|
||||
return tester
|
||||
.widget<Text>(
|
||||
find
|
||||
.descendant(of: find.byKey(key), matching: find.byType(Text))
|
||||
.first,
|
||||
)
|
||||
.data!;
|
||||
}
|
||||
|
||||
expect(statValue(const Key('mine-stat-following')), '3');
|
||||
expect(statValue(const Key('mine-stat-watch-records')), '1');
|
||||
expect(statValue(const Key('mine-stat-coins')), '320');
|
||||
final signedInOrder = [
|
||||
tester.getTopLeft(find.byKey(const Key('mine-user-row'))).dy,
|
||||
tester.getTopLeft(find.byKey(const Key('mine-vip'))).dy,
|
||||
tester.getTopLeft(find.byKey(const Key('mine-continue-watching'))).dy,
|
||||
tester.getTopLeft(find.byKey(const Key('mine-stats'))).dy,
|
||||
tester.getTopLeft(find.byKey(const Key('mine-menu'))).dy,
|
||||
tester.getTopLeft(find.byKey(const Key('mine-more-services'))).dy,
|
||||
];
|
||||
expect(signedInOrder, [...signedInOrder]..sort());
|
||||
|
||||
expect(find.byKey(const Key('mine-notices')), findsOneWidget);
|
||||
await tester.tap(find.byKey(const Key('mine-edit')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('account-profile-page')), findsOneWidget);
|
||||
expect(find.byKey(const Key('mine-edit-works')), findsNothing);
|
||||
expect(find.byKey(const Key('mine-edit-creator')), findsNothing);
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('should_open_more_services_and_about_page', (tester) async {
|
||||
testWidgets('should_open_help_and_about_from_mine', (tester) async {
|
||||
await _pumpApp(tester, signedIn: false);
|
||||
await _openMine(tester);
|
||||
|
||||
await tester.tap(find.byKey(const Key('mine-common-questions')));
|
||||
await tester.tap(find.byKey(const Key('mine-help')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('mine-placeholder-page')), findsOneWidget);
|
||||
await tester.binding.handlePopRoute();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.byKey(const Key('mine-about')));
|
||||
// 关于我们已收进「设置」二级页。
|
||||
await tester.tap(find.byKey(const Key('mine-settings')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('settings-about')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(MineAboutPage), findsOneWidget);
|
||||
expect(find.byKey(const Key('mine-about-page')), findsOneWidget);
|
||||
@@ -420,9 +191,7 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('should_open_history_tab_from_continue_watching_all', (
|
||||
tester,
|
||||
) async {
|
||||
testWidgets('should_open_watch_records_from_quick_actions', (tester) async {
|
||||
await _pumpApp(
|
||||
tester,
|
||||
signedIn: true,
|
||||
@@ -430,29 +199,10 @@ void main() {
|
||||
);
|
||||
await _openMine(tester);
|
||||
|
||||
await tester.tap(find.byKey(const Key('mine-continue-all')));
|
||||
await tester.tap(find.byKey(const Key('mine-history')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byKey(const Key('following-page')), findsOneWidget);
|
||||
expect(find.byKey(const Key('following-history-grid')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_open_player_when_tapping_continue_watching_card', (
|
||||
tester,
|
||||
) async {
|
||||
await _pumpApp(
|
||||
tester,
|
||||
signedIn: true,
|
||||
history: InMemoryWatchHistoryRepository(seed: [_recent]),
|
||||
);
|
||||
await _openMine(tester);
|
||||
|
||||
await tester.tap(find.byKey(const Key('mine-continue-city-lights-demo')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byKey(const Key('player-scaffold')), findsOneWidget);
|
||||
// 继续观看直接进播放页,不应该先落到历史列表
|
||||
expect(find.byKey(const Key('following-page')), findsNothing);
|
||||
expect(find.byKey(const Key('watch-records-page')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_open_vip_from_mine_without_floating_player', (
|
||||
@@ -474,13 +224,16 @@ void main() {
|
||||
expect(find.byType(FloatingActionButton), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('should_expose_eight_menu_destinations_in_order', (tester) async {
|
||||
testWidgets('should_expose_quick_actions_and_service_destinations', (
|
||||
tester,
|
||||
) async {
|
||||
tester.view.physicalSize = const Size(390, 900);
|
||||
tester.view.devicePixelRatio = 1;
|
||||
addTearDown(tester.view.resetPhysicalSize);
|
||||
addTearDown(tester.view.resetDevicePixelRatio);
|
||||
final opened = <MineDestination>[];
|
||||
var languageOpened = 0;
|
||||
var favoritesOpened = 0;
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: AppTheme.dark(),
|
||||
@@ -490,34 +243,53 @@ void main() {
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(AppDimens.pageHorizontal),
|
||||
child: MineMenuList(
|
||||
onOpen: opened.add,
|
||||
onLanguage: () => languageOpened++,
|
||||
child: Column(
|
||||
children: [
|
||||
MineQuickActions(
|
||||
onWallet: () => opened.add(MineDestination.wallet),
|
||||
onFavorites: () => favoritesOpened++,
|
||||
onDownloads: () => opened.add(MineDestination.downloads),
|
||||
onHistory: () => opened.add(MineDestination.history),
|
||||
),
|
||||
MineServiceList(
|
||||
onOpen: opened.add,
|
||||
onLanguage: () => languageOpened++,
|
||||
languageName: 'English',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
const rows = [
|
||||
const quickActions = [
|
||||
(Key('mine-wallet'), MineDestination.wallet),
|
||||
(Key('mine-downloads'), MineDestination.downloads),
|
||||
(Key('mine-history'), MineDestination.history),
|
||||
(Key('mine-watch-preferences'), MineDestination.preferences),
|
||||
];
|
||||
for (final action in quickActions) {
|
||||
await tester.tap(find.byKey(action.$1));
|
||||
await tester.pump();
|
||||
expect(opened.last, action.$2);
|
||||
}
|
||||
await tester.tap(find.byKey(const Key('mine-favorites')));
|
||||
await tester.pump();
|
||||
expect(favoritesOpened, 1);
|
||||
|
||||
const services = [
|
||||
(Key('mine-help'), MineDestination.help),
|
||||
(Key('mine-notices'), MineDestination.notices),
|
||||
(Key('mine-settings'), MineDestination.settings),
|
||||
];
|
||||
for (final row in rows) {
|
||||
await tester.tap(find.byKey(row.$1));
|
||||
for (final service in services) {
|
||||
await tester.tap(find.byKey(service.$1));
|
||||
await tester.pump();
|
||||
expect(opened.last, row.$2);
|
||||
expect(opened.last, service.$2);
|
||||
}
|
||||
await tester.tap(find.byKey(const Key('mine-language')));
|
||||
await tester.pump();
|
||||
expect(languageOpened, 1);
|
||||
await tester.tap(find.byKey(const Key('mine-settings')));
|
||||
await tester.pump();
|
||||
expect(opened.last, MineDestination.settings);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -532,34 +304,6 @@ const _recent = WatchProgress(
|
||||
duration: Duration(minutes: 2),
|
||||
);
|
||||
|
||||
const _secondRecent = WatchProgress(
|
||||
dramaId: 'vengeance-demo',
|
||||
episodeId: 'vengeance-demo-1',
|
||||
dramaTitle: 'Device history',
|
||||
episodeNumber: 1,
|
||||
totalEpisodes: 6,
|
||||
position: Duration(seconds: 15),
|
||||
duration: Duration(minutes: 2),
|
||||
);
|
||||
|
||||
const _accountRecent = WatchProgress(
|
||||
dramaId: 'the-signal-demo',
|
||||
episodeId: 'the-signal-demo-2',
|
||||
dramaTitle: 'Account history',
|
||||
episodeNumber: 2,
|
||||
totalEpisodes: 7,
|
||||
position: Duration(seconds: 20),
|
||||
duration: Duration(minutes: 2),
|
||||
);
|
||||
|
||||
String _statValue(WidgetTester tester, Key key) {
|
||||
return tester
|
||||
.widget<Text>(
|
||||
find.descendant(of: find.byKey(key), matching: find.byType(Text)).first,
|
||||
)
|
||||
.data!;
|
||||
}
|
||||
|
||||
Future<void> _openMine(WidgetTester tester) async {
|
||||
await tester.tap(find.byKey(const Key('tab-mine')));
|
||||
await tester.pumpAndSettle();
|
||||
@@ -606,105 +350,6 @@ Future<void> _pumpApp(
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
Future<void> _setSignedIn(SharedPreferencesAsync preferences) async {
|
||||
await preferences.setString('auth.accessToken', 'access');
|
||||
await preferences.setString('auth.refreshToken', 'refresh');
|
||||
await preferences.setString(
|
||||
'auth.user',
|
||||
'{"uid":"U-100","nickname":"Viewer","avatarUrl":""}',
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _clearSignedIn(SharedPreferencesAsync preferences) async {
|
||||
await preferences.remove('auth.accessToken');
|
||||
await preferences.remove('auth.refreshToken');
|
||||
await preferences.remove('auth.user');
|
||||
}
|
||||
|
||||
class _IdentityMineFavoriteRepository implements FavoriteRepository {
|
||||
_IdentityMineFavoriteRepository({
|
||||
required List<Drama> device,
|
||||
required List<Drama> account,
|
||||
}) : _cards = {'device': device, 'account': account};
|
||||
|
||||
final Map<String, List<Drama>> _cards;
|
||||
String scope = 'device';
|
||||
|
||||
@override
|
||||
Future<PageResult<Drama>> page({int pageIndex = 1, int pageSize = 20}) async {
|
||||
final cards = _cards[scope]!;
|
||||
final offset = (pageIndex - 1) * pageSize;
|
||||
return PageResult(
|
||||
total: cards.length,
|
||||
list: offset >= cards.length
|
||||
? const []
|
||||
: cards.skip(offset).take(pageSize).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> remove(String dramaId) async {
|
||||
_cards[scope]!.removeWhere((drama) => drama.id == dramaId);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> removeMany(List<String> dramaIds) async {
|
||||
final ids = dramaIds.toSet();
|
||||
_cards[scope]!.removeWhere((drama) => ids.contains(drama.id));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> toggle(String dramaId) async => true;
|
||||
}
|
||||
|
||||
class _IdentityMineWatchHistoryRepository implements WatchHistoryRepository {
|
||||
_IdentityMineWatchHistoryRepository({
|
||||
required List<WatchProgress> device,
|
||||
required List<WatchProgress> account,
|
||||
}) : _records = {'device': device, 'account': account};
|
||||
|
||||
final Map<String, List<WatchProgress>> _records;
|
||||
String scope = 'device';
|
||||
|
||||
@override
|
||||
Future<void> clear() async => _records[scope]!.clear();
|
||||
|
||||
@override
|
||||
Future<WatchProgress?> progressFor(String dramaId) async {
|
||||
return _records[scope]!
|
||||
.where((record) => record.dramaId == dramaId)
|
||||
.firstOrNull;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<PageResult<WatchProgress>> recent({
|
||||
int pageIndex = 1,
|
||||
int pageSize = 20,
|
||||
}) async {
|
||||
final records = _records[scope]!;
|
||||
final offset = (pageIndex - 1) * pageSize;
|
||||
return PageResult(
|
||||
total: records.length,
|
||||
list: offset >= records.length
|
||||
? const []
|
||||
: records.skip(offset).take(pageSize).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> remove(String dramaId) async {
|
||||
_records[scope]!.removeWhere((record) => record.dramaId == dramaId);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<WatchProgress?> save({
|
||||
required String episodeId,
|
||||
required Duration position,
|
||||
Duration? duration,
|
||||
bool finished = false,
|
||||
}) async => null;
|
||||
}
|
||||
|
||||
class _MineWalletCommerceRepository implements CommerceRepository {
|
||||
const _MineWalletCommerceRepository();
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ void main() {
|
||||
);
|
||||
final title = tester.widget<Text>(find.byKey(const Key('subpage-title')));
|
||||
expect(title.style?.fontSize, 18);
|
||||
expect(title.style?.fontWeight, FontWeight.w800);
|
||||
expect(title.style?.fontWeight, FontWeight.w400);
|
||||
expect(find.byKey(const Key('settings-notices')), findsNothing);
|
||||
expect(find.byKey(const Key('mine-account-card')), findsNothing);
|
||||
expect(find.byKey(const Key('server-endpoint-setting')), findsNothing);
|
||||
|
||||
Reference in new issue
Block a user