Files
Client/test/demo/demo_marianumconnect_test.dart
T
MineTecandClaude Opus 5.5 c5592f117b added automated App Store screenshots via iOS simulators and fastlane deliver
tool/screenshots_ios.sh runs the existing demo-login integration test on
iPhone 6.5" (iPhone 14 Plus) and iPad 13" simulators, stores the canonical PNGs
under materials/screenshots and mirrors alpha-free JPEGs to
ios/fastlane/screenshots for `fastlane upload_screenshots`.

Fixed the demo router answering timetable/custom-events with a week, which
crashed the inline iOS widget refresh after a demo login. The screenshot test
now skips the one-time Talk notification dialog and waits longer for the app
shell on cold simulators.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 16:58:29 +02:00

96 lines
4.0 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:marianum_mobile/api/demo/demo_marianumconnect.dart';
import 'package:marianum_mobile/api/marianumconnect/models/mc_holiday.dart';
import 'package:marianum_mobile/api/marianumconnect/queries/get_breakers/get_breakers_response.dart';
import 'package:marianum_mobile/api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.dart';
import 'package:marianum_mobile/api/marianumconnect/queries/timetable_get_rooms/timetable_get_rooms_response.dart';
import 'package:marianum_mobile/api/marianumconnect/queries/timetable_get_schoolyear/timetable_get_schoolyear_response.dart';
import 'package:marianum_mobile/api/marianumconnect/queries/timetable_get_subjects/timetable_get_subjects_response.dart';
import 'package:marianum_mobile/api/marianumconnect/queries/timetable_get_timegrid/timetable_get_timegrid_response.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/get/get_custom_timetable_event_response.dart';
/// The demo interceptor answers MarianumConnect calls with these bodies; each
/// must round-trip through the same parser the real query uses. A shape
/// mismatch (bare list vs. object) would only surface at runtime otherwise.
void main() {
Map<String, dynamic> asMap(String path, [Map<String, dynamic> query = const {}]) =>
DemoMarianumConnect.responseBody(path, query) as Map<String, dynamic>;
List<Map<String, dynamic>> asList(String path) =>
(DemoMarianumConnect.responseBody(path, const {}) as List)
.cast<Map<String, dynamic>>();
group('DemoMarianumConnect responseBody parses with the real query parser', () {
test('timetable/me → populated week', () {
final week = TimetableGetWeekResponse.fromJson(
asMap('timetable/me', {'from': '2026-05-04', 'until': '2026-05-10'}),
);
expect(week.entries, isNotEmpty);
});
test('timetable/schoolyear', () {
expect(
() => TimetableGetSchoolyearResponse.fromJson(asMap('timetable/schoolyear')),
returnsNormally,
);
});
test('timetable/rooms → non-empty list of McRoom', () {
final rooms = asList('timetable/rooms').map(McRoom.fromJson).toList();
expect(rooms, isNotEmpty);
});
test('timetable/subjects → non-empty list of McSubject', () {
final subjects = asList('timetable/subjects').map(McSubject.fromJson).toList();
expect(subjects, isNotEmpty);
});
test('timetable/timegrid → non-empty list of McTimegridUnit', () {
final units = asList('timetable/timegrid').map(McTimegridUnit.fromJson).toList();
expect(units, isNotEmpty);
});
test('timetable/holidays → list of McHoliday', () {
expect(
() => asList('timetable/holidays').map(McHoliday.fromJson).toList(),
returnsNormally,
);
});
// Eigener Case nötig: sonst greift der timetable/<type>/<id>-Fallback und
// liefert eine Woche statt `{events: [...]}` (iOS-Widget-Refresh crashte).
test('timetable/custom-events', () {
expect(
() => GetCustomTimetableEventResponse.fromJson(
asMap('timetable/custom-events'),
),
returnsNormally,
);
});
test('holidays → non-empty list of McHoliday', () {
final holidays = asList('holidays').map(McHoliday.fromJson).toList();
expect(holidays, isNotEmpty);
});
test('breaker → GetBreakersResponse with no active rules', () {
final breakers = GetBreakersResponse.fromJson(asMap('breaker'));
expect(breakers.rules, isEmpty);
});
test('foreign element week (timetable/<type>/<id>) parses as a week', () {
expect(
() => TimetableGetWeekResponse.fromJson(
asMap('timetable/teacher/42', {'from': '2026-05-04', 'until': '2026-05-10'}),
),
returnsNormally,
);
});
test('side-effect endpoint returns an empty map body', () {
expect(asMap('me/telemetry'), isEmpty);
});
});
}