Files
plezy/test/widgets/clear_logo_image_test.dart

88 lines
3.4 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:plezy/utils/layout_constants.dart';
import 'package:plezy/widgets/optimized_media_image.dart';
void main() {
Widget buildLogo({String? logoPath, double width = 400, double height = 120, double devicePixelRatio = 3}) {
return MaterialApp(
home: MediaQuery(
// DPR 3 is where the phone hero logo slot (400×120) asks for a
// 1200-wide decode and runs into the 1000px heroLogo width cap.
data: MediaQueryData(size: const Size(390, 844), devicePixelRatio: devicePixelRatio, disableAnimations: true),
child: Center(
child: ClearLogoImage(
client: null,
logoPath: logoPath,
width: width,
height: height,
fallbackBuilder: (context) => const Text('Fallback Title'),
),
),
),
);
}
testWidgets('decodes with the aspect-preserving fit policy', (tester) async {
await tester.pumpWidget(buildLogo(logoPath: 'https://example.com/logo.png'));
final provider = tester.widget<Image>(find.byType(Image)).image;
// Both axes stay bounded so an oversized original can't blow the decode
// budget, but `fit` keeps the source ratio: capping only the width under
// the default `exact` policy is what squashed hero logos on phones.
expect(
provider,
isA<ResizeImage>()
.having((r) => r.policy, 'policy', ResizeImagePolicy.fit)
.having((r) => r.width, 'width', isNotNull)
.having((r) => r.height, 'height', isNotNull),
);
});
testWidgets('bounds the TV spotlight slot without pinning it to the slot ratio', (tester) async {
// The TV slot (520×150 at the 2.0 TV DPR floor) asks for 1040×300 and is
// capped to 1000×300 — the width clamps, the height doesn't. Under the old
// `exact` decode that pinned every TV logo to 3.331: a 4313×1035 source
// served at 1250×300 rendered as 1000×300, 1.25x too tall (checked against
// PMS 1.43). `fit` scales it to 1000×240 and keeps 4.171.
await tester.pumpWidget(
buildLogo(
logoPath: 'https://example.com/logo.png',
width: TvLayoutConstants.heroLogoWidth,
height: TvLayoutConstants.heroLogoHeight,
devicePixelRatio: 2,
),
);
expect(
tester.widget<Image>(find.byType(Image)).image,
isA<ResizeImage>()
.having((r) => r.policy, 'policy', ResizeImagePolicy.fit)
.having((r) => r.width, 'width', 1000)
.having((r) => r.height, 'height', 300),
);
});
testWidgets('falls back to the title when there is no logo path', (tester) async {
await tester.pumpWidget(buildLogo(logoPath: null));
expect(find.text('Fallback Title'), findsOneWidget);
expect(find.byType(Image), findsNothing);
});
testWidgets('falls back to the title when no URL can be built', (tester) async {
// Relative path with no client (offline) resolves to an empty URL.
await tester.pumpWidget(buildLogo(logoPath: '/library/metadata/1/clearLogo'));
expect(find.text('Fallback Title'), findsOneWidget);
expect(find.byType(Image), findsNothing);
});
testWidgets('sizes itself to the requested logo slot', (tester) async {
await tester.pumpWidget(buildLogo(logoPath: null, width: 520, height: 150));
expect(tester.getSize(find.byType(ClearLogoImage)), const Size(520, 150));
});
}