68 lines
2.6 KiB
Dart
68 lines
2.6 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:hepan_everyday/features/school/school_page_adapter.dart';
|
|
import 'package:hepan_everyday/features/school/school_navigation_policy.dart';
|
|
import 'package:hepan_everyday/data/schedule_file_import.dart';
|
|
import 'package:hepan_everyday/domain/course.dart';
|
|
|
|
import 'recognized_timetable_test.dart' show fixture;
|
|
|
|
void main() {
|
|
final target = Uri.parse(
|
|
'https://yjsjy.uestc.edu.cn/pyxx/pygl/xskbcx/index/1',
|
|
);
|
|
test('in-flight read cannot authorize a different origin', () async {
|
|
final reader = SchoolReader(SchoolPageAdapter()),
|
|
body = Completer<String>();
|
|
final valid = reader.read(target, () => body.future);
|
|
final rejected = reader.read(
|
|
Uri.parse('https://evil.example/pyxx/pygl/xskbcx/index/1'),
|
|
() async => fixture(),
|
|
);
|
|
body.complete(fixture());
|
|
await expectLater(rejected, throwsA(isA<UnsupportedSchoolLayout>()));
|
|
await valid;
|
|
});
|
|
test('invalidated read cannot become a fresh authenticated draft', () async {
|
|
final reader = SchoolReader(SchoolPageAdapter()),
|
|
body = Completer<String>();
|
|
final stale = reader.read(target, () => body.future);
|
|
final check = expectLater(stale, throwsA(isA<UnsupportedSchoolLayout>()));
|
|
reader.invalidate();
|
|
final fresh = await reader.read(target, () async => fixture());
|
|
body.complete(fixture());
|
|
await check;
|
|
expect(fresh.courses.length, 4);
|
|
expect(reader.busy, isFalse);
|
|
});
|
|
test('official numeric semester routes are allowed but alternate endpoints are not', () {
|
|
expect(
|
|
SchoolNavigationPolicy.isTimetable(
|
|
Uri.parse('https://yjsjy.uestc.edu.cn/pyxx/pygl/xskbcx/index/73'),
|
|
),
|
|
isTrue,
|
|
);
|
|
for (final url in [
|
|
'http://yjsjy.uestc.edu.cn/pyxx/pygl/xskbcx/index/1',
|
|
'https://user@yjsjy.uestc.edu.cn/pyxx/pygl/xskbcx/index/1',
|
|
'https://yjsjy.uestc.edu.cn:444/pyxx/pygl/xskbcx/index/1',
|
|
'https://yjsjy.uestc.edu.cn/pyxx/pygl/xskbcx/index/73/other',
|
|
'https://yjsjy.uestc.edu.cn/pyxx/pygl/xskbcx/index/73evil',
|
|
]) {
|
|
expect(SchoolNavigationPolicy.isTimetable(Uri.parse(url)), isFalse);
|
|
}
|
|
});
|
|
test('BOM saved HTML file imports without claiming live authentication', () {
|
|
final draft = ScheduleFileImport.parse('\uFEFF${fixture()}');
|
|
expect(draft.courses.length, 4);
|
|
expect(draft.semesterLabel, '2026-2027秋');
|
|
expect(draft.source, CourseSource.file);
|
|
expect(draft.courses.every((c) => c.source == CourseSource.file), isTrue);
|
|
expect(
|
|
() => ScheduleFileImport.parse('<html>登录</html>'),
|
|
throwsA(isA<UnsupportedSchoolLayout>()),
|
|
);
|
|
});
|
|
}
|