Files
ReelShort/test/recommend/home_hero_carousel_test.dart
T

118 lines
3.8 KiB
Dart

// 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/home_feed.dart';
import 'package:fruitshorts/core/theme/app_colors.dart';
import 'package:fruitshorts/l10n/app_localizations.dart';
import 'package:fruitshorts/pages/recommend/widgets/home_hero_carousel.dart';
const List<FeedBanner> _banners = [
FeedBanner(id: '1', imageUrl: 'https://cdn.test/a.png'),
FeedBanner(id: '2', imageUrl: 'https://cdn.test/b.png'),
];
const Drama _drama = Drama(
id: 'd1',
title: 'City Lights',
synopsis: 'A quiet city romance.',
posterUrl: 'https://cdn.test/d.png',
);
Widget _harness(List<FeedBanner> banners, {Drama? drama}) {
return MaterialApp(
locale: const Locale('en'),
supportedLocales: AppLocalizations.supportedLocales,
localizationsDelegates: AppLocalizations.localizationsDelegates,
home: Scaffold(
body: HomeHeroCarousel(
banners: banners,
dramaFor: (_) => drama,
onWatch: (_) {},
),
),
);
}
Color? _dotColor(WidgetTester tester, int index) {
final decoration =
tester
.widget<Container>(find.byKey(Key('home-hero-dot-$index')))
.decoration
as BoxDecoration?;
return decoration?.color;
}
void main() {
testWidgets('should_keep_looping_backwards_from_the_first_banner', (
tester,
) async {
await tester.pumpWidget(_harness(_banners));
await tester.pumpAndSettle();
expect(_dotColor(tester, 0), AppColors.brandRed);
// 从第一张往右滑:无缝轮播应该接到最后一张,而不是被边界挡住。
await tester.fling(find.byType(PageView), const Offset(700, 0), 1200);
await tester.pumpAndSettle();
expect(_dotColor(tester, 1), AppColors.brandRed);
expect(_dotColor(tester, 0), isNot(AppColors.brandRed));
});
testWidgets('should_wrap_to_first_banner_after_last_auto_advance', (
tester,
) async {
await tester.pumpWidget(_harness(_banners));
await tester.pumpAndSettle();
// 自动播两次:第 2 张之后应回到第 1 张,且页码继续往前走不回头。
await tester.pump(const Duration(milliseconds: 4600));
await tester.pumpAndSettle();
expect(_dotColor(tester, 1), AppColors.brandRed);
await tester.pump(const Duration(milliseconds: 4600));
await tester.pumpAndSettle();
expect(_dotColor(tester, 0), AppColors.brandRed);
});
testWidgets('should_keep_only_title_and_synopsis_above_dots', (tester) async {
await tester.pumpWidget(_harness(_banners, drama: _drama));
await tester.pumpAndSettle();
final copy = find.byKey(const Key('home-hero-copy-0'));
expect(copy, findsOneWidget);
expect(
find.descendant(of: copy, matching: find.text('City Lights')),
findsOneWidget,
);
expect(
find.descendant(
of: copy,
matching: find.text('A quiet city romance.'),
),
findsOneWidget,
);
expect(find.byKey(const Key('home-hero-watch')), findsNothing);
expect(find.byKey(const Key('home-hero-favorite')), findsNothing);
// 文案块整体位于轮播点上方,给进度点留出间距。
final copyRect = tester.getRect(copy);
final dotRect = tester.getRect(find.byKey(const Key('home-hero-dot-0')));
expect(copyRect.bottom, lessThanOrEqualTo(dotRect.top));
});
testWidgets('should_not_loop_when_only_one_banner', (tester) async {
await tester.pumpWidget(
_harness(const [FeedBanner(id: '1', imageUrl: 'https://cdn.test/a.png')]),
);
await tester.pumpAndSettle();
expect(find.byKey(const Key('home-hero-dot-0')), findsNothing);
await tester.pump(const Duration(milliseconds: 6000));
await tester.pumpAndSettle();
expect(tester.takeException(), isNull);
});
}