import 'package:flutter_test/flutter_test.dart'; import 'package:pluriwave/modelos/emisora.dart'; import 'package:pluriwave/modelos/grupo_favoritos.dart'; import 'package:pluriwave/servicios/navegacion_auto.dart'; /// Requested: the Android Auto playback screen must offer previous/next for /// stations too, not only for a local-music queue. Those buttons appear /// because `skipToPrevious`/`skipToNext` are advertised in `systemActions` — /// so they have to actually move, or the car shows two dead buttons. void main() { Emisora emisora(String uuid) => Emisora(uuid: uuid, nombre: uuid, url: 'https://example.com/$uuid'); final a = emisora('a'); final b = emisora('b'); final c = emisora('c'); group('emisoraVecina', () { test('avanza y retrocede dentro de la lista', () { expect(emisoraVecina(a, [a, b, c], haciaAtras: false), b); expect(emisoraVecina(b, [a, b, c], haciaAtras: true), a); }); test('da la vuelta en los dos extremos', () { // A dead button at the end of a list reads as a broken app on a car // screen, where there is no visible list position to explain it. expect(emisoraVecina(c, [a, b, c], haciaAtras: false), a); expect(emisoraVecina(a, [a, b, c], haciaAtras: true), c); }); test('identifica por uuid, no por instancia: un snapshot refrescado trae ' 'objetos distintos', () { final copiaDeB = Emisora( uuid: 'b', nombre: 'otro nombre', url: 'https://example.com/cambiada', ); expect(emisoraVecina(copiaDeB, [a, b, c], haciaAtras: false), c); }); test('no hace nada sin contexto suficiente', () { expect(emisoraVecina(null, [a, b], haciaAtras: false), isNull); expect(emisoraVecina(a, [a], haciaAtras: false), isNull); expect(emisoraVecina(a, const [], haciaAtras: false), isNull); expect( emisoraVecina(emisora('fuera'), [a, b], haciaAtras: false), isNull, reason: 'una emisora que no está en la lista no debe saltar a ciegas', ); }); }); group('listaParaSaltoEmisora', () { test('favoritos gana: "siguiente" desde un favorito va al siguiente ' 'favorito, no a la entrada 4318 del catálogo', () { expect( listaParaSaltoEmisora( actual: a, favoritos: [a, b], misEmisoras: [a, c], todas: [a, b, c], ), [a, b], ); }); test('mis emisoras cuando no es favorita', () { expect( listaParaSaltoEmisora( actual: c, favoritos: [a, b], misEmisoras: [c, a], todas: [a, b, c], ), [c, a], ); }); test('cae al catálogo completo para una emisora llegada por búsqueda', () { expect( listaParaSaltoEmisora( actual: c, favoritos: [a], misEmisoras: [b], todas: [a, b, c], ), [a, b, c], ); }); test('vacía si no está en ninguna: el salto queda en no-op', () { expect( listaParaSaltoEmisora( actual: emisora('huerfana'), favoritos: [a], misEmisoras: [b], todas: [a, b], ), isEmpty, ); }); }); group('navegación por GRUPO de favoritos (pedido por el dueño)', () { Emisora favorita(String uuid, String grupo) => Emisora( uuid: uuid, nombre: uuid, url: 'https://example.com/$uuid', grupoFavoritosId: grupo, ); final rock1 = favorita('rock1', 'g-rock'); final rock2 = favorita('rock2', 'g-rock'); final jazz1 = favorita('jazz1', 'g-jazz'); final suelta = favorita('suelta', GrupoFavoritos.sinAsignarId); test('sonando una favorita de un grupo, se recorre SOLO ese grupo', () { expect( listaParaSaltoEmisora( actual: rock1, favoritos: [rock1, jazz1, rock2, suelta], misEmisoras: const [], todas: [rock1, jazz1, rock2, suelta], ), [rock1, rock2], ); }); test('el grupo se lee del registro de FAVORITOS, no de lo que suena: la ' 'emisora reconstruida desde el MediaItem no lleva grupo', () { // emisoraDesdeMediaItem no puede saber el grupo -> llega "sin asignar". final reconstruida = Emisora( uuid: 'rock1', nombre: 'Rock 1', url: 'https://example.com/rock1', ); expect(reconstruida.grupoFavoritosId, GrupoFavoritos.sinAsignarId); expect( listaParaSaltoEmisora( actual: reconstruida, favoritos: [rock1, jazz1, rock2], misEmisoras: const [], todas: const [], ), [rock1, rock2], reason: 'si se leyera de `actual` caeríamos a todos los favoritos', ); }); test('"sin asignar" NO es un grupo: recorre todos los favoritos', () { expect( listaParaSaltoEmisora( actual: suelta, favoritos: [rock1, suelta, jazz1], misEmisoras: const [], todas: const [], ), [rock1, suelta, jazz1], ); }); test('un grupo de UNA sola emisora cae a todos los favoritos, para no ' 'dejar los dos botones muertos', () { expect( listaParaSaltoEmisora( actual: jazz1, favoritos: [rock1, rock2, jazz1], misEmisoras: const [], todas: const [], ), [rock1, rock2, jazz1], ); }); }); }