Gezielter Upload mit Abbrechen aus dem Auswahl-Modus
This commit is contained in:
@@ -485,4 +485,153 @@ void main() {
|
||||
expect(sync.fehler, contains('Anmeldung abgelaufen'));
|
||||
expect(sync.laeuft, isFalse);
|
||||
});
|
||||
|
||||
group('ladeAusgewaehlteHoch', () {
|
||||
Future<List<Song>> dreiTitel(Directory ordner, MeloDb db) async {
|
||||
for (var i = 0; i < 3; i++) {
|
||||
final datei = File('${ordner.path}/auswahl$i.mp3');
|
||||
await datei.writeAsBytes([i]);
|
||||
await db.upsertSongs([
|
||||
SongsCompanion.insert(
|
||||
id: 'lokal-$i',
|
||||
path: datei.path,
|
||||
title: 'Titel $i',
|
||||
dateAddedMs: i,
|
||||
updatedAtMs: 0,
|
||||
),
|
||||
]);
|
||||
}
|
||||
return db.allSongs();
|
||||
}
|
||||
|
||||
test('lädt nur, was noch keine cloudId hat', () async {
|
||||
final songs = await dreiTitel(tempDir, db);
|
||||
await db.setCloudId('lokal-1', 'schon-da');
|
||||
|
||||
var uploads = 0;
|
||||
final sync = await baue((anfrage) async {
|
||||
if (anfrage.url.path.endsWith('/upload')) {
|
||||
uploads++;
|
||||
return http.Response(
|
||||
jsonEncode({'status': 'ok', 'song_id': 'neu-$uploads'}), 200);
|
||||
}
|
||||
return http.Response(jsonEncode({'status': 'ok'}), 200);
|
||||
});
|
||||
|
||||
final ergebnis = await sync.ladeAusgewaehlteHoch(await db.allSongs());
|
||||
|
||||
expect(songs, hasLength(3));
|
||||
expect(uploads, 2);
|
||||
expect(ergebnis.hochgeladen, 2);
|
||||
expect(ergebnis.schonDa, 1);
|
||||
expect(ergebnis.fehler, isEmpty);
|
||||
});
|
||||
|
||||
test('ein abgelehnter Titel stoppt die übrigen nicht', () async {
|
||||
await dreiTitel(tempDir, db);
|
||||
|
||||
var uploads = 0;
|
||||
final sync = await baue((anfrage) async {
|
||||
if (anfrage.url.path.endsWith('/upload')) {
|
||||
uploads++;
|
||||
// Der Server meldet „zu groß" im Körper — dieselbe Wirkung wie eine
|
||||
// lokal abgelehnte 50-MB-Datei, ohne 50 MB schreiben zu müssen.
|
||||
if (uploads == 2) {
|
||||
return http.Response(
|
||||
jsonEncode({'error': 'Datei zu groß (max 50 MB)'}), 200);
|
||||
}
|
||||
return http.Response(
|
||||
jsonEncode({'status': 'ok', 'song_id': 'neu-$uploads'}), 200);
|
||||
}
|
||||
return http.Response(jsonEncode({'status': 'ok'}), 200);
|
||||
});
|
||||
|
||||
final ergebnis = await sync.ladeAusgewaehlteHoch(await db.allSongs());
|
||||
|
||||
expect(ergebnis.hochgeladen, 2);
|
||||
expect(ergebnis.fehler, hasLength(1));
|
||||
expect(ergebnis.fehler.single, contains('zu groß'));
|
||||
});
|
||||
|
||||
test('eine Zeitüberschreitung ist ein Einzelfehler, kein Laufabbruch',
|
||||
() async {
|
||||
await dreiTitel(tempDir, db);
|
||||
|
||||
var uploads = 0;
|
||||
final sync = await baue((anfrage) async {
|
||||
if (anfrage.url.path.endsWith('/upload')) {
|
||||
uploads++;
|
||||
if (uploads == 1) throw TimeoutException('zu lang');
|
||||
return http.Response(
|
||||
jsonEncode({'status': 'ok', 'song_id': 'neu-$uploads'}), 200);
|
||||
}
|
||||
return http.Response(jsonEncode({'status': 'ok'}), 200);
|
||||
});
|
||||
|
||||
final ergebnis = await sync.ladeAusgewaehlteHoch(await db.allSongs());
|
||||
|
||||
expect(ergebnis.hochgeladen, 2);
|
||||
expect(ergebnis.fehler, hasLength(1));
|
||||
});
|
||||
|
||||
test('abbrechen() stoppt zwischen zwei Titeln', () async {
|
||||
await dreiTitel(tempDir, db);
|
||||
|
||||
late SyncService sync;
|
||||
var uploads = 0;
|
||||
sync = await baue((anfrage) async {
|
||||
if (anfrage.url.path.endsWith('/upload')) {
|
||||
uploads++;
|
||||
sync.abbrechen();
|
||||
return http.Response(
|
||||
jsonEncode({'status': 'ok', 'song_id': 'neu-$uploads'}), 200);
|
||||
}
|
||||
return http.Response(jsonEncode({'status': 'ok'}), 200);
|
||||
});
|
||||
|
||||
final ergebnis = await sync.ladeAusgewaehlteHoch(await db.allSongs());
|
||||
|
||||
expect(uploads, 1);
|
||||
expect(ergebnis.abgebrochen, isTrue);
|
||||
expect(sync.laeuft, isFalse);
|
||||
});
|
||||
|
||||
test('schreibt den Sync-Zeitstempel nicht', () async {
|
||||
await dreiTitel(tempDir, db);
|
||||
|
||||
final sync = await baue((anfrage) async {
|
||||
if (anfrage.url.path.endsWith('/upload')) {
|
||||
return http.Response(
|
||||
jsonEncode({'status': 'ok', 'song_id': 'neu'}), 200);
|
||||
}
|
||||
return http.Response(jsonEncode({'status': 'ok'}), 200);
|
||||
});
|
||||
|
||||
await sync.ladeAusgewaehlteHoch(await db.allSongs());
|
||||
|
||||
// Ein Upload ist kein Abgleich: sonst unterdrückt er 15 Minuten den
|
||||
// Auto-Sync und verschiebt die 24-h-Uhr des Berichts.
|
||||
expect(sync.letzterLauf, isNull);
|
||||
});
|
||||
|
||||
test('während eines laufenden Abgleichs wird abgewiesen', () async {
|
||||
await dreiTitel(tempDir, db);
|
||||
|
||||
late SyncService sync;
|
||||
UploadErgebnis? waehrendSync;
|
||||
sync = await baue((anfrage) async {
|
||||
if (anfrage.url.path.endsWith('/list')) {
|
||||
waehrendSync = await sync.ladeAusgewaehlteHoch(await db.allSongs());
|
||||
return http.Response(jsonEncode({'songs': []}), 200);
|
||||
}
|
||||
return http.Response(jsonEncode({'status': 'ok'}), 200);
|
||||
});
|
||||
|
||||
await sync.synchronisiere();
|
||||
|
||||
expect(waehrendSync, isNotNull);
|
||||
expect(waehrendSync!.hochgeladen, 0);
|
||||
expect(sync.fehler, contains('Abgleich'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user