diff --git a/lib/pantallas/pantalla_inicio.dart b/lib/pantallas/pantalla_inicio.dart index 2e490a1..f21ef2e 100644 --- a/lib/pantallas/pantalla_inicio.dart +++ b/lib/pantallas/pantalla_inicio.dart @@ -267,6 +267,22 @@ class _EscucharHero extends StatelessWidget { maxLines: 2, overflow: TextOverflow.ellipsis, ), + if (_metaEscuchar(emisora) case final meta?) ...[ + const SizedBox(height: 4), + Text( + meta, + key: const ValueKey('escuchar-hero-meta'), + style: TextStyle( + fontSize: 12.5, + fontWeight: FontWeight.w600, + color: theme.colorScheme.onSurface.withValues( + alpha: 0.62, + ), + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], const SizedBox(height: 8), VisualizadorAudio( estadoStream: estado.estadoStream, @@ -536,3 +552,17 @@ class _FilaTransporteEscuchar extends StatelessWidget { : l10n.durationMinutesSeconds(d.inMinutes, s); } } + +/// Audit 1.6 (t4 line 62): "género · país · kbps" built ONLY from fields +/// [Emisora] already carries (`tags`/`pais`/`bitrate`) — no new fields, no +/// service calls. Whatever a station lacks is omitted gracefully; this +/// never renders a stray leading/trailing/doubled " · ". +String? _metaEscuchar(Emisora emisora) { + final partes = [ + if (emisora.generos.isNotEmpty) emisora.generos.first, + if (emisora.pais != null && emisora.pais!.isNotEmpty) emisora.pais!, + if (emisora.bitrate != null && emisora.bitrate! > 0) + '${emisora.bitrate} kbps', + ]; + return partes.isEmpty ? null : partes.join(' · '); +} diff --git a/test/pantallas/pantalla_inicio_test.dart b/test/pantallas/pantalla_inicio_test.dart index 3fa054f..ddcef0c 100644 --- a/test/pantallas/pantalla_inicio_test.dart +++ b/test/pantallas/pantalla_inicio_test.dart @@ -8,6 +8,7 @@ import 'package:pluriwave/estado/estado_grabacion.dart'; import 'package:pluriwave/estado/estado_navegacion.dart'; import 'package:pluriwave/estado/estado_radio.dart'; import 'package:pluriwave/l10n/gen/app_localizations.dart'; +import 'package:pluriwave/modelos/emisora.dart'; import 'package:pluriwave/pantallas/pantalla_inicio.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -164,6 +165,79 @@ void main() { reason: 'prototype t4 line 56 sizes the Escuchar hero artwork at 132', ); }); + + testWidgets('visual fidelity (audit 1.6): the hero shows "genre · country · ' + 'bitrate kbps" built from the station model, nothing invented', ( + tester, + ) async { + _setLargeSurfaceSize(tester); + final favoritos = FakeServicioFavoritos(); + final estado = EstadoRadio( + audio: FakeServicioAudio(), + favoritos: favoritos, + radio: FakeServicioRadio(), + servicioEcualizador: FakeServicioEcualizador(), + servicioGrabacion: FakeServicioGrabacionRadio(), + resolverArchivoCustom: _archivoCustomVacio, + iniciarAutomaticamente: false, + ); + addTearDown(estado.dispose); + await tester.runAsync(estado.inicializar); + const completa = Emisora( + uuid: 'meta-1', + nombre: 'Radio Horizonte', + url: 'https://stream.demo/radio', + tags: 'Noticias', + pais: 'España', + bitrate: 128, + ); + await favoritos.agregar(completa); + await estado.cargarFavoritos(); + // The hero only renders when a station is active. + await tester.runAsync(() => estado.reproducir(completa)); + + await tester.pumpWidget( + _conProviders(estado, _testApp(const PantallaInicio())), + ); + await _pumpBounded(tester); + + expect( + find.text('Noticias · España · 128 kbps'), + findsOneWidget, + reason: 'prototype t4 line 62: "Noticias · España · 128 kbps"', + ); + }); + + testWidgets( + 'visual fidelity (audit 1.6): a station missing every meta field omits ' + 'the line gracefully, no stray separators', + (tester) async { + _setLargeSurfaceSize(tester); + final favoritos = FakeServicioFavoritos(); + final estado = EstadoRadio( + audio: FakeServicioAudio(), + favoritos: favoritos, + radio: FakeServicioRadio(), + servicioEcualizador: FakeServicioEcualizador(), + servicioGrabacion: FakeServicioGrabacionRadio(), + resolverArchivoCustom: _archivoCustomVacio, + iniciarAutomaticamente: false, + ); + addTearDown(estado.dispose); + await tester.runAsync(estado.inicializar); + final desnuda = emisoraDemo(uuid: 'meta-2', nombre: 'Radio Desnuda'); + await favoritos.agregar(desnuda); + await estado.cargarFavoritos(); + await tester.runAsync(() => estado.reproducir(desnuda)); + + await tester.pumpWidget( + _conProviders(estado, _testApp(const PantallaInicio())), + ); + await _pumpBounded(tester); + + expect(find.byKey(const ValueKey('escuchar-hero-meta')), findsNothing); + }, + ); } /// Mirrors the app.dart wiring: EstadoRadio owns the domain notifiers and