Fix school browser initialization and redirect detection; improve diagnostics
This commit is contained in:
@@ -33,6 +33,39 @@ class FakeFeedbackHttpTransport implements FeedbackHttpTransport {
|
||||
}
|
||||
|
||||
void main() {
|
||||
test(
|
||||
'old feedback service gets a specific diagnostic-upgrade hint',
|
||||
() async {
|
||||
final transport = FakeFeedbackHttpTransport()
|
||||
..response = FeedbackHttpResponse(
|
||||
422,
|
||||
utf8.encode(
|
||||
'{"error":"validation_error","detail":"Unexpected file field."}',
|
||||
),
|
||||
);
|
||||
await expectLater(
|
||||
HttpFeedbackSender(
|
||||
endpoint: 'https://example.com/v1/feedback',
|
||||
transport: transport,
|
||||
).send(
|
||||
FeedbackSubmission.problem(
|
||||
id: 'same-id',
|
||||
message: '问题',
|
||||
diagnosticLog: Uint8List.fromList(
|
||||
utf8.encode('TPSchedule diagnostic log\n'),
|
||||
),
|
||||
),
|
||||
),
|
||||
throwsA(
|
||||
isA<FeedbackException>().having(
|
||||
(e) => e.message,
|
||||
'upgrade hint',
|
||||
allOf(contains('日志'), contains('更新')),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
test('diagnostics use a separate UTF8 attachment field', () async {
|
||||
final transport = FakeFeedbackHttpTransport();
|
||||
await HttpFeedbackSender(
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
|
||||
import 'package:hepan_everyday/domain/school_term.dart';
|
||||
import 'package:hepan_everyday/features/school/school_browser.dart';
|
||||
import 'package:hepan_everyday/features/school/school_session.dart';
|
||||
import 'package:hepan_everyday/features/school/undergraduate/session.dart';
|
||||
import 'package:hepan_everyday/services/diagnostic_log.dart';
|
||||
|
||||
import '../support/fake_school_web.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
test('both school entries wait for browser compatibility settings before loading', () async {
|
||||
for (final undergraduate in [false, true]) {
|
||||
final platform = FakeSchoolPlatform();
|
||||
WebViewPlatform.instance = platform;
|
||||
final ready = Completer<SchoolBrowserInfo>();
|
||||
final graduate = SchoolSession(configureBrowser: (_, _) => ready.future);
|
||||
final under = UndergraduateSession(
|
||||
configureBrowser: (_, _) => ready.future,
|
||||
);
|
||||
addTearDown(graduate.dispose);
|
||||
addTearDown(under.dispose);
|
||||
final opening = undergraduate
|
||||
? under.openTimetable()
|
||||
: graduate.openTimetable(term: SchoolTerm(73));
|
||||
await flushSchoolEvents();
|
||||
expect(platform.web.loads, isEmpty);
|
||||
ready.complete(const SchoolBrowserInfo(chromiumVersion: '155.0.1.2'));
|
||||
await opening;
|
||||
expect(platform.web.loads, hasLength(1));
|
||||
expect(
|
||||
undergraduate ? under.browserVersion : graduate.browserVersion,
|
||||
'155.0.1.2',
|
||||
);
|
||||
}
|
||||
});
|
||||
test(
|
||||
'cancel while browser settings initialize never starts a late navigation',
|
||||
() async {
|
||||
final platform = FakeSchoolPlatform();
|
||||
WebViewPlatform.instance = platform;
|
||||
final ready = Completer<SchoolBrowserInfo>();
|
||||
final session = UndergraduateSession(
|
||||
configureBrowser: (_, _) => ready.future,
|
||||
);
|
||||
addTearDown(session.dispose);
|
||||
final opening = session.openTimetable();
|
||||
await flushSchoolEvents();
|
||||
session.setReadingActive(false);
|
||||
ready.complete(const SchoolBrowserInfo());
|
||||
await opening;
|
||||
expect(platform.web.loads, isEmpty);
|
||||
},
|
||||
);
|
||||
test('subresource failures remain diagnostic without aborting the school session', () async {
|
||||
final platform = FakeSchoolPlatform();
|
||||
WebViewPlatform.instance = platform;
|
||||
final session = UndergraduateSession();
|
||||
addTearDown(session.dispose);
|
||||
await session.openTimetable();
|
||||
platform.delegate.resourceError(
|
||||
WebResourceError(
|
||||
errorCode: -105,
|
||||
description: 'PRIVATE_COOKIE',
|
||||
isForMainFrame: false,
|
||||
url: 'http://eams.uestc.edu.cn/eams/scripts/component.js?ticket=PRIVATE_TICKET',
|
||||
),
|
||||
);
|
||||
await flushSchoolEvents();
|
||||
final log = utf8.decode(await DiagnosticLog.instance.export());
|
||||
expect(log, contains('school_resource_failed'));
|
||||
expect(log, contains('"page":"script"'));
|
||||
expect(log, contains('"status":-105'));
|
||||
expect(log, isNot(contains('PRIVATE_COOKIE')));
|
||||
expect(log, isNot(contains('PRIVATE_TICKET')));
|
||||
expect(session.message, isNot(contains('未完成')));
|
||||
});
|
||||
}
|
||||
@@ -31,6 +31,48 @@ void main() {
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user