feat(auto): real metadata, quality sort and name buckets for local music [size:exception]
Local tracks now show embedded title/artist/album art (via native MediaMetadataRetriever, cached through the existing FileProvider) instead of the raw filename, falling back gracefully when a file has no usable tags. Adds two navigable entry points per folder: sort by audio quality (bitrate, capped at 150 tracks per folder to bound worst-case latency) and alphabetical name buckets -- the closest realistic form of "filtering" given Android Auto has no text-search UI in this integration. Metadata resolves only for the page actually being browsed (same slice-cheap-then-map discipline as the paging change), backed by a flat 256-entry LRU session cache that survives across pages. No new permission, no new pub dependency, no l10n changes (car-tree labels stay hardcoded Spanish, matching every existing label in the tree).
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:pluriwave/modelos/pista_local.dart';
|
||||
|
||||
void main() {
|
||||
group('MetadatosPista', () {
|
||||
test('todos los campos null: no lanza, todos los getters devuelven null', () {
|
||||
const metadatos = MetadatosPista(
|
||||
titulo: null,
|
||||
artista: null,
|
||||
artUri: null,
|
||||
bitrate: null,
|
||||
sampleRate: null,
|
||||
);
|
||||
|
||||
expect(metadatos.titulo, isNull);
|
||||
expect(metadatos.artista, isNull);
|
||||
expect(metadatos.artUri, isNull);
|
||||
expect(metadatos.bitrate, isNull);
|
||||
expect(metadatos.sampleRate, isNull);
|
||||
});
|
||||
|
||||
test('const constructor sin argumentos (todos por defecto null)', () {
|
||||
const metadatos = MetadatosPista();
|
||||
|
||||
expect(metadatos.titulo, isNull);
|
||||
expect(metadatos.artista, isNull);
|
||||
expect(metadatos.artUri, isNull);
|
||||
expect(metadatos.bitrate, isNull);
|
||||
expect(metadatos.sampleRate, isNull);
|
||||
});
|
||||
|
||||
test('todos los campos poblados se preservan tal cual', () {
|
||||
const metadatos = MetadatosPista(
|
||||
titulo: 'Cancion Genial',
|
||||
artista: 'Artista X',
|
||||
artUri: 'content://es.freetimelab.pluriwave.fileprovider/cache/pluriwave_art/abc',
|
||||
bitrate: 320000,
|
||||
sampleRate: 44100,
|
||||
);
|
||||
|
||||
expect(metadatos.titulo, 'Cancion Genial');
|
||||
expect(metadatos.artista, 'Artista X');
|
||||
expect(
|
||||
metadatos.artUri,
|
||||
'content://es.freetimelab.pluriwave.fileprovider/cache/pluriwave_art/abc',
|
||||
);
|
||||
expect(metadatos.bitrate, 320000);
|
||||
expect(metadatos.sampleRate, 44100);
|
||||
});
|
||||
});
|
||||
|
||||
group('PistaLocal', () {
|
||||
test('campos extendidos (artista/embeddedArtUri/bitrate/sampleRate) son '
|
||||
'opcionales y por defecto null', () {
|
||||
const pista = PistaLocal(
|
||||
documentId: 'doc1',
|
||||
titulo: 'Titulo',
|
||||
contentUri: 'content://provider/doc1',
|
||||
);
|
||||
|
||||
expect(pista.artista, isNull);
|
||||
expect(pista.embeddedArtUri, isNull);
|
||||
expect(pista.bitrate, isNull);
|
||||
expect(pista.sampleRate, isNull);
|
||||
});
|
||||
|
||||
test('campos extendidos se preservan cuando se proveen', () {
|
||||
const pista = PistaLocal(
|
||||
documentId: 'doc1',
|
||||
titulo: 'Titulo',
|
||||
contentUri: 'content://provider/doc1',
|
||||
artista: 'Artista X',
|
||||
embeddedArtUri:
|
||||
'content://es.freetimelab.pluriwave.fileprovider/cache/pluriwave_art/abc',
|
||||
bitrate: 320000,
|
||||
sampleRate: 44100,
|
||||
);
|
||||
|
||||
expect(pista.artista, 'Artista X');
|
||||
expect(
|
||||
pista.embeddedArtUri,
|
||||
'content://es.freetimelab.pluriwave.fileprovider/cache/pluriwave_art/abc',
|
||||
);
|
||||
expect(pista.bitrate, 320000);
|
||||
expect(pista.sampleRate, 44100);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user