migrated timetable integration from WebUntis to the MarianumConnect API, implementing a Dio-based client with bearer token authentication, background session validation, and auto-refresh logic.

This commit is contained in:
2026-05-23 17:32:42 +02:00
parent 2858f910c9
commit 93b9929f8f
106 changed files with 2739 additions and 2624 deletions
+24 -21
View File
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:marianum_mobile/api/marianumconnect/queries/timetable_get_week/timetable_get_week_response.dart';
import 'package:marianum_mobile/api/mhsl/custom_timetable_event/custom_timetable_event.dart';
import 'package:marianum_mobile/api/webuntis/queries/get_timetable/get_timetable_response.dart';
import 'package:marianum_mobile/view/pages/timetable/data/arbitrary_appointment.dart';
import 'package:marianum_mobile/view/pages/timetable/data/calendar_logic.dart';
import 'package:marianum_mobile/view/pages/timetable/data/lesson_period_schedule.dart';
@@ -27,18 +27,21 @@ Appointment _appt({
recurrenceRule: rrule,
);
GetTimetableResponseObject _lesson({String? code}) =>
GetTimetableResponseObject(
id: 0,
date: 0,
startTime: 0,
endTime: 0,
kl: const [],
te: const [],
su: const [],
ro: const [],
code: code,
);
McTimetableEntry _lesson({String status = 'REGULAR'}) => McTimetableEntry(
id: 0,
date: DateTime(2026, 5, 8),
startTime: DateTime(1970, 1, 1, 8),
endTime: DateTime(1970, 1, 1, 9),
subjects: const [],
teachers: const [],
rooms: const [],
classNames: const [],
lessonType: 'LESSON',
status: status,
substitutionText: null,
lessonText: null,
infoText: null,
);
CustomTimetableEvent _customEvent() => CustomTimetableEvent(
id: 'x',
@@ -331,7 +334,7 @@ void main() {
end: _at(2026, 5, 8, 10),
);
final regular = _appt(
id: WebuntisAppointment(_lesson()),
id: LessonAppointment(_lesson()),
start: _at(2026, 5, 8, 8),
end: _at(2026, 5, 8, 10),
);
@@ -345,19 +348,19 @@ void main() {
(c) => c.appointment.id is CustomAppointment,
);
final regularCell = result.firstWhere(
(c) => c.appointment.id is WebuntisAppointment,
(c) => c.appointment.id is LessonAppointment,
);
expect(customCell.lane, lessThan(regularCell.lane));
});
test('cancelled lesson lands left of a non-cancelled one on tie', () {
final cancelled = _appt(
id: WebuntisAppointment(_lesson(code: 'cancelled')),
id: LessonAppointment(_lesson(status: 'CANCELLED')),
start: _at(2026, 5, 8, 8),
end: _at(2026, 5, 8, 10),
);
final regular = _appt(
id: WebuntisAppointment(_lesson()),
id: LessonAppointment(_lesson()),
start: _at(2026, 5, 8, 8),
end: _at(2026, 5, 8, 10),
);
@@ -366,13 +369,13 @@ void main() {
regular,
cancelled,
], maxLanes: 2).whereType<LaidOutAppointment>().toList();
String? codeOf(LaidOutAppointment c) {
String? statusOf(LaidOutAppointment c) {
final id = c.appointment.id;
return id is WebuntisAppointment ? id.lesson.code : null;
return id is LessonAppointment ? id.entry.status : null;
}
final cancelledCell = result.firstWhere((c) => codeOf(c) == 'cancelled');
final regularCell = result.firstWhere((c) => codeOf(c) == null);
final cancelledCell = result.firstWhere((c) => statusOf(c) == 'CANCELLED');
final regularCell = result.firstWhere((c) => statusOf(c) == 'REGULAR');
expect(cancelledCell.lane, lessThan(regularCell.lane));
});