feat(auto): add an Ecualizador browsable folder with preset selection
On-device feedback showed the equalizer's preset-cycling custom action
looked dead: many head units render custom actions icon-first, and a
monochrome icon cannot legibly encode "which of six presets" the way a
browsable list's text rows can.
This adds an "Ecualizador" folder to the car's browse tree, listing
"Desactivar" first, then the six factory presets by name, with the
currently-active one marked. Selecting a preset routes through the same
playFromMediaId seam every other browse-tree leaf already uses; picking
a preset while the equalizer is off turns it on and applies that preset.
Supersedes the earlier "no equalizer folder" rule (commit 2403da3),
which predated this feedback -- see decision auto/ecualizador-diseno.
The preset-cycling custom action still coexists with the folder in this
commit; it is removed in the next one.
This commit is contained in:
+2213
-2154
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,123 @@
|
||||
import 'dart:ui' show Locale;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:pluriwave/l10n/gen/app_localizations.dart';
|
||||
import 'package:pluriwave/modelos/preset_ecualizador.dart';
|
||||
import 'package:pluriwave/servicios/navegacion_auto.dart';
|
||||
import 'package:pluriwave/servicios/servicio_audio.dart';
|
||||
|
||||
/// Decision `auto/ecualizador-diseno` -- the "Ecualizador" browsable
|
||||
/// folder's item-building (`itemsEcualizadorAuto`), the pure,
|
||||
/// `AppLocalizations`-dependent half of the folder feature. Lives in a
|
||||
/// dedicated file, separate from `servicio_audio_eq_custom_actions_test.dart`
|
||||
/// (which covers the now-playing screen's on/off toggle) because this is a
|
||||
/// different car UI surface: a browsable folder, not a custom action.
|
||||
void main() {
|
||||
final l10n = lookupAppLocalizations(const Locale('es'));
|
||||
|
||||
group('itemsEcualizadorAuto (decision `auto/ecualizador-diseno`)', () {
|
||||
test('devuelve exactamente 7 items: Desactivar primero, luego los 6 '
|
||||
'presets de fábrica, todos playable', () {
|
||||
final items = itemsEcualizadorAuto(
|
||||
activo: true,
|
||||
presetActual: PresetEcualizador.flat,
|
||||
l10n: l10n,
|
||||
);
|
||||
|
||||
expect(items, hasLength(7));
|
||||
expect(items.first.id, ConstructorArbolAuto.idDesactivarEq);
|
||||
for (final item in items) {
|
||||
expect(item.playable, isTrue);
|
||||
}
|
||||
});
|
||||
|
||||
test('los 6 presets aparecen en el mismo orden que '
|
||||
'PresetEcualizador.presets, cada uno con su id eq_preset:<nombre>', () {
|
||||
final items = itemsEcualizadorAuto(
|
||||
activo: true,
|
||||
presetActual: PresetEcualizador.flat,
|
||||
l10n: l10n,
|
||||
);
|
||||
final builder = ConstructorArbolAuto();
|
||||
|
||||
final idsPresets = items.skip(1).map((i) => i.id).toList();
|
||||
final idsEsperados =
|
||||
PresetEcualizador.presets
|
||||
.map((p) => builder.idPresetEq(p.nombre))
|
||||
.toList();
|
||||
|
||||
expect(idsPresets, idsEsperados);
|
||||
});
|
||||
|
||||
test('los nombres de preset están localizados vía nombrePresetVisible, '
|
||||
'no crudos', () {
|
||||
final items = itemsEcualizadorAuto(
|
||||
activo: true,
|
||||
presetActual: PresetEcualizador.flat,
|
||||
l10n: l10n,
|
||||
);
|
||||
final builder = ConstructorArbolAuto();
|
||||
|
||||
final rock = items.firstWhere(
|
||||
(i) => i.id == builder.idPresetEq(PresetEcualizador.rock.nombre),
|
||||
);
|
||||
|
||||
expect(rock.title, contains(nombrePresetVisible(l10n, 'Rock')));
|
||||
});
|
||||
|
||||
test('con el ecualizador ACTIVO, el preset actual queda marcado y '
|
||||
'Desactivar NO', () {
|
||||
final items = itemsEcualizadorAuto(
|
||||
activo: true,
|
||||
presetActual: PresetEcualizador.jazz,
|
||||
l10n: l10n,
|
||||
);
|
||||
final builder = ConstructorArbolAuto();
|
||||
|
||||
final desactivar = items.firstWhere(
|
||||
(i) => i.id == ConstructorArbolAuto.idDesactivarEq,
|
||||
);
|
||||
final jazz = items.firstWhere(
|
||||
(i) => i.id == builder.idPresetEq(PresetEcualizador.jazz.nombre),
|
||||
);
|
||||
final marcados = items.where((i) => i.title.contains('✓')).toList();
|
||||
|
||||
expect(desactivar.title, isNot(contains('✓')));
|
||||
expect(jazz.title, contains('✓'));
|
||||
expect(marcados, hasLength(1));
|
||||
expect(marcados.single.id, jazz.id);
|
||||
});
|
||||
|
||||
test('con el ecualizador DESACTIVADO, Desactivar queda marcado y NINGÚN '
|
||||
'preset lo está', () {
|
||||
final items = itemsEcualizadorAuto(
|
||||
activo: false,
|
||||
presetActual: PresetEcualizador.rock,
|
||||
l10n: l10n,
|
||||
);
|
||||
|
||||
final desactivar = items.firstWhere(
|
||||
(i) => i.id == ConstructorArbolAuto.idDesactivarEq,
|
||||
);
|
||||
final marcados = items.where((i) => i.title.contains('✓')).toList();
|
||||
|
||||
expect(desactivar.title, contains('✓'));
|
||||
expect(marcados, hasLength(1));
|
||||
expect(marcados.single.id, ConstructorArbolAuto.idDesactivarEq);
|
||||
});
|
||||
|
||||
test('el label de Desactivar usa l10n.autoEqDisableOption', () {
|
||||
final items = itemsEcualizadorAuto(
|
||||
activo: false,
|
||||
presetActual: PresetEcualizador.flat,
|
||||
l10n: l10n,
|
||||
);
|
||||
|
||||
final desactivar = items.firstWhere(
|
||||
(i) => i.id == ConstructorArbolAuto.idDesactivarEq,
|
||||
);
|
||||
|
||||
expect(desactivar.title, contains(l10n.autoEqDisableOption));
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user