From 5058853af3ee0ebe24026f7e683f2b3b091ec98d Mon Sep 17 00:00:00 2001 From: Zhou Weidong <502333560@qq.com> Date: Sat, 17 Oct 2026 16:59:59 +0800 Subject: [PATCH] =?UTF-8?q?fix(flutter):=20=E6=B3=A8=E5=86=8C=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E4=BB=93=E5=BA=93=E5=B9=B6=E4=BF=AE=E6=AD=A3=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E8=BD=AE=E6=92=AD=E6=95=B0=E6=8D=AE=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/app.dart | 1 + lib/pages/discover/discover_view.dart | 4 +- test/discover/home_banner_source_test.dart | 100 ++++++++++++++++++++ test/watch/watch_history_provider_test.dart | 52 ++++++++++ 4 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 test/discover/home_banner_source_test.dart create mode 100644 test/watch/watch_history_provider_test.dart diff --git a/lib/app.dart b/lib/app.dart index da8e9be..f9cacaa 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -181,6 +181,7 @@ class _LumaDramaAppState extends State { providers: [ Provider(create: (_) => PlaybackCoordinator()), Provider(create: (_) => widget.playerFactory), + Provider.value(value: _catalogRepository), Provider.value(value: _playback), Provider.value(value: _watchHistory), Provider.value(value: _favorites), diff --git a/lib/pages/discover/discover_view.dart b/lib/pages/discover/discover_view.dart index 4787d6d..ccb7005 100644 --- a/lib/pages/discover/discover_view.dart +++ b/lib/pages/discover/discover_view.dart @@ -7,6 +7,7 @@ import 'package:provider/provider.dart'; import '../../core/data/models/drama.dart'; import '../../core/data/models/home_feed.dart'; import '../../core/data/repositories/watch_history_repository.dart'; +import '../../core/data/services/catalog_controller.dart'; import '../../core/data/services/category_controller.dart'; import '../../core/theme/app_colors.dart'; import '../../core/theme/app_theme.dart'; @@ -98,6 +99,7 @@ class _DiscoverPageState extends State { Widget _page(BuildContext context) { final l10n = AppLocalizations.of(context)!; final categories = context.watch(); + final homeBanners = context.watch().feed.banners; final allDramas = [...?widget.dramas, ...categories.visibleDramas]; final cards = _cardsFor(categories.visibleDramas, ''); final content = SafeArea( @@ -114,7 +116,7 @@ class _DiscoverPageState extends State { padding: const EdgeInsets.fromLTRB(16, 4, 16, 0), child: ClipRRect( borderRadius: BorderRadius.circular(18), - child: _carousel(l10n, categories.feed.banners, allDramas), + child: _carousel(l10n, homeBanners, allDramas), ), ), Padding( diff --git a/test/discover/home_banner_source_test.dart b/test/discover/home_banner_source_test.dart new file mode 100644 index 0000000..1e4edeb --- /dev/null +++ b/test/discover/home_banner_source_test.dart @@ -0,0 +1,100 @@ +// Author: fruit.com.cn + +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/home_feed.dart'; +import 'package:fruitshorts/core/data/repositories/catalog_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/pages/discover/widgets/cover_carousel.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'; + +import '../support/fake_catalog.dart'; +import '../support/fake_category.dart'; +import '../support/fake_interaction_repositories.dart'; +import '../support/fake_notice_repository.dart'; +import '../support/widget_player.dart'; + +void main() { + testWidgets( + 'should_render_home_feed_banners_when_discover_banners_are_empty', + (tester) async { + SharedPreferencesAsyncPlatform.instance = + InMemorySharedPreferencesAsync.empty(); + final catalog = _HomeBannerCatalogRepository(); + await tester.pumpWidget( + LumaDramaApp( + playerFactory: createWidgetPlayer, + catalogRepository: catalog, + categoryRepository: FakeCategoryRepository(catalog: catalog), + watchHistoryRepository: InMemoryWatchHistoryRepository(), + favoriteRepository: InMemoryFavoriteRepository(), + playbackRepository: FakePlaybackRepository(), + commentRepository: FakeCommentRepository(), + interactionRepository: FakeInteractionRepository(), + noticeRepository: FakeNoticeRepository(), + ), + ); + await tester.pumpAndSettle(); + await tester.tap(find.byKey(const Key('tab-discover'))); + await tester.pumpAndSettle(); + + expect(find.byType(CoverCarousel), findsOneWidget); + expect(find.byKey(const Key('carousel-dot-0')), findsOneWidget); + expect(find.byKey(const Key('carousel-dot-1')), findsOneWidget); + expect( + find.descendant( + of: find.byType(CoverCarousel), + matching: find.text('The Signal'), + ), + findsOneWidget, + ); + + await tester.pump(const Duration(milliseconds: 4500)); + await tester.pump(const Duration(milliseconds: 500)); + expect( + find.descendant( + of: find.byType(CoverCarousel), + matching: find.text('City Lights & Velvet Nights'), + ), + findsOneWidget, + ); + await tester.pumpWidget(const SizedBox.shrink()); + }, + ); +} + +class _HomeBannerCatalogRepository implements CatalogRepository { + final _delegate = FakeCatalogRepository(); + + @override + Future fetchHomeFeed() async => HomeFeed( + banners: const [ + FeedBanner( + id: 'banner-1', + imageUrl: '/files/banner-1.png', + linkType: 'DRAMA', + linkValue: 'the-signal-demo', + ), + FeedBanner( + id: 'banner-2', + imageUrl: '/files/banner-2.png', + linkType: 'DRAMA', + linkValue: 'city-lights-demo', + ), + ], + sections: [FeedSection(code: 'hot', title: 'Hot', dramas: demoDramas)], + ); + + @override + Future fetchDiscoverFeed() async => HomeFeed( + sections: [FeedSection(code: 'hot', title: 'Hot', dramas: demoDramas)], + ); + + @override + Future fetchDrama(String dramaId) => _delegate.fetchDrama(dramaId); +} diff --git a/test/watch/watch_history_provider_test.dart b/test/watch/watch_history_provider_test.dart new file mode 100644 index 0000000..932728f --- /dev/null +++ b/test/watch/watch_history_provider_test.dart @@ -0,0 +1,52 @@ +// Author: fruit.com.cn + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:fruitshorts/app.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:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; + +import '../support/fake_catalog.dart'; +import '../support/fake_category.dart'; +import '../support/fake_interaction_repositories.dart'; +import '../support/fake_notice_repository.dart'; +import '../support/widget_player.dart'; + +void main() { + testWidgets('should_open_watch_history_with_catalog_provider_registered', ( + tester, + ) async { + SharedPreferencesAsyncPlatform.instance = + InMemorySharedPreferencesAsync.withData({ + 'auth.accessToken': 'test-access', + 'auth.refreshToken': 'test-refresh', + 'auth.user': '{"uid":"1","nickname":"Viewer","avatarUrl":""}', + }); + final catalog = FakeCatalogRepository(); + await tester.pumpWidget( + LumaDramaApp( + playerFactory: createWidgetPlayer, + catalogRepository: catalog, + categoryRepository: FakeCategoryRepository(catalog: catalog), + watchHistoryRepository: InMemoryWatchHistoryRepository(), + favoriteRepository: InMemoryFavoriteRepository(), + playbackRepository: FakePlaybackRepository(), + commentRepository: FakeCommentRepository(), + interactionRepository: FakeInteractionRepository(), + noticeRepository: FakeNoticeRepository(), + ), + ); + await tester.pumpAndSettle(); + await tester.tap(find.byKey(const Key('tab-my'))); + await tester.pumpAndSettle(); + await tester.tap(find.text('Watch History')); + await tester.pumpAndSettle(); + + expect(tester.takeException(), isNull); + expect(find.byKey(const Key('watch-records-page')), findsOneWidget); + expect(find.text('No watch history yet.'), findsOneWidget); + }); +}