EstadoAlarmas, EstadoGrabacion and EstadoRadio defaulted `esPremium` to `() => true`, so any construction site that forgot to wire entitlement compiled fine and silently ran ungated — failing OPEN to premium and disabling the paywall with no test able to catch it. The parameter is now required with no default. Production wiring in app.dart was already correct and is unchanged; the 184 pre-existing test call sites now pass `() => true` explicitly, which is exactly the old implicit default, so every assertion is untouched. EstadoRadio has no gate of its own but constructs EstadoGrabacion, so it inherits the same contract. The one test that existed to pin the old default is renamed to describe what it still covers (the premium path through iniciar() with no duracion); its assertions are unchanged.
77 lines
2.5 KiB
Dart
77 lines
2.5 KiB
Dart
import 'dart:ui' show Tristate;
|
|
|
|
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';
|
|
|
|
/// S5-R2: the mini favorite button in the full card must be accessible
|
|
/// (semantic button with label + toggled state) and reach a 48dp target.
|
|
void main() {
|
|
setUp(() {
|
|
SharedPreferences.setMockInitialValues({});
|
|
});
|
|
|
|
testWidgets('el favorito mini es accesible y mide al menos 48x48 dp', (
|
|
tester,
|
|
) async {
|
|
final semantics = tester.ensureSemantics();
|
|
final estado = EstadoRadio(
|
|
esPremium: () => true,
|
|
audio: FakeServicioAudio(),
|
|
favoritos: FakeServicioFavoritos(),
|
|
radio: FakeServicioRadio(),
|
|
servicioEcualizador: FakeServicioEcualizador(),
|
|
iniciarAutomaticamente: false,
|
|
);
|
|
addTearDown(estado.dispose);
|
|
|
|
await tester.pumpWidget(
|
|
ChangeNotifierProvider<EstadoRadio>.value(
|
|
value: estado,
|
|
child: MaterialApp(
|
|
locale: const Locale('es'),
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: SizedBox(
|
|
width: 220,
|
|
height: 300,
|
|
// Full (non-compact) card: it renders the MINI favorite.
|
|
child: TarjetaEmisora(
|
|
emisora: emisoraDemo(uuid: 'a11y-1', nombre: 'A11y FM'),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.pump();
|
|
|
|
final l10n = await AppLocalizations.delegate.load(const Locale('es'));
|
|
|
|
// Semantic node: button + label (favorite is OFF, so the "add" label).
|
|
final boton = find.bySemanticsLabel(l10n.favoritesAddTooltip);
|
|
expect(boton, findsOneWidget);
|
|
final nodo = tester.getSemantics(boton);
|
|
final flags = nodo.flagsCollection;
|
|
expect(flags.isButton, isTrue);
|
|
// Toggled state present (favorite OFF) — tristate: not null, not true.
|
|
expect(flags.isToggled, Tristate.isFalse);
|
|
|
|
// Touch target: at least 48x48 dp (S5-R2-A).
|
|
final size = tester.getSize(boton);
|
|
expect(size.width, greaterThanOrEqualTo(48));
|
|
expect(size.height, greaterThanOrEqualTo(48));
|
|
|
|
semantics.dispose();
|
|
});
|
|
}
|