Reklamationen der Fahrer: Meldungen verdeckten Buttons, und nach dem Abschluss stand „Lieferung nicht in der Tour gefunden" ohne Ausweg da. Meldungen: - Erfolgs-SnackBars entfernt, bei Erfolg bleibt der Spinner - einheitliche, schwebende Meldungen statt Stau über den Buttons - Server-Rohtexte durch verständliche Texte ersetzt (api_failure_text) Laden: - fehlt eine geöffnete Lieferung, wird die Tour einmal neu geholt; die Meldung kommt nur nach erfolgreichem Abruf ohne die Lieferung - Endlos-Spinner auf Lieferdetail, Filial-Abholung und Beladen ersetzt durch Kopfzeile, Fehlergrund und „Erneut versuchen" - Tour wird nach einem Tageswechsel nachgeladen, offene Seiten bleiben dabei unberührt - Abschluss und Zuweisung überschreiben kein zwischenzeitliches Neuladen, alte Antworten drehen einen Abschluss nicht mehr zurück - leere Server-Antworten gelten als Fehler statt als „keine Daten" Anmeldung: - Token-Erneuerung wartet höchstens 12 s, der native Aufruf läuft weiter - App-Start ohne Netz zeigt einen Hinweis mit „Erneut versuchen" - Fehlerseite der Fahrzeugauswahl bietet „Abmelden" Außerdem Podfile.lock an die Plugins angeglichen. Tests für die neuen Fehlerpfade ergänzt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
92 lines
2.7 KiB
Dart
92 lines
2.7 KiB
Dart
import 'package:dio/dio.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import 'package:hl_lieferservice/data/network/api_failure_text.dart';
|
|
|
|
DioException _fehler(int? status, [String? serverText]) {
|
|
final options = RequestOptions(path: '/x');
|
|
return DioException(
|
|
requestOptions: options,
|
|
response: status == null
|
|
? null
|
|
: Response(
|
|
requestOptions: options,
|
|
statusCode: status,
|
|
data: serverText == null ? null : {'message': serverText},
|
|
),
|
|
);
|
|
}
|
|
|
|
void main() {
|
|
const bekannt = {'existiert bereits': 'Dieses Kennzeichen ist bereits vergeben'};
|
|
|
|
test('bekannter Server-Text wird übersetzt, ohne Rohtext', () {
|
|
final text = describeApiFailure(
|
|
_fehler(400, "validation: kennzeichen 'test' existiert bereits"),
|
|
operation: 'Anlegen eines Fahrzeugs',
|
|
byServerText: bekannt,
|
|
);
|
|
expect(text, 'Dieses Kennzeichen ist bereits vergeben');
|
|
});
|
|
|
|
test('unbekannter Server-Text erreicht den Fahrer nicht', () {
|
|
final text = describeApiFailure(
|
|
_fehler(400, 'validation: numericValue 12 above max 10'),
|
|
operation: 'Service setzen',
|
|
byServerText: bekannt,
|
|
);
|
|
expect(text, 'Service setzen fehlgeschlagen. Bitte erneut versuchen');
|
|
});
|
|
|
|
test('Serverfehler nennt keinen HTTP-Code', () {
|
|
final text = describeApiFailure(_fehler(500), operation: 'Notiz anlegen');
|
|
expect(text, 'Notiz anlegen fehlgeschlagen. Bitte erneut versuchen');
|
|
});
|
|
|
|
test('Statuscodes der Fachseite und Sitzungsende', () {
|
|
expect(
|
|
describeApiFailure(
|
|
_fehler(404),
|
|
operation: 'x',
|
|
byStatus: const {404: 'Fahrzeug nicht gefunden'},
|
|
),
|
|
'Fahrzeug nicht gefunden',
|
|
);
|
|
expect(describeApiFailure(_fehler(401), operation: 'x'), 'Sitzung abgelaufen');
|
|
});
|
|
|
|
test('ohne Antwort: Hinweis auf die Verbindung', () {
|
|
expect(
|
|
describeApiFailure(_fehler(null), operation: 'x'),
|
|
'Server nicht erreichbar. Bitte Verbindung prüfen',
|
|
);
|
|
});
|
|
|
|
test('Timeouts und Abbrüche werden unterschieden', () {
|
|
DioException ohneAntwort(DioExceptionType type) => DioException(
|
|
requestOptions: RequestOptions(path: '/x'),
|
|
type: type,
|
|
);
|
|
|
|
for (final type in const [
|
|
DioExceptionType.connectionTimeout,
|
|
DioExceptionType.sendTimeout,
|
|
DioExceptionType.receiveTimeout,
|
|
]) {
|
|
expect(
|
|
describeApiFailure(ohneAntwort(type), operation: 'x'),
|
|
'Der Server antwortet nicht. Bitte Verbindung prüfen',
|
|
);
|
|
}
|
|
for (final type in const [
|
|
DioExceptionType.connectionError,
|
|
DioExceptionType.unknown,
|
|
]) {
|
|
expect(
|
|
describeApiFailure(ohneAntwort(type), operation: 'x'),
|
|
'Server nicht erreichbar. Bitte Verbindung prüfen',
|
|
);
|
|
}
|
|
});
|
|
}
|