Files
TPSchedule/mobile/test/school/undergraduate_exam_adapter_test.dart
T

116 lines
4.5 KiB
Dart

import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:hepan_everyday/features/school/undergraduate/exam_adapter.dart';
import 'package:hepan_everyday/data/exam_file_import.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';
void main() {
String fixture() =>
File('test/fixtures/school/undergraduate-exams.html').readAsStringSync();
final term = SchoolTerm(503, school: SupportedSchool.uestcUndergraduate);
test('unpublished room and seat merged by school keep the dated exam', () {
final page = fixture().replaceFirst(
RegExp(r'<td>示例考场</td>\s*<td>1</td>'),
'<td colspan="2">[考试情况尚未发布]</td>',
);
expect(page, contains('colspan="2"'));
final result = UndergraduateExamAdapter.extract(page);
expect(result.records, hasLength(4));
final record = result.records.first;
expect(record.date, '2026-06-22');
expect(record.time, contains('14:00-16:00'));
expect(record.room, '[考试情况尚未发布]');
expect(record.seat, '');
expect(record.status, '正常');
expect(record.examTypeId, 1);
});
test('unexpected merged exam columns remain a failed import', () {
final page = fixture().replaceFirst(
'<td>示例考场</td>',
'<td colspan="3">[考试情况尚未发布]</td>',
);
expect(() => UndergraduateExamAdapter.extract(page), throwsFormatException);
});
test('actual exam result term wins over the outer default', () {
final schedule = UndergraduateExamAdapter.extract(fixture());
expect(schedule.termId, '503');
expect(schedule.records, hasLength(4));
expect(schedule.requestedExamTypes, {1});
expect(schedule.records.first.date, '2026-06-22');
expect(schedule.records.first.time, contains('14:00-16:00'));
expect(ExamFileImport.parse(fixture()).termId, '503');
expect(ExamSchedule.fromJson(schedule.toJson()).records.first.status, '正常');
expect(
() => UndergraduateExamAdapter.extract(
fixture(),
expectedTerm: SchoolTerm(
523,
school: SupportedSchool.uestcUndergraduate,
),
),
throwsFormatException,
);
});
test(
'multi type merge preserves both exams for the same course and is complete',
() {
final finalExam = UndergraduateExamAdapter.extract(fixture());
final mid = UndergraduateExamAdapter.extract(
fixture()
.replaceAll('examType.id=1', 'examType.id=2')
.replaceAll(
'name="examType.id" value="1"',
'name="examType.id" value="2"',
)
.replaceAll('期末考试', '期中考试'),
);
final query = UndergraduateExamQuery(
term: term,
types: {UndergraduateExamType.finalExam, UndergraduateExamType.midterm},
);
expect(
UndergraduateExamAdapter.merge(query, [finalExam, mid]).records,
hasLength(8),
);
expect(
() => UndergraduateExamAdapter.merge(query, [finalExam]),
throwsFormatException,
);
expect(
() => UndergraduateExamAdapter.extract(
fixture(),
expectedType: UndergraduateExamType.midterm,
),
throwsFormatException,
);
},
);
test('only recognized explicit empty exam tables are empty success', () {
final empty =
'<form id="stdExamTableForm"><input name="semester.id" value="503"><input name="examType.id" value="1"></form><table><tr>${['课程序号', '课程名称', '考试日期', '考试安排', '考试地点', '座位号', '考试情况', '考试类型', '其它说明'].map((s) => '<td>$s</td>').join()}</tr><tr><td colspan="9">暂无考试安排</td></tr></table>';
expect(UndergraduateExamAdapter.extract(empty).records, isEmpty);
expect(
() => UndergraduateExamAdapter.extract(empty.replaceAll('暂无考试安排', '')),
throwsFormatException,
);
expect(
() => UndergraduateExamAdapter.extract('<html>登录</html>'),
throwsFormatException,
);
});
final original = Platform.environment['UESTC_UNDERGRADUATE_EXAM_FIXTURE'];
if (original != null) {
test('actual supplied exam export belongs to 503', () {
final result = UndergraduateExamAdapter.extract(
File(original).readAsStringSync(),
);
expect(result.records, hasLength(4));
expect(result.termId, '503');
});
}
}