mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-18 15:52:30 +02:00
feat(metadata): add safe batch editing and matching
This commit is contained in:
@@ -51,6 +51,62 @@ void main() {
|
||||
expect(fields, const ['isrc']);
|
||||
});
|
||||
|
||||
test('manual mode only exposes shared-value fields', () {
|
||||
expect(manualBatchMetadataFields, containsAll(['album_name', 'genre']));
|
||||
expect(manualBatchMetadataFields, isNot(contains('track_name')));
|
||||
expect(manualBatchMetadataFields, isNot(contains('track_number')));
|
||||
expect(manualBatchMetadataFields, isNot(contains('isrc')));
|
||||
});
|
||||
|
||||
test('manual values build a per-track review without an online lookup', () {
|
||||
final selection = const ReEnrichFieldSelection(
|
||||
mode: ReEnrichBatchMode.manualValues,
|
||||
manualValues: {'album_name': ' New Album ', 'genre': 'Rock'},
|
||||
);
|
||||
|
||||
expect(selection.updateFieldsFor(_item()), ['album_name', 'genre']);
|
||||
final preview = buildManualBatchReEnrichPreview(_item(), selection);
|
||||
|
||||
expect(preview, isNotNull);
|
||||
expect(preview!.enrichedMetadata['album_name'], 'New Album');
|
||||
expect(preview.changes.map((change) => change.field), [
|
||||
'album_name',
|
||||
'genre',
|
||||
]);
|
||||
|
||||
final request = buildBatchReEnrichRequest(
|
||||
item: preview.item,
|
||||
settings: const AppSettings(),
|
||||
updateFields: preview.updateFields,
|
||||
resolvedMetadata: preview.enrichedMetadata,
|
||||
);
|
||||
expect(request['search_online'], isFalse);
|
||||
expect(request['album_name'], 'New Album');
|
||||
expect(request['genre'], 'Rock');
|
||||
});
|
||||
|
||||
test('manual preview omits unchanged and empty values', () {
|
||||
final preview = buildManualBatchReEnrichPreview(
|
||||
_item(genre: 'Rock'),
|
||||
const ReEnrichFieldSelection(
|
||||
mode: ReEnrichBatchMode.manualValues,
|
||||
manualValues: {'album_name': 'Album', 'genre': 'Rock', 'label': ' '},
|
||||
),
|
||||
);
|
||||
|
||||
expect(preview, isNull);
|
||||
});
|
||||
|
||||
test('manual mode rejects unsafe per-track identifiers', () {
|
||||
final selection = const ReEnrichFieldSelection(
|
||||
mode: ReEnrichBatchMode.manualValues,
|
||||
manualValues: {'isrc': 'USAAA2600001', 'track_name': 'Same title'},
|
||||
);
|
||||
|
||||
expect(selection.updateFieldsFor(_item()), isEmpty);
|
||||
expect(buildManualBatchReEnrichPreview(_item(), selection), isNull);
|
||||
});
|
||||
|
||||
test('resolved preview metadata is reused without another online search', () {
|
||||
final request = buildBatchReEnrichRequest(
|
||||
item: _item(),
|
||||
|
||||
@@ -165,6 +165,21 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('missing lyrics filter', () {
|
||||
test(
|
||||
'requires a completed lyrics scan before treating false as missing',
|
||||
() {
|
||||
final predicate = confirmedMissingLyricsSqlPredicate(
|
||||
hasLyricsExpr: 'item.has_lyrics',
|
||||
lyricsKnownExpr: 'item.lyrics_scan_version >= 1',
|
||||
);
|
||||
|
||||
expect(predicate, contains('item.lyrics_scan_version >= 1'));
|
||||
expect(predicate, contains('COALESCE(item.has_lyrics, 0) = 0'));
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
group('app state database migrations', () {
|
||||
final source = File(
|
||||
'lib/services/app_state_database.dart',
|
||||
|
||||
Reference in New Issue
Block a user