The prototype's station thumbnail is a plain 44-48px square, radius 11/12, with no ring or glow (t4 lines 84, 175, 227, 302, 614). TarjetaEmisora's compact row variant instead painted a 58x58 circle wrapped in a SweepGradient ring (magenta/cyan/coral) and a 22-blur glow behind a 50x50 ClipRRect(18). Replace it with a 48x48 ClipRRect(12) square. Update the loading shimmer placeholder to match (was also a 58x58 circle block). S6, Tier 1 visual-fidelity pass (audit id 2521).
98 lines
3.3 KiB
Dart
98 lines
3.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:pluriwave/estado/estado_radio.dart';
|
|
import 'package:pluriwave/l10n/gen/app_localizations.dart';
|
|
import 'package:pluriwave/widgets/tarjeta_emisora.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import '../helpers/fakes.dart';
|
|
|
|
/// S6 (Tier 1 visual fidelity): the prototype's station thumbnail is a
|
|
/// plain 44-48px square, radius 11/12, with NO ring or glow (t4 lines 84
|
|
/// `44px/radius 11`, 175 `46px/radius 12`, 227 `48px/radius 12`, 302
|
|
/// `48px/radius 12`, 614 `44px/radius 12`). The compact row variant used to
|
|
/// paint a 58x58 circle with a `SweepGradient` ring and a 22-blur glow
|
|
/// behind a 50x50 `ClipRRect(18)`.
|
|
void main() {
|
|
setUp(() {
|
|
SharedPreferences.setMockInitialValues({});
|
|
});
|
|
|
|
Widget host(Widget child) {
|
|
final estado = EstadoRadio(
|
|
audio: FakeServicioAudio(),
|
|
favoritos: FakeServicioFavoritos(),
|
|
radio: FakeServicioRadio(),
|
|
servicioEcualizador: FakeServicioEcualizador(),
|
|
iniciarAutomaticamente: false,
|
|
);
|
|
addTearDown(estado.dispose);
|
|
return ChangeNotifierProvider<EstadoRadio>.value(
|
|
value: estado,
|
|
child: MaterialApp(
|
|
locale: const Locale('en'),
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
home: Scaffold(body: Center(child: child)),
|
|
),
|
|
);
|
|
}
|
|
|
|
bool isRingContainer(Widget w) =>
|
|
w is Container &&
|
|
w.decoration is BoxDecoration &&
|
|
(w.decoration as BoxDecoration).shape == BoxShape.circle &&
|
|
(w.decoration as BoxDecoration).gradient is SweepGradient;
|
|
|
|
testWidgets('esCompacta (row) thumbnail is a 48x48 square, radius 12, no '
|
|
'ring/glow', (tester) async {
|
|
await tester.pumpWidget(
|
|
host(
|
|
SizedBox(
|
|
width: 320,
|
|
child: TarjetaEmisora(
|
|
emisora: emisoraDemo(uuid: 'row', nombre: 'Row FM'),
|
|
esCompacta: true,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.pump();
|
|
|
|
expect(find.byWidgetPredicate(isRingContainer), findsNothing);
|
|
|
|
// Not `.first` — the outer PluriGlassSurface also renders its own
|
|
// ClipRRect (radius 14, the row surface radius from S4), so the
|
|
// thumbnail's own clip must be found by its distinct radius instead of
|
|
// tree order.
|
|
final thumbnailClip = find.byWidgetPredicate(
|
|
(w) => w is ClipRRect && w.borderRadius == BorderRadius.circular(12),
|
|
);
|
|
expect(thumbnailClip, findsOneWidget);
|
|
expect(tester.getSize(thumbnailClip), const Size(48, 48));
|
|
});
|
|
|
|
testWidgets('esCompacta shimmer placeholder is a square block, not a '
|
|
'circle', (tester) async {
|
|
await tester.pumpWidget(
|
|
host(const TarjetaEmisoraShimmer(esCompacta: true)),
|
|
);
|
|
await tester.pump();
|
|
|
|
expect(find.byWidgetPredicate(isRingContainer), findsNothing);
|
|
final circles = tester
|
|
.widgetList<Container>(find.byType(Container))
|
|
.where(
|
|
(c) =>
|
|
c.decoration is BoxDecoration &&
|
|
(c.decoration as BoxDecoration).shape == BoxShape.circle,
|
|
);
|
|
expect(
|
|
circles,
|
|
isEmpty,
|
|
reason: 'the real thumbnail is square now — its shimmer must match',
|
|
);
|
|
});
|
|
}
|