import 'package:flutter_test/flutter_test.dart'; import 'package:melo/services/navidrome_service.dart'; /// Tests für die Subsonic-Antwort-Auswertung. Kern des Bugfixes: /// Navidrome liefert bei Fehlern (z. B. falsches Passwort) HTTP 200 mit /// {"subsonic-response":{"status":"failed","error":{...}}}. Diese Antworten /// dürfen NICHT stillschweigend als „leer" behandelt werden. void main() { group('NavidromeService.parseSubsonic', () { test('status:failed wirft NavidromeException mit Server-Meldung', () { const body = '{"subsonic-response":{"status":"failed","version":"1.16.1",' '"error":{"code":40,"message":"Wrong username or password"}}}'; expect( () => NavidromeService.parseSubsonic(body), throwsA(isA() .having((e) => e.message, 'message', 'Wrong username or password') .having((e) => e.code, 'code', 40)), ); }); test('status:ok liefert den subsonic-response-Block zurück', () { const body = '{"subsonic-response":{"status":"ok","version":"1.16.1",' '"albumList2":{"album":[]}}}'; final resp = NavidromeService.parseSubsonic(body); expect(resp['status'], 'ok'); expect(resp['albumList2'], isNotNull); }); test('fehlender subsonic-response wirft NavidromeException', () { expect(() => NavidromeService.parseSubsonic('{"foo":1}'), throwsA(isA())); }); }); group('NavidromeService.parseAlben (ID3 / getAlbumList2)', () { test('liest albumList2.album korrekt', () { const body = '{"subsonic-response":{"status":"ok","albumList2":{"album":[' '{"id":"a1","name":"Erstes Album","coverArt":"c1","songCount":9},' '{"id":"a2","title":"Zweites","songCount":3}' ']}}}'; final resp = NavidromeService.parseSubsonic(body); final alben = NavidromeService.parseAlben(resp); expect(alben.length, 2); expect(alben[0].id, 'a1'); expect(alben[0].name, 'Erstes Album'); expect(alben[0].songCount, 9); expect(alben[1].name, 'Zweites'); }); test('leere albumList2 liefert leere Liste (kein Fehler)', () { final resp = NavidromeService.parseSubsonic( '{"subsonic-response":{"status":"ok","albumList2":{}}}'); expect(NavidromeService.parseAlben(resp), isEmpty); }); }); }