// Author: fruit.com.cn // 职责:验证共用简介的短文案、展开声明、内容更新与减少动画行为。 import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:fruitshorts/core/theme/app_colors.dart'; import 'package:fruitshorts/core/theme/app_theme.dart'; import 'package:fruitshorts/l10n/app_localizations.dart'; import 'package:fruitshorts/pages/player/widgets/expandable_synopsis.dart'; const _width = 300.0; const _shortCopy = 'A short story.'; const _longCopy = 'A hidden promise brings two families together after years apart. ' 'Every secret leads them closer to an unexpected truth. ' 'Their journey through the city changes everything they once believed.'; const _toggle = Key('player-synopsis-more'); const _expanded = Key('player-synopsis-expanded'); const _collapsed = Key('player-synopsis'); const _footer = Text('Author declaration', key: Key('test-author-note')); const _motionSample = Duration(milliseconds: 80); Future _pump( WidgetTester tester, { String synopsis = _longCopy, bool disableAnimations = false, }) async { await tester.pumpWidget( MaterialApp( theme: AppTheme.dark(), locale: const Locale('en'), localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, home: Builder( builder: (context) => MediaQuery( data: MediaQuery.of( context, ).copyWith(disableAnimations: disableAnimations), child: Scaffold( body: Align( alignment: Alignment.bottomLeft, child: SizedBox( width: _width, child: ExpandableSynopsis( synopsis: synopsis, keyPrefix: 'player', expandedFooter: _footer, ), ), ), ), ), ), ), ); } void main() { testWidgets('should_use_video_copy_color_when_player_does_not_override', ( tester, ) async { await _pump(tester, synopsis: _shortCopy); final synopsis = tester.widget(find.byKey(_collapsed)); expect(synopsis.style?.color, AppColors.homeFeedVideoCopy); }); testWidgets('should_hide_toggle_when_synopsis_fits_two_lines', ( tester, ) async { await _pump(tester, synopsis: _shortCopy); expect(find.byKey(_toggle), findsNothing); expect(tester.widget(find.byKey(_collapsed)).maxLines, 2); expect(find.byKey(_footer.key!), findsNothing); }); testWidgets('should_render_no_copy_when_synopsis_is_empty', (tester) async { await _pump(tester, synopsis: ''); expect(find.byKey(_collapsed), findsNothing); expect(find.byKey(_toggle), findsNothing); expect(find.byKey(_footer.key!), findsNothing); }); testWidgets('should_only_show_author_note_when_synopsis_is_expanded', ( tester, ) async { await _pump(tester); final toggle = find.byKey(_toggle); final toggleRect = tester.getRect(toggle); expect(find.byKey(_footer.key!), findsNothing); await tester.tap(toggle); await tester.pumpAndSettle(); expect(find.byKey(_expanded), findsOneWidget); expect(find.byKey(_footer.key!), findsOneWidget); expect(tester.getRect(toggle), toggleRect); await tester.tap(toggle); await tester.pumpAndSettle(); expect(find.byKey(_collapsed), findsOneWidget); expect(find.byKey(_footer.key!), findsNothing); expect(tester.getRect(toggle), toggleRect); }); testWidgets('should_collapse_again_when_synopsis_changes', (tester) async { await _pump(tester); await tester.tap(find.byKey(_toggle)); await tester.pumpAndSettle(); expect(find.byKey(_expanded), findsOneWidget); await _pump(tester, synopsis: '$_longCopy $_shortCopy'); await tester.pumpAndSettle(); expect(find.byKey(_expanded), findsNothing); expect(find.byKey(_collapsed), findsOneWidget); expect(find.byKey(_footer.key!), findsNothing); }); testWidgets('should_toggle_immediately_when_animations_are_disabled', ( tester, ) async { await _pump(tester, disableAnimations: true); await tester.pumpAndSettle(); expect(find.byKey(const Key('player-synopsis-size')), findsNothing); await tester.tap(find.byKey(_toggle)); await tester.pump(); expect(find.byKey(_expanded), findsOneWidget); expect(find.byKey(_footer.key!), findsOneWidget); final expandedRect = tester.getRect(find.byKey(_expanded)); await tester.pump(_motionSample); expect(tester.getRect(find.byKey(_expanded)), expandedRect); }); }