Files
ReelShort/test/discover/cover_carousel_test.dart
T

194 lines
5.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:fruitshorts/l10n/app_localizations.dart';
import 'package:fruitshorts/pages/discover/widgets/cover_carousel.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
List<CoverItem> items(int count) => [
for (var index = 0; index < count; index++)
CoverItem(
title: 'Banner $index',
subtitle: 'Subtitle $index',
image: '/files/banner-$index.png',
onOpen: _noop,
),
];
testWidgets('should_turn_cube_and_keep_title_on_poster_when_carousel_pages', (
tester,
) async {
await tester.pumpWidget(
_localizedApp(
CoverCarousel(
items: [
for (final title in ['The Signal', 'City Lights', 'Vengeance'])
CoverItem(
title: title,
subtitle: 'Mock',
image: '/files/poster.png',
onOpen: _noop,
),
],
),
),
);
await tester.pump();
expect(find.text('The Signal'), findsOneWidget);
expect(find.text('Mock'), findsOneWidget);
final box = tester.getRect(find.byType(CoverCarousel));
final gesture = await tester.startGesture(
Offset(box.right - 40, box.center.dy),
);
await gesture.moveBy(const Offset(-500, 0));
await tester.pump();
final turned = tester
.widgetList<Transform>(find.byType(Transform))
.any((transform) => (transform.transform.entry(0, 0) - 1).abs() > 0.15);
expect(turned, isTrue);
await gesture.moveBy(const Offset(-200, 0));
await gesture.up();
await tester.pump();
await tester.pump(const Duration(milliseconds: 450));
expect(find.text('City Lights'), findsOneWidget);
expect(tester.takeException(), isNull);
});
testWidgets('should_auto_advance_and_show_dots_when_multiple_items_exist', (
tester,
) async {
await tester.pumpWidget(_localizedApp(CoverCarousel(items: items(3))));
await tester.pump();
expect(find.text('Banner 0'), findsOneWidget);
expect(find.byKey(const Key('carousel-dot-0')), findsOneWidget);
expect(find.byKey(const Key('carousel-dot-1')), findsOneWidget);
expect(find.byKey(const Key('carousel-dot-2')), findsOneWidget);
await tester.pump(const Duration(milliseconds: 4500));
await tester.pump(const Duration(milliseconds: 500));
expect(find.text('Banner 1'), findsOneWidget);
await tester.pumpWidget(const SizedBox.shrink());
});
testWidgets('should_not_schedule_auto_advance_when_only_one_item_exists', (
tester,
) async {
await tester.pumpWidget(_localizedApp(CoverCarousel(items: items(1))));
await tester.pump(const Duration(seconds: 12));
expect(find.text('Banner 0'), findsOneWidget);
expect(find.byKey(const Key('carousel-dot-0')), findsOneWidget);
expect(find.byKey(const Key('carousel-dot-1')), findsNothing);
});
testWidgets('should_pause_auto_advance_while_pointer_is_down', (
tester,
) async {
await tester.pumpWidget(_localizedApp(CoverCarousel(items: items(3))));
await tester.pump();
final box = tester.getRect(find.byType(CoverCarousel));
final gesture = await tester.startGesture(box.center);
await tester.pump(const Duration(seconds: 6));
expect(find.text('Banner 0'), findsOneWidget);
await gesture.up();
await tester.pump();
await tester.pump(const Duration(milliseconds: 4500));
await tester.pump(const Duration(milliseconds: 500));
expect(find.text('Banner 1'), findsOneWidget);
await tester.pumpWidget(const SizedBox.shrink());
});
testWidgets('should_pause_when_inactive_and_resume_when_active_again', (
tester,
) async {
final active = ValueNotifier(false);
await tester.pumpWidget(
_localizedApp(
ValueListenableBuilder<bool>(
valueListenable: active,
builder: (context, enabled, _) =>
CoverCarousel(items: items(2), active: enabled),
),
),
);
await tester.pump(const Duration(seconds: 6));
expect(find.text('Banner 0'), findsOneWidget);
active.value = true;
await tester.pump();
await tester.pump(const Duration(milliseconds: 4500));
await tester.pump(const Duration(milliseconds: 500));
expect(find.text('Banner 1'), findsOneWidget);
await tester.pumpWidget(const SizedBox.shrink());
});
testWidgets('should_show_icon_fallback_when_banner_image_is_empty', (
tester,
) async {
await tester.pumpWidget(
_localizedApp(
CoverCarousel(
items: const [
CoverItem(
title: 'Broken image',
subtitle: '',
image: '',
onOpen: _noop,
),
],
),
),
);
await tester.pump();
expect(find.byKey(const Key('carousel-image-fallback')), findsOneWidget);
});
testWidgets(
'should_keep_existing_open_callback_when_active_poster_is_tapped',
(tester) async {
var opened = 0;
await tester.pumpWidget(
_localizedApp(
CoverCarousel(
items: [
CoverItem(
title: 'Tap me',
subtitle: '',
image: '/files/banner.png',
onOpen: () => opened++,
),
...items(1),
],
),
),
);
await tester.pump();
await tester.tap(find.text('Tap me'));
expect(opened, 1);
await tester.pumpWidget(const SizedBox.shrink());
},
);
}
void _noop() {}
Widget _localizedApp(Widget child) => MaterialApp(
locale: const Locale('en'),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
home: Scaffold(body: child),
);