255 lines
8.2 KiB
Dart
255 lines
8.2 KiB
Dart
// 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/l10n/app_localizations.dart';
|
|
import 'package:fruitshorts/pages/player/widgets/player_more_sheet.dart';
|
|
|
|
void main() {
|
|
testWidgets('should_hide_pip_row_when_platform_unsupported', (tester) async {
|
|
await _openSheet(tester);
|
|
|
|
expect(find.byKey(const Key('player-more-sheet')), findsOneWidget);
|
|
expect(find.byKey(const Key('player-more-clear')), findsOneWidget);
|
|
expect(find.byKey(const Key('player-more-offline')), findsOneWidget);
|
|
expect(find.byKey(const Key('player-more-pip')), findsNothing);
|
|
expect(find.byKey(const Key('player-more-close')), findsNothing);
|
|
});
|
|
|
|
testWidgets('should_render_reference_layout_metrics', (tester) async {
|
|
await _openSheet(tester);
|
|
|
|
expect(
|
|
tester.widget<Material>(find.byKey(const Key('player-more-sheet'))).color,
|
|
AppColors.ink,
|
|
);
|
|
expect(
|
|
tester.getSize(find.byKey(const Key('player-more-drag-handle'))),
|
|
const Size(36, 4),
|
|
);
|
|
for (final key in const [
|
|
Key('player-more-speed-row'),
|
|
Key('player-more-quality-row'),
|
|
Key('player-more-clear'),
|
|
Key('player-more-offline'),
|
|
]) {
|
|
expect(tester.getSize(find.byKey(key)).height, 56);
|
|
}
|
|
for (final key in const [
|
|
Key('player-more-speed-track'),
|
|
Key('player-more-quality-track'),
|
|
]) {
|
|
expect(tester.getSize(find.byKey(key)).height, 34);
|
|
final trackDecoration =
|
|
tester.widget<Container>(find.byKey(key)).decoration!
|
|
as BoxDecoration;
|
|
expect(trackDecoration.color, AppColors.raised);
|
|
}
|
|
for (final key in const [
|
|
Key('player-more-speed-0.75'),
|
|
Key('player-more-speed-1.0'),
|
|
Key('player-more-speed-1.25'),
|
|
]) {
|
|
expect(tester.getSize(find.byKey(key)).height, 26);
|
|
}
|
|
|
|
final speedLabel = tester.widget<Text>(
|
|
find
|
|
.descendant(
|
|
of: find.byKey(const Key('player-more-speed-row')),
|
|
matching: find.byType(Text),
|
|
)
|
|
.first,
|
|
);
|
|
expect(speedLabel.style?.fontSize, 15);
|
|
expect(speedLabel.style?.fontWeight, FontWeight.w500);
|
|
expect(tester.widget<Icon>(find.byIcon(Icons.speed_outlined)).size, 22);
|
|
expect(tester.widget<Icon>(find.byIcon(Icons.fullscreen)).size, 22);
|
|
|
|
final selected = tester.widget<Container>(
|
|
find
|
|
.descendant(
|
|
of: find.byKey(const Key('player-more-speed-1.0')),
|
|
matching: find.byType(Container),
|
|
)
|
|
.first,
|
|
);
|
|
final selectedDecoration = selected.decoration! as BoxDecoration;
|
|
expect(selectedDecoration.color, AppColors.card);
|
|
expect(selectedDecoration.boxShadow, isNotEmpty);
|
|
final selectedText = tester.widget<Text>(
|
|
find.descendant(
|
|
of: find.byKey(const Key('player-more-speed-1.0')),
|
|
matching: find.text('1.0x'),
|
|
),
|
|
);
|
|
expect(selectedText.style?.color, AppColors.onSurface);
|
|
expect(selectedText.style?.fontSize, 13);
|
|
expect(selectedText.style?.fontWeight, FontWeight.w600);
|
|
|
|
final unselected = tester.widget<Container>(
|
|
find
|
|
.descendant(
|
|
of: find.byKey(const Key('player-more-speed-1.25')),
|
|
matching: find.byType(Container),
|
|
)
|
|
.first,
|
|
);
|
|
final unselectedDecoration = unselected.decoration! as BoxDecoration;
|
|
expect(unselectedDecoration.color, Colors.transparent);
|
|
final unselectedText = tester.widget<Text>(
|
|
find.descendant(
|
|
of: find.byKey(const Key('player-more-speed-1.25')),
|
|
matching: find.text('1.25x'),
|
|
),
|
|
);
|
|
expect(unselectedText.style?.color, AppColors.muted);
|
|
expect(unselectedText.style?.fontSize, 13);
|
|
expect(unselectedText.style?.fontWeight, FontWeight.w400);
|
|
|
|
final disabledText = tester.widget<Text>(
|
|
find.descendant(
|
|
of: find.byKey(const Key('player-more-quality-720P')),
|
|
matching: find.byType(Text),
|
|
),
|
|
);
|
|
expect(disabledText.style?.color, AppColors.subtle);
|
|
});
|
|
|
|
testWidgets('should_enable_quality_when_ticket_uses_lowercase_codes', (
|
|
tester,
|
|
) async {
|
|
await _openSheet(
|
|
tester,
|
|
qualities: const ['AUTO', '360p', '480p', '720p', '1080p'],
|
|
);
|
|
|
|
expect(find.text('720P'), findsOneWidget);
|
|
expect(find.text('1080P'), findsOneWidget);
|
|
expect(find.textContaining('暂不可用'), findsNothing);
|
|
final enabled = tester.widget<Text>(
|
|
find.descendant(
|
|
of: find.byKey(const Key('player-more-quality-720P')),
|
|
matching: find.byType(Text),
|
|
),
|
|
);
|
|
expect(enabled.style?.color, isNot(AppColors.subtle));
|
|
});
|
|
|
|
testWidgets('should_report_selected_quality_when_a_rendition_is_tapped', (
|
|
tester,
|
|
) async {
|
|
String? picked;
|
|
await _openSheet(
|
|
tester,
|
|
qualities: const ['AUTO', '720p'],
|
|
onQuality: (quality) async {
|
|
picked = quality;
|
|
return true;
|
|
},
|
|
);
|
|
|
|
await tester.ensureVisible(find.byKey(const Key('player-more-quality-720P')));
|
|
await tester.tap(find.byKey(const Key('player-more-quality-720P')));
|
|
await tester.pump();
|
|
|
|
expect(picked, '720P');
|
|
final selected = tester.widget<Text>(
|
|
find.descendant(
|
|
of: find.byKey(const Key('player-more-quality-720P')),
|
|
matching: find.byType(Text),
|
|
),
|
|
);
|
|
expect(selected.style?.color, AppColors.onSurface);
|
|
});
|
|
|
|
testWidgets('should_restore_previous_quality_when_switch_fails', (
|
|
tester,
|
|
) async {
|
|
await _openSheet(
|
|
tester,
|
|
qualities: const ['AUTO', '720p'],
|
|
onQuality: (_) async => false,
|
|
);
|
|
|
|
await tester.ensureVisible(find.byKey(const Key('player-more-quality-720P')));
|
|
await tester.tap(find.byKey(const Key('player-more-quality-720P')));
|
|
await tester.pumpAndSettle();
|
|
|
|
final restored = tester.widget<Text>(
|
|
find.descendant(
|
|
of: find.byKey(const Key('player-more-quality-AUTO')),
|
|
matching: find.byType(Text),
|
|
),
|
|
);
|
|
expect(restored.style?.color, AppColors.onSurface);
|
|
});
|
|
|
|
testWidgets('should_trigger_pip_and_close_sheet_when_tapped', (tester) async {
|
|
var pipCalls = 0;
|
|
await _openSheet(tester, onPip: () => pipCalls++);
|
|
|
|
expect(find.byKey(const Key('player-more-pip')), findsOneWidget);
|
|
expect(
|
|
tester.getTopLeft(find.byKey(const Key('player-more-clear'))).dy <
|
|
tester.getTopLeft(find.byKey(const Key('player-more-pip'))).dy,
|
|
isTrue,
|
|
);
|
|
expect(
|
|
tester.getTopLeft(find.byKey(const Key('player-more-pip'))).dy <
|
|
tester.getTopLeft(find.byKey(const Key('player-more-offline'))).dy,
|
|
isTrue,
|
|
);
|
|
|
|
await tester.tap(find.byKey(const Key('player-more-pip')));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(pipCalls, 1);
|
|
expect(find.byKey(const Key('player-more-sheet')), findsNothing);
|
|
});
|
|
}
|
|
|
|
Future<void> _openSheet(
|
|
WidgetTester tester, {
|
|
VoidCallback? onPip,
|
|
Future<bool> Function(String quality)? onQuality,
|
|
List<String> qualities = const ['AUTO'],
|
|
}) async {
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
home: Scaffold(
|
|
body: Builder(
|
|
builder: (context) => Center(
|
|
child: TextButton(
|
|
key: const Key('open-more-sheet'),
|
|
onPressed: () => showModalBottomSheet<void>(
|
|
context: context,
|
|
backgroundColor: Colors.transparent,
|
|
isScrollControlled: true,
|
|
builder: (_) => PlayerMoreSheet(
|
|
l10n: AppLocalizations.of(context)!,
|
|
state: PlayerMoreState(speed: 1.0, qualities: qualities),
|
|
actions: PlayerMoreActions(
|
|
onSpeedChanged: (_) {},
|
|
onClear: () {},
|
|
onDownload: () {},
|
|
onQualityChanged: onQuality ?? (_) async => true,
|
|
onPip: onPip,
|
|
),
|
|
),
|
|
),
|
|
child: const Text('open'),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.tap(find.byKey(const Key('open-more-sheet')));
|
|
await tester.pumpAndSettle();
|
|
}
|