Files
pluriwave/test/servicios/servicio_dispositivo_audio_toggle_test.dart
T
Javier Bautista Fernández 163ff69f7a
Build & Deploy PluriWave / Análisis de código (push) Successful in 26s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m16s
feat(eq): android auto custom equalizer and robust device detection
- MainActivity: onListen re-emits the current active device and registers
  the audio device callback idempotently, so recreated activities resync
  instead of freezing the active-device id on a disconnected device.
- servicio_dispositivo_audio: resubscribir() re-opens the event channel;
  estado_ecualizador exposes refrescarDispositivoActual() with an
  in-flight guard, invoked on app resume and when opening advanced EQ
  options, clearing stale green-dot device selections.
- navegacion_auto/servicio_audio: new 'Personalizado' browse tree in
  Android Auto (5 band folders, 13 gain steps each) applied live via
  setBanda; preset and gain taps persist at device level when
  multi-device EQ is active and respect station/matrix overrides,
  with apply-before-persist ordering and children-changed notifications.
- l10n: regenerate stale generated localizations; add rxdart as direct
  dependency for the subscribeToChildren override.
2026-07-22 10:26:02 +02:00

80 lines
2.5 KiB
Dart

import 'dart:async';
import 'package:flutter_test/flutter_test.dart';
import 'package:pluriwave/modelos/dispositivo_audio.dart';
import 'package:pluriwave/servicios/servicio_dispositivo_audio.dart';
import '../helpers/fakes.dart';
/// Null (toggle-off) implementation that returns empty data without errors.
/// Represents the behavior when `eqMultiDeviceEnabled` is false.
class NullServicioDispositivoAudio extends ServicioDispositivoAudio {
@override
DispositivoAudio? get dispositivoActual => null;
@override
Stream<DispositivoAudio> get onDispositivoCambiado => const Stream.empty();
@override
Future<DispositivoAudio> obtenerDispositivoActual() async {
return const DispositivoAudio(
id: 'builtin_speaker',
tipo: TipoDispositivo.altavozInterno,
nombre: 'Speaker',
);
}
@override
Future<void> resubscribir() async {}
@override
Future<bool> solicitarPermisoBluetooth() async => true;
@override
Future<void> dispose() async {}
}
void main() {
group('Toggle-off path: NullServicioDispositivoAudio', () {
late NullServicioDispositivoAudio servicio;
setUp(() {
servicio = NullServicioDispositivoAudio();
});
test('dispositivoActual is always null', () {
expect(servicio.dispositivoActual, isNull);
});
test('onDispositivoCambiado emits no events', () async {
final received = <DispositivoAudio>[];
final sub = servicio.onDispositivoCambiado.listen(received.add);
await Future<void>.delayed(const Duration(milliseconds: 10));
await sub.cancel();
expect(received, isEmpty);
});
test('obtenerDispositivoActual returns fallback builtin_speaker', () async {
final device = await servicio.obtenerDispositivoActual();
expect(device.id, 'builtin_speaker');
expect(device.tipo, TipoDispositivo.altavozInterno);
});
test('dispose completes without error', () async {
await expectLater(servicio.dispose(), completes);
});
test('no platform channel code is invoked (fake, not real)', () async {
// Verify that FakeServicioDispositivoAudio also produces no events
// when no emitirDispositivo is called — simulating toggle-off behavior.
final fake = FakeServicioDispositivoAudio();
final received = <DispositivoAudio>[];
final sub = fake.onDispositivoCambiado.listen(received.add);
await Future<void>.delayed(const Duration(milliseconds: 10));
await sub.cancel();
expect(received, isEmpty);
await fake.dispose();
});
});
}