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( 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(); }); }