Files
TPSchedule/mobile/test/domain/undergraduate_models_test.dart
T

169 lines
5.2 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:hepan_everyday/domain/school_identity.dart';
import 'package:hepan_everyday/domain/school_term.dart';
import 'package:hepan_everyday/domain/undergraduate_exam_query.dart';
import 'package:hepan_everyday/domain/exam_schedule.dart';
import 'package:hepan_everyday/domain/app_snapshot.dart';
import 'package:hepan_everyday/domain/course.dart';
void main() {
test(
'optional exam types reject invalid values even in graduate snapshots',
() {
final saved = ExamSchedule(
semesterLabel: '2026秋',
termId: '73',
records: [const ExamRecord(code: 'A', name: '课程', examTypeId: 99)],
).toJson();
expect(() => ExamSchedule.fromJson(saved), throwsFormatException);
},
);
test(
'managed undergraduate identifiers cannot lose their school or term',
() {
final c = Course(
id: 'uestc-undergraduate-523-managed',
name: '课程',
teacher: '教师',
room: '教室',
weekday: 1,
startPeriod: 1,
endPeriod: 2,
weeks: {1},
source: CourseSource.school,
);
final saved = AppSnapshot(
courses: [c],
schoolTerm: SchoolTerm(523, school: SupportedSchool.uestcUndergraduate),
).toJson();
expect(
() => AppSnapshot.fromJson({
...saved,
'schoolTerm': {'id': 73},
}),
throwsFormatException,
);
expect(
() => AppSnapshot.fromJson({...saved, 'schoolTerm': null}),
throwsFormatException,
);
},
);
SchoolTerm under(int id) =>
SchoolTerm(id, school: SupportedSchool.uestcUndergraduate);
test('undergraduate semester labels and final exam URLs', () {
expect([483, 503, 523, 543, 563].map((id) => under(id).label).toList(), [
'2025-2026第一学期',
'2025-2026第二学期',
'2026-2027第一学期',
'2026-2027第二学期',
'2027-2028第一学期',
]);
final query = UndergraduateExamQuery(
term: under(523),
types: {UndergraduateExamType.finalExam},
);
expect(
query.uriFor(UndergraduateExamType.finalExam).toString(),
'https://eams.uestc.edu.cn/eams/stdExamTable!examTable.action?semester.id=523&examType.id=1',
);
expect(
() => UndergraduateExamQuery(term: under(523), types: {}),
throwsArgumentError,
);
expect(() => under(504), throwsArgumentError);
expect(under(523), isNot(SchoolTerm(523)));
expect(() => under(523).examUri, throwsStateError);
expect(
SchoolTerm.fromJson({'id': 73}).school,
SupportedSchool.uestcGraduate,
);
expect(SchoolTerm.undergraduateChoices(DateTime(2026, 10)).first.id, 583);
});
test(
'undergraduate exam identity retains both types and rejects corruption',
() {
final schedule = ExamSchedule(
semesterLabel: under(523).label,
termId: '523',
school: SupportedSchool.uestcUndergraduate,
requestedExamTypes: {1, 2},
records: [
const ExamRecord(code: 'A', name: '课程', examTypeId: 1),
const ExamRecord(code: 'A', name: '课程', examTypeId: 2),
],
);
expect(ExamSchedule.fromJson(schedule.toJson()).records, hasLength(2));
expect(
() => ExamSchedule.fromJson({
...schedule.toJson(),
'requestedExamTypes': [],
}),
throwsFormatException,
);
expect(
() => ExamSchedule.fromJson({
...schedule.toJson(),
'schoolId': 'unknown',
}),
throwsFormatException,
);
final old = ExamSchedule(
semesterLabel: '2026秋',
termId: '73',
records: [
const ExamRecord(code: 'A', name: '课程'),
const ExamRecord(code: 'A', name: '课程'),
],
);
expect(() => ExamSchedule.fromJson(old.toJson()), throwsFormatException);
},
);
test(
'snapshots persist school selection and validate period twelve source',
() {
final course = Course(
id: 'under-523-test',
name: '课程',
teacher: '教师',
room: '教室',
weekday: 1,
startPeriod: 9,
endPeriod: 12,
weeks: {1},
source: CourseSource.school,
courseCode: 'A',
notes: '备注',
);
final saved = AppSnapshot(
selectedSchool: SupportedSchool.uestcUndergraduate,
schoolTerm: under(523),
courses: [course],
);
final round = AppSnapshot.fromJson(saved.toJson());
expect(round.selectedSchool, SupportedSchool.uestcUndergraduate);
expect(round.courses.single.notes, '备注');
expect(
() => AppSnapshot.fromJson({
...saved.toJson(),
'schoolTerm': {'id': 73},
}),
throwsFormatException,
);
expect(
() => AppSnapshot.fromJson({
...saved.toJson(),
'selectedSchoolId': 'unknown',
}),
throwsFormatException,
);
final legacy = AppSnapshot(schoolTerm: SchoolTerm(73)).toJson()
..remove('selectedSchoolId');
expect(
AppSnapshot.fromJson(legacy).selectedSchool,
SupportedSchool.uestcGraduate,
);
},
);
}