import 'package:drift/drift.dart'; import 'package:drift/native.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:melo/library/database.dart'; void main() { late MeloDb db; setUp(() => db = MeloDb(NativeDatabase.memory())); tearDown(() => db.close()); SongsCompanion song(String id, String path, String title, {String? artist}) => SongsCompanion.insert( id: id, path: path, title: title, artist: Value(artist), dateAddedMs: 1, updatedAtMs: 1, ); test('upsert + watchSongs sortiert nach Titel', () async { await db.upsertSongs([song('1', '/a.mp3', 'Beta'), song('2', '/b.mp3', 'Alpha')]); final songs = await db.watchSongs().first; expect(songs.map((s) => s.title), ['Alpha', 'Beta']); }); test('Re-upsert gleicher id erzeugt kein Duplikat, aktualisiert', () async { await db.upsertSongs([song('1', '/a.mp3', 'Alt')]); await db.upsertSongs([song('1', '/a.mp3', 'Neu')]); final songs = await db.watchSongs().first; expect(songs.length, 1); expect(songs.first.title, 'Neu'); }); test('searchSongs findet über Titel und Künstler', () async { await db.upsertSongs([ song('1', '/a.mp3', 'Nachtpuls', artist: 'Rotklang'), song('2', '/b.mp3', 'Taglicht', artist: 'Beatzwei'), ]); expect((await db.searchSongs('nacht').first).length, 1); expect((await db.searchSongs('rotklang').first).length, 1); expect((await db.searchSongs('xyz').first).length, 0); }); test('markMissing setzt Tombstone für nicht aktualisierte Dateien', () async { final now1 = 100; final now2 = 200; // Initialer Scan: zwei Songs await db.upsertSongs([ SongsCompanion.insert(id: '1', path: '/a.mp3', title: 'A', dateAddedMs: now1, updatedAtMs: now1), SongsCompanion.insert(id: '2', path: '/b.mp3', title: 'B', dateAddedMs: now1, updatedAtMs: now1), ]); // Zweiter Scan: nur /a.mp3 gefunden await db.upsertSongs([ SongsCompanion.insert(id: '1', path: '/a.mp3', title: 'A', dateAddedMs: now1, updatedAtMs: now2), ]); await db.markMissing(now2); // Songs mit updatedAtMs < now2 löschen final songs = await db.watchSongs().first; expect(songs.map((s) => s.path), ['/a.mp3']); }); test('scan_test.dart: CRITICAL-1 — empty scan deletes nothing (in scan_test.dart)', () { // Diese Regression ist in scan_test.dart mit echtem scanFolders() getestet. // Hier nur ein Placeholder um die alte Test-Nummer zu behalten. }); test('scan_test.dart: CRITICAL-2 — rescan restores deleted songs (in scan_test.dart)', () { // Diese Regression ist in scan_test.dart mit echtem scanFolders() getestet. // Hier nur ein Placeholder um die alte Test-Nummer zu behalten. }); }