113 lines
4.0 KiB
Dart
113 lines
4.0 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:timezone/data/latest.dart' as tzdata;
|
|
import 'package:hepan_everyday/app/app_controller.dart';
|
|
import 'package:hepan_everyday/domain/app_snapshot.dart';
|
|
import 'package:hepan_everyday/domain/app_settings.dart';
|
|
import 'package:hepan_everyday/domain/semester.dart';
|
|
import 'package:hepan_everyday/domain/school_identity.dart';
|
|
import 'package:hepan_everyday/domain/school_term.dart';
|
|
import 'package:hepan_everyday/domain/exam_schedule.dart';
|
|
import 'package:hepan_everyday/data/json_schedule_import.dart';
|
|
|
|
import '../domain/schedule_engine_test.dart' show course;
|
|
import '../support/fakes.dart';
|
|
|
|
void main() {
|
|
setUpAll(tzdata.initializeTimeZones);
|
|
late MemoryStore store;
|
|
late FakeNotifications notifications;
|
|
late FakeCalendar calendar;
|
|
late AppController controller;
|
|
setUp(() {
|
|
store = MemoryStore(
|
|
AppSnapshot(
|
|
courses: [course()],
|
|
schoolTerm: SchoolTerm(73),
|
|
settings: AppSettings(
|
|
semester: Semester(startDate: DateTime(2026, 9, 7), totalWeeks: 20),
|
|
),
|
|
),
|
|
);
|
|
notifications = FakeNotifications();
|
|
calendar = FakeCalendar();
|
|
controller = AppController(
|
|
store,
|
|
notifications,
|
|
calendar,
|
|
() => DateTime.utc(2026, 9, 8),
|
|
);
|
|
});
|
|
tearDown(() => controller.dispose());
|
|
ExamSchedule exams() => ExamSchedule(
|
|
semesterLabel: '2025-2026第二学期',
|
|
termId: '503',
|
|
records: [],
|
|
school: SupportedSchool.uestcUndergraduate,
|
|
requestedExamTypes: {1},
|
|
);
|
|
test(
|
|
'historical undergraduate exams preserve courses and services',
|
|
() async {
|
|
await controller.initialize();
|
|
final before = controller.snapshot;
|
|
final count = notifications.reconciliations;
|
|
await controller.applyExams(exams());
|
|
expect(controller.lastError, isNull);
|
|
expect(controller.snapshot.courses, before.courses);
|
|
expect(controller.snapshot.schoolTerm, before.schoolTerm);
|
|
expect(controller.snapshot.settings.semester, before.settings.semester);
|
|
expect(notifications.reconciliations, count);
|
|
expect(controller.snapshot.examSchedule!.termId, '503');
|
|
},
|
|
);
|
|
test('school selection and failed exam writes are atomic', () async {
|
|
await controller.initialize();
|
|
store.failSave = true;
|
|
final old = controller.snapshot.toJson();
|
|
expect(
|
|
await controller.selectSchool(SupportedSchool.uestcUndergraduate),
|
|
isFalse,
|
|
);
|
|
expect(controller.snapshot.toJson(), old);
|
|
await controller.applyExams(exams());
|
|
expect(controller.snapshot.toJson(), old);
|
|
store.failSave = false;
|
|
expect(
|
|
await controller.selectSchool(SupportedSchool.uestcUndergraduate),
|
|
isTrue,
|
|
);
|
|
expect(store.value!.selectedSchool, SupportedSchool.uestcUndergraduate);
|
|
});
|
|
test('undergraduate course changes preserve independent exams and reset only new term dates', () async {
|
|
await controller.initialize();
|
|
await controller.applyExams(exams());
|
|
final term = SchoolTerm(523, school: SupportedSchool.uestcUndergraduate);
|
|
final draft = ImportDraft(
|
|
courses: [course()],
|
|
explicitlyEmpty: false,
|
|
source: course().source,
|
|
parserVersion: 'test',
|
|
schoolTerm: term,
|
|
);
|
|
await controller.applyImport(draft, confirmedEmpty: false);
|
|
expect(controller.snapshot.settings.semester, isNull);
|
|
expect(controller.snapshot.examSchedule!.termId, '503');
|
|
await controller.updateSettings(
|
|
(s) => s.copyWith(
|
|
semester: Semester(startDate: DateTime(2026, 9, 7), totalWeeks: 20),
|
|
),
|
|
);
|
|
final date = controller.snapshot.settings.semester;
|
|
await controller.applyImport(draft, confirmedEmpty: false);
|
|
expect(controller.snapshot.settings.semester, date);
|
|
});
|
|
test('JSON period twelve needs an explicit undergraduate term', () {
|
|
final old = course().toJson()..['endPeriod'] = 12;
|
|
final json =
|
|
'{"schemaVersion":1,"courses":[${const JsonEncoder().convert(old)}]}';
|
|
expect(() => JsonScheduleImport.parse(json), throwsFormatException);
|
|
});
|
|
}
|