import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:hepan_everyday/features/school/school_exam_adapter.dart'; import 'package:hepan_everyday/domain/app_snapshot.dart'; String examHtml({String time = '', String room = '', String seat = ''}) => ''' ${['id', '序号', '学号', '姓名', '课程代码', '课程名称', '考核方式', '考生编号', '考场顺序号', '考场', '座位号', '考试时间'].map((s) => '').join()} ${['1', '1', 'private-id', 'private-name', 'MATH', '矩阵理论', '笔试', '', '', room, seat, time].map((s) => '').join()}
$s
$s
'''; void main() { test( 'unscheduled courses and supplied arrangement fields survive saving', () { final draft = SchoolExamAdapter.extract(examHtml()); expect(draft.records.single.name, '矩阵理论'); expect(draft.records.single.time, ''); final arranged = SchoolExamAdapter.extract( examHtml(time: '2026-12-01 09:00–11:00', room: '品学楼A101', seat: '16'), ); final saved = AppSnapshot.fromJson( AppSnapshot(examSchedule: arranged).toJson(), ); expect(saved.examSchedule!.records.single.room, '品学楼A101'); expect(saved.examSchedule!.records.single.seat, '16'); expect(saved.examSchedule!.records.single.time, '2026-12-01 09:00–11:00'); final text = saved.toJson().toString(); expect(text, isNot(contains('private-id'))); expect(text, isNot(contains('private-name'))); }, ); test('partial exam pages cannot replace previously imported records', () { final headerOnly = examHtml().replaceAll( RegExp(r'.*?', dotAll: true), '', ); expect(() => SchoolExamAdapter.extract(headerOnly), throwsFormatException); expect( () => SchoolExamAdapter.extract(examHtml().replaceFirst('16', '')), returnsNormally, ); expect( () => SchoolExamAdapter.extract( examHtml().replaceFirst('MATH', ''), ), throwsFormatException, ); expect( () => SchoolExamAdapter.extract('登录'), throwsFormatException, ); }); final actual = Platform.environment['RSCHEDULE_EXAM_FIXTURE']; if (actual != null) { test( 'provided exam export has eight courses with no arrangements', () async { final draft = SchoolExamAdapter.extract( await File(actual).readAsString(), ); expect(draft.records.length, 8); expect(draft.semesterLabel, '2026-2027秋'); expect( draft.records.every( (e) => e.time.isEmpty && e.room.isEmpty && e.seat.isEmpty, ), isTrue, ); }, ); } }