168 lines
5.7 KiB
Dart
168 lines
5.7 KiB
Dart
import 'dart:io';
|
|
import 'dart:convert';
|
|
import 'dart:async';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
|
|
import 'package:hepan_everyday/features/school/undergraduate/session.dart';
|
|
import 'package:hepan_everyday/features/school/undergraduate/page_probe.dart';
|
|
|
|
import '../support/fake_school_web.dart';
|
|
|
|
String underEvidence(
|
|
String url, {
|
|
bool authenticated = true,
|
|
String? html,
|
|
String kind = 'timetable',
|
|
}) => jsonEncode({
|
|
'topUrl': url,
|
|
'authenticated': authenticated,
|
|
'pages': [
|
|
if (html != null) {'kind': kind, 'url': url, 'html': html},
|
|
],
|
|
});
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
late FakeSchoolPlatform platform;
|
|
late UndergraduateSession session;
|
|
setUp(() {
|
|
platform = FakeSchoolPlatform();
|
|
WebViewPlatform.instance = platform;
|
|
session = UndergraduateSession();
|
|
});
|
|
tearDown(() => session.dispose());
|
|
test(
|
|
'page-finished during an old probe is retried on the redirected portal',
|
|
() async {
|
|
await session.openTimetable();
|
|
var first = true;
|
|
platform.web.javascript = (_) async {
|
|
if (first) {
|
|
first = false;
|
|
platform.web.url = 'https://eams.uestc.edu.cn/eams/home.action';
|
|
platform.delegate.finished(platform.web.url!);
|
|
}
|
|
return underEvidence(platform.web.url!);
|
|
};
|
|
platform.delegate.finished(platform.web.url!);
|
|
await flushSchoolEvents();
|
|
await Future<void>.delayed(const Duration(milliseconds: 600));
|
|
await flushSchoolEvents();
|
|
expect(session.statusLabel, '已连接');
|
|
expect(session.busy, isFalse);
|
|
},
|
|
);
|
|
test('a redirect between page callback and probe does not permanently stop login detection', () async {
|
|
await session.openTimetable();
|
|
var redirect = true;
|
|
platform.web.javascript = (_) async {
|
|
if (redirect) {
|
|
redirect = false;
|
|
platform.web.url = 'https://idas.uestc.edu.cn/authserver/login';
|
|
return underEvidence(platform.web.url!, authenticated: false);
|
|
}
|
|
return underEvidence(platform.web.url!);
|
|
};
|
|
platform.delegate.finished(platform.web.url!);
|
|
await flushSchoolEvents();
|
|
expect(session.message, isNot(contains('未完成')));
|
|
platform.delegate.finished(platform.web.url!);
|
|
await flushSchoolEvents();
|
|
platform.web.url = 'https://eams.uestc.edu.cn/eams/';
|
|
platform.delegate.finished(platform.web.url!);
|
|
await flushSchoolEvents();
|
|
expect(session.statusLabel, '已连接');
|
|
});
|
|
test(
|
|
'activating a loading browser never probes the previous blank document',
|
|
() async {
|
|
await session.openTimetable();
|
|
var probes = 0;
|
|
platform.web.javascript = (_) async {
|
|
probes++;
|
|
return underEvidence('about:blank', authenticated: false);
|
|
};
|
|
session.setReadingActive(true);
|
|
await flushSchoolEvents();
|
|
expect(probes, 0);
|
|
platform.web.javascript = (_) async => underEvidence(platform.web.url!);
|
|
platform.delegate.started(platform.web.url!);
|
|
platform.delegate.finished(platform.web.url!);
|
|
await flushSchoolEvents();
|
|
expect(session.busy, isFalse);
|
|
expect(session.message, UndergraduateSession.manualMessage);
|
|
},
|
|
);
|
|
test(
|
|
'manual session is lazy and never captures until the student taps import',
|
|
() async {
|
|
expect(platform.controllerCreations, 0);
|
|
await session.openTimetable();
|
|
expect(platform.web.loads, ['https://eams.uestc.edu.cn/eams/']);
|
|
final content = File('test/fixtures/school/undergraduate-timetable.html')
|
|
.readAsStringSync();
|
|
var captures = 0;
|
|
platform.web.javascript = (s) async {
|
|
if (s == undergraduateCaptureScript) {
|
|
captures++;
|
|
return underEvidence(platform.web.url!, html: content);
|
|
}
|
|
return underEvidence(platform.web.url!);
|
|
};
|
|
platform.delegate.finished(platform.web.url!);
|
|
await flushSchoolEvents();
|
|
expect(captures, 0);
|
|
expect(session.pendingDraft, isNull);
|
|
await session.readCurrentTimetable();
|
|
expect(captures, 1);
|
|
expect(session.pendingDraft!.courses, hasLength(18));
|
|
},
|
|
);
|
|
test('closed routes reject old asynchronous capture and save', () async {
|
|
await session.openTimetable();
|
|
final gate = Completer<Object>();
|
|
platform.web.javascript = (_) => gate.future;
|
|
final read = session.readCurrentTimetable();
|
|
await flushSchoolEvents();
|
|
final generation = session.pageGeneration;
|
|
session.setReadingActive(false);
|
|
gate.complete(
|
|
underEvidence(
|
|
platform.web.url!,
|
|
html: File('test/fixtures/school/undergraduate-timetable.html')
|
|
.readAsStringSync(),
|
|
),
|
|
);
|
|
await read;
|
|
expect(session.pendingDraft, isNull);
|
|
expect(session.saved(generation: generation), isFalse);
|
|
});
|
|
test(
|
|
'unused logout stays lazy and failed cookie clearing can be retried',
|
|
() async {
|
|
await session.logout();
|
|
expect(platform.controllerCreations, 0);
|
|
await session.openTimetable();
|
|
platform.cookies.fail = true;
|
|
await session.logout();
|
|
expect(session.canLogout, isTrue);
|
|
platform.cookies.fail = false;
|
|
await session.logout();
|
|
expect(session.canLogout, isFalse);
|
|
},
|
|
);
|
|
test('new login waits for an outstanding cookie clear', () async {
|
|
await session.openTimetable();
|
|
platform.cookies.clearing = Completer<bool>();
|
|
final closing = session.logout();
|
|
await flushSchoolEvents();
|
|
final reopening = session.openTimetable();
|
|
await flushSchoolEvents();
|
|
platform.cookies.clearing!.complete(true);
|
|
await closing;
|
|
await reopening;
|
|
expect(session.hasOpened, isTrue);
|
|
expect(platform.web.loads.last, 'https://eams.uestc.edu.cn/eams/');
|
|
});
|
|
}
|