// Author: fruit.com.cn import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:fruitshorts/core/data/models/drama.dart'; import 'package:fruitshorts/core/data/models/feed_page.dart'; import 'package:fruitshorts/core/data/models/home_feed.dart'; import 'package:fruitshorts/core/data/repositories/catalog_repository.dart'; import 'package:fruitshorts/core/data/services/catalog_controller.dart'; import 'package:fruitshorts/core/theme/app_theme.dart'; import 'package:fruitshorts/l10n/app_localizations.dart'; import 'package:fruitshorts/pages/ranking/ranking_page.dart'; import 'package:provider/provider.dart'; void main() { testWidgets('should_render_rank_badges_on_covers_for_all_entries', ( tester, ) async { await _pumpPage(tester, [ _drama('a', viewCount: 400), _drama('b', viewCount: 300), _drama('c', viewCount: 200), _drama('d', viewCount: 100), ]); expect(find.byKey(const Key('ranking-top-1')), findsOneWidget); expect(find.byKey(const Key('ranking-top-2')), findsOneWidget); expect(find.byKey(const Key('ranking-top-3')), findsOneWidget); expect(find.byKey(const Key('ranking-top-4')), findsOneWidget); expect(find.byKey(const Key('ranking-row-cover-1')), findsOneWidget); expect(find.byKey(const Key('ranking-title-1')), findsOneWidget); }); testWidgets('should_hide_optional_fields_when_drama_has_no_data', ( tester, ) async { await _pumpPage(tester, [_drama('solo')]); expect(find.byKey(const Key('ranking-tag-1')), findsNothing); expect(find.byIcon(Icons.local_fire_department_rounded), findsNothing); }); testWidgets('should_show_optional_fields_when_present', (tester) async { await _pumpPage(tester, [ _drama( 'rich', viewCount: 15340000, likeCount: 550, tag: '新剧', genre: '剧情', synopsis: '以拟人化视角,重温长征岁月。', ), ]); expect(find.byKey(const Key('ranking-tag-1')), findsOneWidget); expect(find.text('新剧'), findsOneWidget); expect(find.text('剧情'), findsOneWidget); expect(find.text('以拟人化视角,重温长征岁月。'), findsOneWidget); expect(find.text('1534w heat · 550 likes'), findsOneWidget); final synopsis = tester.widget(find.text('以拟人化视角,重温长征岁月。')); expect(synopsis.maxLines, 3); expect(synopsis.overflow, TextOverflow.ellipsis); final tag = tester.widget(find.byKey(const Key('ranking-tag-1'))); expect(tag.style?.color, isNotNull); final synopsisRect = tester.getRect(find.text('以拟人化视角,重温长征岁月。')); final tagRect = tester.getRect(find.byKey(const Key('ranking-tag-1'))); expect(tagRect.top - synopsisRect.bottom, lessThan(8)); }); } Future _pumpPage(WidgetTester tester, List dramas) async { final controller = CatalogController(_EmptyCatalogRepository()); controller.feed = HomeFeed( sections: [FeedSection(code: 'hot', title: 'Hot', dramas: dramas)], ); await tester.pumpWidget( ChangeNotifierProvider.value( value: controller, child: MaterialApp( theme: AppTheme.dark(), localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, home: const RankingPage(), ), ), ); await tester.pumpAndSettle(); } Drama _drama( String id, { int viewCount = 0, int? likeCount, String tag = '', String genre = '', String synopsis = '', }) => Drama( id: id, title: 'Drama $id', synopsis: synopsis, posterUrl: '', tag: tag, genre: genre, viewCount: viewCount, likeCount: likeCount, ); class _EmptyCatalogRepository implements CatalogRepository { @override Future fetchHomeFeed() async => const HomeFeed(); @override Future fetchDiscoverFeed() async => const HomeFeed(); @override Future fetchFeed({ List types = const [], String? categoryId, String? cursor, int size = 10, }) async => const FeedPage(); @override Future fetchDrama(String dramaId) async => Drama(id: dramaId, title: '', synopsis: '', posterUrl: ''); }