Fix: Cloud-Playlists lassen sich nicht löschen (DELETE statt POST)

deletePlaylist() schickte ein POST auf /api/v1/cloud/playlists. Der Server
unterscheidet dort nach Methode (POST = anlegen, DELETE = löschen), also
landete das Löschen im Anlegen-Handler, scheiterte an der leeren
Namensprüfung und lieferte HTTP 200 mit `status: error` zurück.

Zusätzlich wurde der Rückgabewert in cloud_screen.dart ignoriert: die UI
meldete "Playlist gelöscht", während die Playlist auf dem Server bestehen
blieb und beim nächsten Sync wieder auftauchte.

- cloud_service.dart: DELETE mit id im Body, Fehler werden geloggt
- cloud_screen.dart: Rückgabewert auswerten statt pauschal Erfolg melden
- cloud_service_test.dart: 3 Regressionstests (Methode ist DELETE, id im
  Body, status != ok → false, Netzwerkfehler → false)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hermes (Server)
2026-08-14 23:48:26 +02:00
co-authored by Claude Opus 5
parent 8f9ed1ff53
commit 22238138e8
3 changed files with 66 additions and 5 deletions
+7 -2
View File
@@ -816,9 +816,14 @@ class _CloudScreenState extends State<CloudScreen>
),
);
if (ok == true) {
await widget.cloud.deletePlaylist(id);
// Rückgabewert auswerten — sonst meldet die UI Erfolg, während die
// Playlist auf dem Server bleibt und beim nächsten Sync wieder auftaucht.
final geloescht = await widget.cloud.deletePlaylist(id);
await _ladePlaylists();
_setzeStatus('Playlist gelöscht', ok: true);
_setzeStatus(
geloescht ? 'Playlist gelöscht' : 'Löschen fehlgeschlagen',
ok: geloescht,
);
}
}
+20 -3
View File
@@ -199,10 +199,27 @@ class CloudService extends ChangeNotifier {
return r?['playlist'];
}
/// Playlist löschen
/// Playlist löschen.
///
/// Muss DELETE sein: der Server unterscheidet die Methode auf demselben Pfad
/// (POST = anlegen, DELETE = löschen). Ein POST landete früher im
/// Anlegen-Handler, scheiterte dort an der leeren Namensprüfung und lieferte
/// HTTP 200 mit `status: error` — die Playlist blieb unbemerkt bestehen.
Future<bool> deletePlaylist(int id) async {
final r = await _post('/api/v1/cloud/playlists', {'id': id});
return r?['status'] == 'ok';
try {
final r = await _client
.delete(Uri.parse('$_base/api/v1/cloud/playlists'),
headers: _jsonHeader, body: jsonEncode({'id': id}))
.timeout(const Duration(seconds: 10));
if (r.statusCode != 200) {
MeloLogger().fehler('cloud_playlist_delete', '${r.statusCode}');
return false;
}
return jsonDecode(r.body)['status'] == 'ok';
} catch (e) {
MeloLogger().fehler('cloud_playlist_delete_error', '$e');
return false;
}
}
/// Playlist-Details mit Songs abrufen