210 lines
7.5 KiB
Dart
210 lines
7.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:timezone/data/latest.dart' as tzdata;
|
|
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
|
|
import 'package:hepan_everyday/app/hepan_app.dart';
|
|
import 'package:hepan_everyday/app/app_controller.dart';
|
|
import 'package:hepan_everyday/domain/app_snapshot.dart';
|
|
import 'package:hepan_everyday/domain/school_identity.dart';
|
|
import 'package:hepan_everyday/domain/exam_schedule.dart';
|
|
import 'package:hepan_everyday/domain/undergraduate_exam_query.dart';
|
|
import 'package:hepan_everyday/features/school/school_session.dart';
|
|
import 'package:hepan_everyday/features/school/undergraduate/session.dart';
|
|
|
|
import '../support/fakes.dart';
|
|
import '../support/fake_school_web.dart';
|
|
|
|
void main() {
|
|
setUpAll(tzdata.initializeTimeZones);
|
|
testWidgets(
|
|
'undergraduate selection persists and enters its manual workflow',
|
|
(tester) async {
|
|
final platform = FakeSchoolPlatform();
|
|
WebViewPlatform.instance = platform;
|
|
final store = MemoryStore(),
|
|
controller = AppController(
|
|
MemoryStore(),
|
|
FakeNotifications(),
|
|
FakeCalendar(),
|
|
() => DateTime.utc(2026, 10, 14),
|
|
);
|
|
final under = UndergraduateSession();
|
|
addTearDown(controller.dispose);
|
|
addTearDown(under.dispose);
|
|
await controller.initialize();
|
|
await tester.pumpWidget(
|
|
HepanApp(
|
|
controller: controller,
|
|
undergraduate: under,
|
|
undergraduateBuilder: () => const Scaffold(body: Text('本科网页')),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
expect(platform.controllerCreations, 0);
|
|
await tester.tap(find.bySemanticsLabel('个人设置'));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.widgetWithText(FilledButton, '选择学校'));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('电子科技大学(研究生)'), findsOneWidget);
|
|
expect(find.text('电子科技大学(本科生)'), findsOneWidget);
|
|
await tester.tap(find.text('电子科技大学(本科生)'));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('本科网页'), findsOneWidget);
|
|
expect(
|
|
controller.snapshot.selectedSchool,
|
|
SupportedSchool.uestcUndergraduate,
|
|
);
|
|
expect(platform.web.loads, ['https://eams.uestc.edu.cn/eams/']);
|
|
expect(under.requestingExams, isFalse);
|
|
store.value = AppSnapshot.fromJson(controller.snapshot.toJson());
|
|
expect(store.value!.selectedSchool, SupportedSchool.uestcUndergraduate);
|
|
},
|
|
);
|
|
testWidgets('failed school preference does not create a browser', (
|
|
tester,
|
|
) async {
|
|
final platform = FakeSchoolPlatform();
|
|
WebViewPlatform.instance = platform;
|
|
final store = MemoryStore(), under = UndergraduateSession();
|
|
final controller = AppController(
|
|
store,
|
|
FakeNotifications(),
|
|
FakeCalendar(),
|
|
DateTime.now,
|
|
);
|
|
addTearDown(controller.dispose);
|
|
addTearDown(under.dispose);
|
|
await controller.initialize();
|
|
store.failSave = true;
|
|
await tester.pumpWidget(
|
|
HepanApp(
|
|
controller: controller,
|
|
undergraduate: under,
|
|
undergraduateBuilder: () => const Scaffold(body: Text('本科网页')),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.bySemanticsLabel('个人设置'));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.widgetWithText(FilledButton, '选择学校'));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.text('电子科技大学(本科生)'));
|
|
await tester.pumpAndSettle();
|
|
expect(platform.controllerCreations, 0);
|
|
expect(controller.snapshot.selectedSchool, isNull);
|
|
expect(find.text('本科网页'), findsNothing);
|
|
});
|
|
testWidgets('exam refresh reuses the successful undergraduate query', (
|
|
tester,
|
|
) async {
|
|
final platform = FakeSchoolPlatform();
|
|
WebViewPlatform.instance = platform;
|
|
final under = UndergraduateSession();
|
|
final store = MemoryStore(
|
|
AppSnapshot(
|
|
selectedSchool: SupportedSchool.uestcUndergraduate,
|
|
examSchedule: ExamSchedule(
|
|
semesterLabel: '2025-2026第二学期',
|
|
termId: '503',
|
|
school: SupportedSchool.uestcUndergraduate,
|
|
requestedExamTypes: {1, 2},
|
|
records: [],
|
|
),
|
|
),
|
|
);
|
|
final controller = AppController(
|
|
store,
|
|
FakeNotifications(),
|
|
FakeCalendar(),
|
|
DateTime.now,
|
|
);
|
|
addTearDown(controller.dispose);
|
|
addTearDown(under.dispose);
|
|
await controller.initialize();
|
|
await tester.pumpWidget(
|
|
HepanApp(
|
|
controller: controller,
|
|
undergraduate: under,
|
|
undergraduateBuilder: () => const Scaffold(body: Text('本科网页')),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.bySemanticsLabel('考试'));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.byTooltip('从学校更新考试'));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('本科网页'), findsOneWidget);
|
|
expect(under.query!.term.id, 503);
|
|
expect(under.query!.types, {
|
|
UndergraduateExamType.finalExam,
|
|
UndergraduateExamType.midterm,
|
|
});
|
|
});
|
|
testWidgets('query option cancellation starts no login', (tester) async {
|
|
final platform = FakeSchoolPlatform();
|
|
WebViewPlatform.instance = platform;
|
|
final under = UndergraduateSession();
|
|
final controller = AppController(
|
|
MemoryStore(
|
|
AppSnapshot(selectedSchool: SupportedSchool.uestcUndergraduate),
|
|
),
|
|
FakeNotifications(),
|
|
FakeCalendar(),
|
|
DateTime.now,
|
|
);
|
|
addTearDown(controller.dispose);
|
|
addTearDown(under.dispose);
|
|
await controller.initialize();
|
|
await tester.pumpWidget(
|
|
HepanApp(
|
|
controller: controller,
|
|
undergraduate: under,
|
|
undergraduateBuilder: () => const Scaffold(body: Text('本科网页')),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.bySemanticsLabel('考试'));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.byTooltip('查询选项'));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.text('取消'));
|
|
await tester.pumpAndSettle();
|
|
expect(platform.controllerCreations, 0);
|
|
});
|
|
testWidgets(
|
|
'shared logout invalidates both schools without creating another browser',
|
|
(tester) async {
|
|
final platform = FakeSchoolPlatform();
|
|
WebViewPlatform.instance = platform;
|
|
final under = UndergraduateSession(), grad = SchoolSession();
|
|
await grad.openTimetable();
|
|
await under.openTimetable();
|
|
final controller = AppController(
|
|
MemoryStore(
|
|
AppSnapshot(selectedSchool: SupportedSchool.uestcUndergraduate),
|
|
),
|
|
FakeNotifications(),
|
|
FakeCalendar(),
|
|
DateTime.now,
|
|
);
|
|
addTearDown(controller.dispose);
|
|
addTearDown(under.dispose);
|
|
addTearDown(grad.dispose);
|
|
await controller.initialize();
|
|
await tester.pumpWidget(
|
|
HepanApp(controller: controller, school: grad, undergraduate: under),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.bySemanticsLabel('个人设置'));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.text('退出学校登录'));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.text('保留课表和考试'));
|
|
await tester.pumpAndSettle();
|
|
expect(platform.controllerCreations, 2);
|
|
expect(under.canLogout, isFalse);
|
|
expect(grad.canLogout, isFalse);
|
|
},
|
|
);
|
|
}
|