134 lines
4.8 KiB
Dart
134 lines
4.8 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:marianum_mobile/api/marianumconnect/queries/timetable_get_element_week/timetable_element_type.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_subjects/timetable_get_subjects_response.dart';
|
|
import 'package:marianum_mobile/api/mhsl/custom_timetable_event/get/get_custom_timetable_event_response.dart';
|
|
import 'package:marianum_mobile/state/app/modules/capabilities/bloc/capabilities_state.dart';
|
|
import 'package:marianum_mobile/state/app/modules/timetable/bloc/timetable_state.dart';
|
|
import 'package:marianum_mobile/state/app/modules/timetable/policy/timetable_policy.dart';
|
|
import 'package:marianum_mobile/state/app/modules/timetable/subject/timetable_subject.dart';
|
|
|
|
ElementTimetable _element(TimetableElementType type, [int id = 7]) =>
|
|
ElementTimetable((type: type, id: id, label: 'X'));
|
|
|
|
void main() {
|
|
group('TimetableSubject', () {
|
|
test('own plan keeps the legacy storage slot and persists', () {
|
|
const own = OwnTimetable();
|
|
expect(own.storageId, '');
|
|
expect(own.persistent, isTrue);
|
|
expect(own.supportsCustomEvents, isTrue);
|
|
});
|
|
|
|
test('element plans get distinct slots and do not persist', () {
|
|
final room = _element(TimetableElementType.room, 1);
|
|
final teacher = _element(TimetableElementType.teacher, 1);
|
|
expect(room.storageId, isNot(teacher.storageId));
|
|
expect(room.storageId, isNot(const OwnTimetable().storageId));
|
|
expect(room.persistent, isFalse);
|
|
expect(room.supportsCustomEvents, isFalse);
|
|
});
|
|
|
|
test('element equality ignores the display label', () {
|
|
final a = ElementTimetable((
|
|
type: TimetableElementType.room,
|
|
id: 3,
|
|
label: 'A',
|
|
));
|
|
final b = ElementTimetable((
|
|
type: TimetableElementType.room,
|
|
id: 3,
|
|
label: 'B',
|
|
));
|
|
expect(a, b);
|
|
expect(a.hashCode, b.hashCode);
|
|
expect(a, isNot(_element(TimetableElementType.schoolClass, 3)));
|
|
});
|
|
});
|
|
|
|
group('TimetablePolicy', () {
|
|
const student = CapabilitiesState(userType: 'STUDENT');
|
|
const teacher = CapabilitiesState(
|
|
userType: 'TEACHER',
|
|
viewForeignTimetables: true,
|
|
);
|
|
|
|
test('own plan offers custom events and subject colours', () {
|
|
final p = TimetablePolicy.resolve(
|
|
subject: const OwnTimetable(),
|
|
capabilities: student,
|
|
);
|
|
expect(p.canManageCustomEvents, isTrue);
|
|
expect(p.canEditSubjectColors, isTrue);
|
|
expect(p.canOpenForeign, isFalse);
|
|
expect(p.showClassInsteadOfTeacher, isFalse);
|
|
});
|
|
|
|
test('own teacher plan shows classes and may open foreign plans', () {
|
|
final p = TimetablePolicy.resolve(
|
|
subject: const OwnTimetable(),
|
|
capabilities: teacher,
|
|
);
|
|
expect(p.showClassInsteadOfTeacher, isTrue);
|
|
expect(p.canOpenForeign, isTrue);
|
|
});
|
|
|
|
test('foreign plans are read-only', () {
|
|
final p = TimetablePolicy.resolve(
|
|
subject: _element(TimetableElementType.room),
|
|
capabilities: teacher,
|
|
);
|
|
expect(p.canManageCustomEvents, isFalse);
|
|
expect(p.canEditSubjectColors, isFalse);
|
|
expect(p.canOpenForeign, isTrue);
|
|
expect(p.showClassInsteadOfTeacher, isFalse);
|
|
});
|
|
|
|
test('class labels follow the viewed element, not the viewer', () {
|
|
expect(
|
|
TimetablePolicy.resolve(
|
|
subject: _element(TimetableElementType.teacher),
|
|
capabilities: student,
|
|
).showClassInsteadOfTeacher,
|
|
isTrue,
|
|
);
|
|
expect(
|
|
TimetablePolicy.resolve(
|
|
subject: _element(TimetableElementType.student),
|
|
capabilities: teacher,
|
|
).showClassInsteadOfTeacher,
|
|
isFalse,
|
|
);
|
|
});
|
|
});
|
|
|
|
group('TimetableState.isReady', () {
|
|
final empty = TimetableState(
|
|
startDate: DateTime(2026, 9, 14),
|
|
endDate: DateTime(2026, 9, 18),
|
|
);
|
|
|
|
final withReference = empty.copyWith(
|
|
rooms: TimetableGetRoomsResponse(result: const []),
|
|
subjects: TimetableGetSubjectsResponse(result: const []),
|
|
schoolHolidays: TimetableGetHolidaysResponse(result: const []),
|
|
);
|
|
|
|
test('is false without reference data', () {
|
|
expect(empty.isReady(needsCustomEvents: false), isFalse);
|
|
});
|
|
|
|
test('only waits for custom events when the subject needs them', () {
|
|
expect(withReference.isReady(needsCustomEvents: false), isTrue);
|
|
expect(withReference.isReady(needsCustomEvents: true), isFalse);
|
|
expect(
|
|
withReference
|
|
.copyWith(customEvents: GetCustomTimetableEventResponse(const []))
|
|
.isReady(needsCustomEvents: true),
|
|
isTrue,
|
|
);
|
|
});
|
|
});
|
|
}
|