feat: deliver RSchedule service login exams and elastic glass navigation
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
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 = ''}) =>
|
||||
'''
|
||||
<select id="xqbh"><option value="73" selected>2026-2027秋</option></select>
|
||||
<table id="sample-table-1"><thead><tr>
|
||||
${['id', '序号', '学号', '姓名', '课程代码', '课程名称', '考核方式', '考生编号', '考场顺序号', '考场', '座位号', '考试时间'].map((s) => '<th>$s</th>').join()}
|
||||
</tr></thead><tbody><tr>
|
||||
${['1', '1', 'private-id', 'private-name', 'MATH', '矩阵理论', '笔试', '', '', room, seat, time].map((s) => '<td>$s</td>').join()}
|
||||
</tr></tbody></table>''';
|
||||
|
||||
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'<tbody>.*?</tbody>', dotAll: true),
|
||||
'<tbody></tbody>',
|
||||
);
|
||||
expect(() => SchoolExamAdapter.extract(headerOnly), throwsFormatException);
|
||||
expect(
|
||||
() =>
|
||||
SchoolExamAdapter.extract(examHtml().replaceFirst('<td>16</td>', '')),
|
||||
returnsNormally,
|
||||
);
|
||||
expect(
|
||||
() => SchoolExamAdapter.extract(
|
||||
examHtml().replaceFirst('<td>MATH</td>', ''),
|
||||
),
|
||||
throwsFormatException,
|
||||
);
|
||||
expect(
|
||||
() => SchoolExamAdapter.extract('<html>登录</html>'),
|
||||
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,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user