120 lines
4.3 KiB
Dart
120 lines
4.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:hepan_everyday/app/app_controller.dart';
|
|
import 'package:hepan_everyday/domain/app_snapshot.dart';
|
|
import 'package:hepan_everyday/domain/school_term.dart';
|
|
import 'package:hepan_everyday/features/school/school_auth_page.dart';
|
|
import 'package:hepan_everyday/features/school/school_session.dart';
|
|
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
|
|
|
|
import '../support/fake_school_web.dart';
|
|
import '../support/fakes.dart';
|
|
|
|
// Native WebView rendering is unavailable to widget tests. All session and
|
|
// authentication logic still uses the real controller through the platform.
|
|
class _WidgetSchoolPlatform extends FakeSchoolPlatform {
|
|
@override
|
|
PlatformWebViewWidget createPlatformWebViewWidget(
|
|
PlatformWebViewWidgetCreationParams params,
|
|
) => _WebSurface(params);
|
|
}
|
|
|
|
class _WebSurface extends PlatformWebViewWidget {
|
|
_WebSurface(super.params) : super.implementation();
|
|
@override
|
|
Widget build(BuildContext context) => const SizedBox.expand();
|
|
}
|
|
|
|
void main() {
|
|
testWidgets(
|
|
'picker waits for school login and selected row only imports on confirmation',
|
|
(tester) async {
|
|
final platform = _WidgetSchoolPlatform();
|
|
WebViewPlatform.instance = platform;
|
|
final session = SchoolSession();
|
|
final controller = AppController(
|
|
MemoryStore(),
|
|
FakeNotifications(),
|
|
FakeCalendar(),
|
|
() => DateTime(2026, 10, 13),
|
|
);
|
|
await controller.initialize();
|
|
await session.openExams();
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: SchoolAuthPage(session: session, controller: controller),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('选择学校学期'), findsNothing);
|
|
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 tester.pumpAndSettle();
|
|
expect(find.text('选择学校学期'), findsOneWidget);
|
|
await tester.tap(find.text('2025-2026年春'));
|
|
await tester.pump();
|
|
expect(platform.web.loads.length, 1);
|
|
expect(controller.snapshot.schoolTerm, isNull);
|
|
await tester.tap(find.text('导入所选学期'));
|
|
await tester.pump();
|
|
expect(
|
|
platform.web.loads.last,
|
|
'https://yjsjy.uestc.edu.cn/pyxx/pygl/kskcxx/index?xq=72',
|
|
);
|
|
expect(controller.snapshot.schoolTerm, isNull);
|
|
await tester.pumpWidget(const SizedBox());
|
|
session.dispose();
|
|
controller.dispose();
|
|
},
|
|
);
|
|
|
|
testWidgets('canceling a connected term change leaves saved term intact', (
|
|
tester,
|
|
) async {
|
|
final platform = _WidgetSchoolPlatform();
|
|
WebViewPlatform.instance = platform;
|
|
final session = SchoolSession();
|
|
final controller = AppController(
|
|
MemoryStore(AppSnapshot(schoolTerm: SchoolTerm(72))),
|
|
FakeNotifications(),
|
|
FakeCalendar(),
|
|
() => DateTime(2026, 10, 13),
|
|
);
|
|
await controller.initialize();
|
|
session.connectionState = SchoolConnectionState.connected;
|
|
await session.openTimetable(term: SchoolTerm(72), chooseTerm: true);
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Builder(
|
|
builder: (context) => TextButton(
|
|
onPressed: () => Navigator.of(context).push(
|
|
MaterialPageRoute<void>(
|
|
builder: (_) =>
|
|
SchoolAuthPage(session: session, controller: controller),
|
|
),
|
|
),
|
|
child: const Text('打开学校'),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.tap(find.text('打开学校'));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('选择学校学期'), findsOneWidget);
|
|
await tester.tap(find.text('2026-2027年秋'));
|
|
await tester.tap(find.text('取消'));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('选择学校学期'), findsNothing);
|
|
expect(platform.web.loads, isEmpty);
|
|
expect(session.selectedTerm, SchoolTerm(72));
|
|
expect(controller.snapshot.schoolTerm, SchoolTerm(72));
|
|
await tester.pumpWidget(const SizedBox());
|
|
session.dispose();
|
|
controller.dispose();
|
|
});
|
|
}
|