185 lines
7.1 KiB
Dart
185 lines
7.1 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
|
|
import 'package:hepan_everyday/features/school/school_session.dart';
|
|
import 'package:hepan_everyday/features/school/school_page_probe.dart';
|
|
import 'package:hepan_everyday/domain/school_term.dart';
|
|
|
|
import 'dart:convert';
|
|
|
|
import '../support/fake_school_web.dart';
|
|
import 'recognized_timetable_test.dart' show fixture;
|
|
import 'exam_adapter_test.dart' show examHtml;
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
test(
|
|
'first online import waits for an explicit term even on a ready table',
|
|
() async {
|
|
final platform = FakeSchoolPlatform();
|
|
WebViewPlatform.instance = platform;
|
|
final session = SchoolSession();
|
|
addTearDown(session.dispose);
|
|
await session.open();
|
|
const url = 'https://yjsjy.uestc.edu.cn/pyxx/pygl/xskbcx/index/73';
|
|
platform.web.url = url;
|
|
platform.web.javascript = (_) async =>
|
|
schoolPageEvidence(topUrl: url, authenticated: true, html: fixture());
|
|
platform.delegate.started(url);
|
|
platform.delegate.finished(url);
|
|
await flushSchoolEvents();
|
|
expect(session.pendingDraft, isNull);
|
|
expect(session.finding, isFalse);
|
|
expect(session.needsTermSelection, isTrue);
|
|
},
|
|
);
|
|
|
|
test('signed out change waits for authentication then explicit choice before requesting exams', () async {
|
|
final platform = FakeSchoolPlatform();
|
|
WebViewPlatform.instance = platform;
|
|
final session = SchoolSession();
|
|
addTearDown(session.dispose);
|
|
await session.openExams(term: SchoolTerm(73), chooseTerm: true);
|
|
expect(session.needsTermSelection, isFalse);
|
|
expect(
|
|
platform.web.loads.single,
|
|
'https://yjsjy.uestc.edu.cn/pyxx/jzsso/login',
|
|
);
|
|
const home = 'https://yjsjy.uestc.edu.cn/pyxx/home/index';
|
|
platform.web.url = home;
|
|
platform.web.javascript = (_) async =>
|
|
schoolPageEvidence(topUrl: platform.web.url!, authenticated: true);
|
|
platform.delegate.started(home);
|
|
platform.delegate.finished(home);
|
|
await flushSchoolEvents();
|
|
expect(session.needsTermSelection, isTrue);
|
|
expect(platform.web.loads.length, 1);
|
|
await session.selectTerm(SchoolTerm(72));
|
|
expect(
|
|
platform.web.loads.last,
|
|
'https://yjsjy.uestc.edu.cn/pyxx/pygl/kskcxx/index?xq=72',
|
|
);
|
|
expect(session.needsTermSelection, isFalse);
|
|
});
|
|
|
|
test('connected change prompts immediately without replacing imported data or navigating', () async {
|
|
final platform = FakeSchoolPlatform();
|
|
WebViewPlatform.instance = platform;
|
|
final session = SchoolSession();
|
|
addTearDown(session.dispose);
|
|
// A previously authenticated session has already opened its browser.
|
|
final connectedBrowser = session.web;
|
|
session.connectionState = SchoolConnectionState.connected;
|
|
await session.openTimetable(term: SchoolTerm(72), chooseTerm: true);
|
|
expect(session.needsTermSelection, isTrue);
|
|
expect(session.web, same(connectedBrowser));
|
|
expect(platform.web.loads, isEmpty);
|
|
expect(session.selectedTerm, SchoolTerm(72));
|
|
expect(session.pendingDraft, isNull);
|
|
expect(session.termChoices.first.id, 73);
|
|
expect(session.termChoices.last.id, 1);
|
|
await session.selectTerm(SchoolTerm(71));
|
|
expect(
|
|
platform.web.loads.single,
|
|
'https://yjsjy.uestc.edu.cn/pyxx/pygl/xskbcx/index/71',
|
|
);
|
|
});
|
|
|
|
test('timetable selected DOM term must match request before an import can become pending', () async {
|
|
final platform = FakeSchoolPlatform();
|
|
WebViewPlatform.instance = platform;
|
|
final session = SchoolSession();
|
|
addTearDown(session.dispose);
|
|
session.connectionState = SchoolConnectionState.connected;
|
|
await session.openTimetable(term: SchoolTerm(72));
|
|
platform.web.javascript = (_) async =>
|
|
schoolPageEvidence(topUrl: platform.web.url!, html: fixture());
|
|
platform.delegate.started(platform.web.url!);
|
|
platform.delegate.finished(platform.web.url!);
|
|
await flushSchoolEvents();
|
|
expect(session.pendingDraft, isNull);
|
|
platform.web.javascript = (_) async => schoolPageEvidence(
|
|
topUrl: platform.web.url!,
|
|
html: fixture().replaceFirst('value="73"', 'value="72"'),
|
|
);
|
|
await session.readCurrentPage();
|
|
expect(session.pendingDraft?.schoolTerm, SchoolTerm(72));
|
|
});
|
|
|
|
test(
|
|
'exam selected DOM term must match requested query before saving',
|
|
() async {
|
|
final platform = FakeSchoolPlatform();
|
|
WebViewPlatform.instance = platform;
|
|
final session = SchoolSession();
|
|
addTearDown(session.dispose);
|
|
session.connectionState = SchoolConnectionState.connected;
|
|
await session.openExams(term: SchoolTerm(72));
|
|
platform.web.javascript = (_) async => schoolPageEvidence(
|
|
topUrl: platform.web.url!,
|
|
html: examHtml(),
|
|
kind: 'exams',
|
|
);
|
|
platform.delegate.started(platform.web.url!);
|
|
platform.delegate.finished(platform.web.url!);
|
|
await flushSchoolEvents();
|
|
expect(session.pendingExams, isNull);
|
|
platform.web.javascript = (_) async => schoolPageEvidence(
|
|
topUrl: platform.web.url!,
|
|
html: examHtml().replaceFirst('value="73"', 'value="72"'),
|
|
kind: 'exams',
|
|
);
|
|
await session.readCurrentPage();
|
|
expect(session.pendingExams?.termId, '72');
|
|
},
|
|
);
|
|
|
|
test(
|
|
're-authentication retains chosen term and unfinished picker intent',
|
|
() async {
|
|
final platform = FakeSchoolPlatform();
|
|
WebViewPlatform.instance = platform;
|
|
final session = SchoolSession();
|
|
addTearDown(session.dispose);
|
|
session.connectionState = SchoolConnectionState.connected;
|
|
await session.openExams(term: SchoolTerm(72), chooseTerm: true);
|
|
await session.openAuthentication();
|
|
expect(session.needsTermSelection, isFalse);
|
|
expect(session.selectedTerm, SchoolTerm(72));
|
|
const home = 'https://yjsjy.uestc.edu.cn/pyxx/home/index';
|
|
platform.web.url = home;
|
|
platform.web.javascript = (_) async =>
|
|
schoolPageEvidence(topUrl: home, authenticated: true);
|
|
platform.delegate.started(home);
|
|
platform.delegate.finished(home);
|
|
await flushSchoolEvents();
|
|
expect(session.needsTermSelection, isTrue);
|
|
await session.selectTerm(SchoolTerm(71));
|
|
await session.openAuthentication();
|
|
expect(session.selectedTerm, SchoolTerm(71));
|
|
expect(session.needsTermSelection, isFalse);
|
|
platform.web.url = home;
|
|
platform.delegate.started(home);
|
|
platform.delegate.finished(home);
|
|
await flushSchoolEvents();
|
|
expect(
|
|
platform.web.loads.last,
|
|
'https://yjsjy.uestc.edu.cn/pyxx/pygl/kskcxx/index?xq=71',
|
|
);
|
|
},
|
|
);
|
|
|
|
test('live dropdown choices are validated, deduplicated and sorted without private fields', () {
|
|
final uri = Uri.parse('https://yjsjy.uestc.edu.cn/pyxx/home/index');
|
|
final evidence = SchoolPageEvidence.decode(
|
|
jsonEncode({
|
|
'topUrl': uri.toString(),
|
|
'authenticated': true,
|
|
'pages': [],
|
|
'terms': [72, 73, 72, 0, -1, 10000, 'private-value'],
|
|
}),
|
|
uri,
|
|
);
|
|
expect(evidence.terms.map((term) => term.id), [73, 72]);
|
|
});
|
|
}
|