implemented RMV public transit module including trip search, station departures, and nearby stop lookup, added "Marianum Connect" API integration with bearer token authentication and auto-refresh logic, integrated geolocator for location-based station search, added persistent storage for favorite stations and recent trip queries, and implemented comprehensive UI for journey details, trip results, and disruption alerts

This commit is contained in:
2026-05-20 19:08:05 +02:00
parent f185b3273a
commit 067012cc84
61 changed files with 7885 additions and 1 deletions
+57
View File
@@ -0,0 +1,57 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:marianum_mobile/api/connect/rmv/iso_duration.dart';
void main() {
group('IsoDuration.fromJson', () {
test('null and empty return null', () {
expect(IsoDuration.fromJson(null), isNull);
expect(IsoDuration.fromJson(''), isNull);
});
test('hours-minutes-seconds parse correctly', () {
expect(
IsoDuration.fromJson('PT1H30M15S'),
const Duration(hours: 1, minutes: 30, seconds: 15),
);
});
test('hours only', () {
expect(IsoDuration.fromJson('PT2H'), const Duration(hours: 2));
});
test('minutes only', () {
expect(IsoDuration.fromJson('PT45M'), const Duration(minutes: 45));
});
test('seconds with fraction', () {
expect(
IsoDuration.fromJson('PT30.5S'),
const Duration(milliseconds: 30500),
);
});
test('invalid string returns null', () {
expect(IsoDuration.fromJson('not a duration'), isNull);
});
});
group('IsoDuration.toJson', () {
test('null returns null', () => expect(IsoDuration.toJson(null), isNull));
test('zero duration formats as PT0S', () {
expect(IsoDuration.toJson(Duration.zero), 'PT0S');
});
test('hours and minutes only formats without seconds', () {
expect(
IsoDuration.toJson(const Duration(hours: 1, minutes: 30)),
'PT1H30M',
);
});
test('full duration roundtrips through parse', () {
const original = Duration(hours: 2, minutes: 15, seconds: 7);
expect(IsoDuration.fromJson(IsoDuration.toJson(original)), original);
});
});
}
@@ -0,0 +1,26 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:marianum_mobile/api/connect/errors/rmv_upstream_exception.dart';
void main() {
group('RmvUpstreamException', () {
test('H390 maps to no-connection message', () {
final e = RmvUpstreamException(errorCode: 'H390');
expect(e.userMessage, contains('Keine Verbindung'));
});
test('H891 maps to invalid-station message', () {
final e = RmvUpstreamException(errorCode: 'H891');
expect(e.userMessage, contains('ungültig'));
});
test('unknown code falls through to a generic but specific message', () {
final e = RmvUpstreamException(errorCode: 'HXYZ');
expect(e.userMessage, contains('HXYZ'));
});
test('null code yields the generic upstream message', () {
final e = RmvUpstreamException(errorCode: null);
expect(e.userMessage, contains('keine Antwort'));
});
});
}