feat(flutter): 完成 K28-A1 四 Tab 首页

This commit is contained in:
Zhou Weidong committed 2026-10-20 09:57:10 +08:00
1 parent f981f88e0d
commit 49f3e63ed0
25 files changed
+606 -689

No files matched your search

+21 -12
View File
@@ -24,27 +24,37 @@ void main() {
InMemorySharedPreferencesAsync.empty();
});
testWidgets('should_show_search_category_language_and_drama_grid', (
testWidgets('should_show_search_categories_ranking_and_all_dramas', (
tester,
) async {
await _pumpTheater(tester, categoryRepository: _GridCategoryRepository());
expect(find.text('Continue Watching'), findsNothing);
expect(find.byKey(const Key('discover-search')), findsOneWidget);
expect(find.byKey(const Key('theater-category-chips')), findsOneWidget);
expect(find.byKey(const Key('theater-language-chips')), findsOneWidget);
expect(find.byKey(const Key('discover-category-grid')), findsOneWidget);
expect(find.byKey(const Key('discover-ranking-section')), findsOneWidget);
expect(find.byKey(const Key('home-all-dramas-grid')), findsOneWidget);
expect(find.byKey(const Key('ranking-tab-hot')), findsOneWidget);
expect(find.byKey(const Key('ranking-tab-new')), findsOneWidget);
final grid = tester.widget<GridView>(
find.byKey(const Key('discover-category-grid')),
);
final delegate =
grid.gridDelegate as SliverGridDelegateWithFixedCrossAxisCount;
expect(delegate.crossAxisCount, 3);
expect(tester.takeException(), isNull);
});
testWidgets('should_filter_grid_when_category_chip_is_tapped', (
testWidgets('should_open_category_dramas_page_when_tile_is_tapped', (
tester,
) async {
await _pumpTheater(tester, categoryRepository: _GridCategoryRepository());
await tester.tap(find.byKey(const Key('theater-category-7')));
await tester.tap(find.byKey(const Key('discover-category-7')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('category-dramas-page')), findsOneWidget);
expect(
find.byKey(const Key('home-drama-card-city-lights-demo')),
findsOneWidget,
@@ -66,23 +76,22 @@ void main() {
);
final headerBefore = tester.getTopLeft(
find.byKey(const Key('discover-search')),
find.byKey(const Key('discover-search-button')),
);
final scrollable = find.descendant(
of: find.byKey(const Key('discover-refresh')),
matching: find.byType(Scrollable),
final contentBefore = tester.getTopLeft(
find.byKey(const Key('discover-category-grid')),
);
await tester.drag(find.byType(ListView), const Offset(0, -140));
await tester.pumpAndSettle();
expect(
tester.getTopLeft(find.byKey(const Key('discover-search'))),
tester.getTopLeft(find.byKey(const Key('discover-search-button'))),
headerBefore,
);
expect(
tester.state<ScrollableState>(scrollable).position.pixels,
greaterThan(0),
tester.getTopLeft(find.byKey(const Key('discover-category-grid'))).dy,
lessThan(contentBefore.dy),
);
});
+46 -34
View File
@@ -68,35 +68,15 @@ void main() {
expect(field.focusNode?.hasFocus, isTrue);
});
testWidgets('should_select_theater_language_without_filtering_catalog', (
tester,
) async {
await _pumpApp(tester);
await tester.tap(find.byKey(const Key('tab-theater')));
await tester.pumpAndSettle();
expect(_chip(tester, 'theater-language-all').selected, isTrue);
expect(
find.byKey(const Key('home-drama-card-the-signal-demo')),
findsOneWidget,
);
await tester.tap(find.byKey(const Key('theater-language-id')));
await tester.pumpAndSettle();
expect(_chip(tester, 'theater-language-all').selected, isFalse);
expect(_chip(tester, 'theater-language-id').selected, isTrue);
expect(
find.byKey(const Key('home-drama-card-the-signal-demo')),
findsOneWidget,
);
});
testWidgets('should_open_fullscreen_player_when_home_card_is_tapped', (
tester,
) async {
await _pumpApp(tester);
await tester.ensureVisible(
find.byKey(const Key('home-drama-card-the-signal-demo')),
);
await tester.pumpAndSettle();
await tester.tap(find.byKey(const Key('home-drama-card-the-signal-demo')));
await tester.pumpAndSettle();
@@ -104,6 +84,20 @@ void main() {
expect(player.homeMode, isFalse);
});
testWidgets('should_use_first_drama_cover_when_home_has_no_banner', (
tester,
) async {
await _pumpApp(tester, withBanner: false);
expect(find.byKey(const Key('home-hero-banner')), findsOneWidget);
expect(find.byKey(const Key('home-hero-title-0')), findsOneWidget);
await tester.tap(find.byKey(const Key('feed-banner-0')));
await tester.pumpAndSettle();
final player = tester.widget<PlayerPage>(find.byType(PlayerPage));
expect(player.homeMode, isFalse);
});
testWidgets('should_open_fullscreen_player_when_theater_card_is_tapped', (
tester,
) async {
@@ -111,7 +105,20 @@ void main() {
await tester.tap(find.byKey(const Key('tab-theater')));
await tester.pumpAndSettle();
await tester.tap(find.byKey(const Key('home-drama-card-the-signal-demo')));
final card = find.byKey(const Key('home-drama-card-the-signal-demo'));
await tester.scrollUntilVisible(
card,
220,
scrollable: find
.descendant(
of: find.byKey(const Key('discover-refresh')),
matching: find.byType(Scrollable),
)
.first,
);
await tester.ensureVisible(card);
await tester.pumpAndSettle();
await tester.tap(card);
await tester.pumpAndSettle();
final player = tester.widget<PlayerPage>(find.byType(PlayerPage));
@@ -136,6 +143,7 @@ void main() {
);
expect(find.byKey(const Key('home-continue-watching')), findsOneWidget);
expect(find.text('Episode 3 · 8 min left'), findsOneWidget);
await tester.tap(
find.byKey(const Key('home-continue-play-the-signal-demo')),
);
@@ -155,7 +163,8 @@ void main() {
await tester.tap(find.byKey(const Key('tab-theater')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('theater-language-chips')), findsOneWidget);
expect(find.byKey(const Key('discover-category-grid')), findsOneWidget);
expect(find.byKey(const Key('discover-ranking-section')), findsOneWidget);
expect(tester.takeException(), isNull);
});
}
@@ -174,20 +183,23 @@ Future<void> _pumpApp(
WidgetTester tester, {
WatchHistoryRepository? history,
Size size = const Size(390, 844),
bool withBanner = true,
}) async {
tester.view.physicalSize = size;
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
final catalog = FakeCatalogRepository(
banners: const [
FeedBanner(
id: 'banner-1',
imageUrl: '/files/banner.jpg',
linkType: 'DRAMA',
linkValue: 'the-signal-demo',
),
],
banners: withBanner
? const [
FeedBanner(
id: 'banner-1',
imageUrl: '/files/banner.jpg',
linkType: 'DRAMA',
linkValue: 'the-signal-demo',
),
]
: const [],
);
await tester.pumpWidget(
LumaDramaApp(
+14 -1
View File
@@ -309,7 +309,20 @@ void _expectFullscreenOverlay(WidgetTester tester) {
Future<void> _openSeriesPlayer(WidgetTester tester) async {
await tester.tap(find.byKey(const Key('tab-theater')));
await tester.pumpAndSettle();
await tester.tap(find.byKey(const Key('home-drama-card-city-lights-demo')));
final card = find.byKey(const Key('home-drama-card-city-lights-demo'));
await tester.scrollUntilVisible(
card,
220,
scrollable: find
.descendant(
of: find.byKey(const Key('discover-refresh')),
matching: find.byType(Scrollable),
)
.first,
);
await tester.ensureVisible(card);
await tester.pumpAndSettle();
await tester.tap(card);
await tester.pumpAndSettle();
}
+22 -9
View File
@@ -84,6 +84,10 @@ void main() {
) async {
await tester.pumpWidget(appUnderTest());
await tester.pumpAndSettle();
await tester.ensureVisible(
find.byKey(const Key('home-drama-card-the-signal-demo')),
);
await tester.pumpAndSettle();
await tester.tap(find.byKey(const Key('home-drama-card-the-signal-demo')));
await tester.pumpAndSettle();
@@ -172,7 +176,7 @@ void main() {
expect(tester.takeException(), isNull);
});
testWidgets('should_render_theater_with_filters_and_same_route_tabs', (
testWidgets('should_render_existing_theater_layout_on_same_route_tab', (
tester,
) async {
tester.view.physicalSize = const Size(360, 720);
@@ -185,15 +189,11 @@ void main() {
await tester.tap(find.byKey(const Key('tab-theater')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('discover-search')), findsOneWidget);
expect(find.byKey(const Key('theater-category-chips')), findsOneWidget);
expect(find.byKey(const Key('theater-language-chips')), findsOneWidget);
expect(find.byKey(const Key('discover-category-grid')), findsOneWidget);
expect(find.byKey(const Key('discover-ranking-section')), findsOneWidget);
expect(find.byKey(const Key('home-all-dramas-grid')), findsOneWidget);
expect(find.byKey(const Key('discover-search-button')), findsOneWidget);
expect(find.byKey(const Key('discover-profile')), findsOneWidget);
expect(
find.byKey(const Key('home-drama-card-city-lights-demo')),
findsOneWidget,
);
expect(tester.takeException(), isNull);
});
@@ -287,7 +287,20 @@ void main() {
Future<void> _openTheaterPlayer(WidgetTester tester) async {
await tester.tap(find.byKey(const Key('tab-theater')));
await tester.pumpAndSettle();
await tester.tap(find.byKey(const Key('home-drama-card-city-lights-demo')));
final card = find.byKey(const Key('home-drama-card-city-lights-demo'));
await tester.scrollUntilVisible(
card,
220,
scrollable: find
.descendant(
of: find.byKey(const Key('discover-refresh')),
matching: find.byType(Scrollable),
)
.first,
);
await tester.ensureVisible(card);
await tester.pumpAndSettle();
await tester.tap(card);
await tester.pumpAndSettle();
}