// Author: fruit.com.cn import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.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 'package:fruitshorts/app.dart'; import 'package:fruitshorts/core/data/models/drama.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/theme/app_theme.dart'; import 'package:fruitshorts/l10n/app_localizations.dart'; import 'package:fruitshorts/pages/player/widgets/home_feed_overlay.dart'; import '../support/fake_catalog.dart'; import '../support/fake_category.dart'; import '../support/fake_haptics.dart'; import '../support/fake_interaction_repositories.dart'; import '../support/fake_notice_repository.dart'; import '../support/widget_player.dart'; void main() { testWidgets('should_render_preview_home_card_without_hot_or_follow_avatar', ( tester, ) async { SharedPreferencesAsyncPlatform.instance = InMemorySharedPreferencesAsync.empty(); tester.view.physicalSize = const Size(390, 844); tester.view.devicePixelRatio = 1; addTearDown(tester.view.resetPhysicalSize); addTearDown(tester.view.resetDevicePixelRatio); final catalog = FakeCatalogRepository(); await tester.pumpWidget( LumaDramaApp( playerFactory: createWidgetPlayer, catalogRepository: catalog, categoryRepository: FakeCategoryRepository(catalog: catalog), watchHistoryRepository: InMemoryWatchHistoryRepository(), favoriteRepository: InMemoryFavoriteRepository(cards: catalog.dramas), playbackRepository: FakePlaybackRepository(), commentRepository: FakeCommentRepository(), interactionRepository: FakeInteractionRepository(), noticeRepository: FakeNoticeRepository(), haptics: FakeHaptics(), ), ); await tester.pumpAndSettle(); await tester.tap(find.byKey(const Key('tab-home'))); await tester.pumpAndSettle(); expect(find.byKey(const Key('home-feed-title')), findsOneWidget); expect(find.byKey(const Key('home-feed-info-card')), findsOneWidget); expect(find.byKey(const Key('home-feed-episode')), findsOneWidget); final cardRect = tester.getRect( find.byKey(const Key('home-feed-info-card')), ); final episodeRect = tester.getRect( find.byKey(const Key('home-feed-episode')), ); expect(episodeRect.left, lessThan(cardRect.center.dx)); final railCenter = tester.getCenter(find.byKey(const Key('rail-like'))); final railBottom = tester.getBottomLeft(find.byKey(const Key('rail-save'))); expect(railCenter.dy, greaterThan(844 * 0.4)); expect(railBottom.dy, lessThan(cardRect.top)); expect(find.byKey(const Key('home-feed-follow-series')), findsOneWidget); expect(find.byKey(const Key('home-feed-episodes')), findsOneWidget); for (final key in const [Key('home-feed-search'), Key('home-feed-more')]) { expect(tester.getSize(find.byKey(key)), const Size(36, 36)); expect( tester .widget( find.descendant(of: find.byKey(key), matching: find.byType(Icon)), ) .size, 18, ); } expect( tester.getSize(find.byKey(const Key('home-feed-follow-series'))).height, 34, ); expect(find.text('HOT'), findsNothing); expect(find.textContaining('Season'), findsNothing); expect(find.byKey(const Key('home-feed-follow')), findsNothing); expect(tester.takeException(), isNull); }); testWidgets('should_use_episode_title_then_drama_title_as_fallback', ( tester, ) async { Future pumpEpisode(Episode episode) async { await tester.pumpWidget( MaterialApp( theme: AppTheme.dark(), locale: const Locale('en'), supportedLocales: AppLocalizations.supportedLocales, localizationsDelegates: AppLocalizations.localizationsDelegates, home: Builder( builder: (context) => Scaffold( body: HomeFeedOverlay( l10n: AppLocalizations.of(context)!, drama: _drama, episode: episode, liked: false, saved: false, onLike: () {}, onSave: () {}, onComments: () {}, onShare: () {}, onEpisodes: () {}, onDownload: () {}, onClear: () {}, onSearch: () {}, ), ), ), ), ); await tester.pumpAndSettle(); } await pumpEpisode( const Episode( id: 'featured', number: 2, title: 'Midnight Contract', isFree: true, ), ); expect( tester .widget(find.byKey(const Key('home-feed-episode-title'))) .data, 'Midnight Contract', ); await pumpEpisode( const Episode(id: 'fallback', number: 2, title: '', isFree: true), ); expect( tester .widget(find.byKey(const Key('home-feed-episode-title'))) .data, 'Fallback Drama', ); }); testWidgets('should_show_server_like_count_when_count_is_available', ( tester, ) async { await tester.pumpWidget( MaterialApp( theme: AppTheme.dark(), locale: const Locale('en'), supportedLocales: AppLocalizations.supportedLocales, localizationsDelegates: AppLocalizations.localizationsDelegates, home: Builder( builder: (context) => Scaffold( body: HomeFeedOverlay( l10n: AppLocalizations.of(context)!, drama: _drama, episode: const Episode( id: 'count-episode', number: 1, title: 'Count Episode', isFree: true, ), liked: true, likeCount: 128, saved: false, onLike: () {}, onSave: () {}, onComments: () {}, onShare: () {}, onEpisodes: () {}, onDownload: () {}, onClear: () {}, onSearch: () {}, ), ), ), ), ); await tester.pumpAndSettle(); expect(find.byKey(const Key('rail-like-count')), findsOneWidget); expect(find.text('128'), findsOneWidget); }); } const _drama = Drama( id: 'featured-drama', title: 'Fallback Drama', synopsis: 'synopsis', posterUrl: '', totalEpisodes: 8, );