feat: compose Android app and verify native calendar and reminders
This commit is contained in:
@@ -2,11 +2,44 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:timezone/data/latest.dart' as tzdata;
|
||||
import 'package:hepan_everyday/app/hepan_app.dart';
|
||||
import 'package:hepan_everyday/app/app_controller.dart';
|
||||
import 'package:hepan_everyday/features/profile/settings_page.dart';
|
||||
import 'package:hepan_everyday/services/calendar_service.dart';
|
||||
|
||||
import '../support/fakes.dart';
|
||||
|
||||
import 'navigation_test.dart' show uiController;
|
||||
|
||||
void main() {
|
||||
setUpAll(tzdata.initializeTimeZones);
|
||||
testWidgets('calendar provider failure is explained and keeps switch off', (
|
||||
tester,
|
||||
) async {
|
||||
final controller = AppController(
|
||||
MemoryStore(),
|
||||
FakeNotifications(),
|
||||
UnavailableCalendar(),
|
||||
DateTime.now,
|
||||
);
|
||||
await controller.initialize();
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(home: SettingsPage(controller: controller)),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.scrollUntilVisible(
|
||||
find.text('导入手机日历'),
|
||||
250,
|
||||
scrollable: find.byType(Scrollable).first,
|
||||
);
|
||||
await tester.ensureVisible(find.text('导入手机日历'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('导入手机日历'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(tester.takeException(), isNull);
|
||||
expect(find.text('日历暂时不可用,请检查权限后重试'), findsOneWidget);
|
||||
expect(controller.snapshot.settings.calendarEnabled, isFalse);
|
||||
controller.dispose();
|
||||
});
|
||||
testWidgets(
|
||||
'invalid semester weeks are rejected without changing saved data',
|
||||
(tester) async {
|
||||
@@ -57,3 +90,9 @@ void main() {
|
||||
controller.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
class UnavailableCalendar extends FakeCalendar {
|
||||
@override
|
||||
Future<List<DeviceCalendar>> listWritableCalendars() async =>
|
||||
throw StateError('unavailable');
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:timezone/data/latest.dart' as tzdata;
|
||||
import 'package:hepan_everyday/main.dart';
|
||||
import 'package:hepan_everyday/app/app_controller.dart';
|
||||
import 'package:hepan_everyday/app/hepan_app.dart';
|
||||
import 'package:hepan_everyday/domain/app_snapshot.dart';
|
||||
import 'package:hepan_everyday/domain/app_settings.dart';
|
||||
import 'package:hepan_everyday/domain/semester.dart';
|
||||
|
||||
import '../support/fakes.dart';
|
||||
import '../domain/schedule_engine_test.dart' show course;
|
||||
|
||||
void main() {
|
||||
setUpAll(tzdata.initializeTimeZones);
|
||||
testWidgets(
|
||||
'actual startup connects both tabs and reminder tap opens saved course',
|
||||
(tester) async {
|
||||
final selection = ValueNotifier<String?>(null);
|
||||
final controller = AppController(
|
||||
MemoryStore(
|
||||
AppSnapshot(
|
||||
courses: [course(last: 2)],
|
||||
settings: AppSettings(
|
||||
semester: Semester(
|
||||
startDate: DateTime(2026, 9, 9),
|
||||
totalWeeks: 5,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
FakeNotifications(),
|
||||
FakeCalendar(),
|
||||
() => DateTime.utc(2026, 9, 8),
|
||||
);
|
||||
await controller.initialize();
|
||||
await tester.pumpWidget(
|
||||
buildApplication(controller, notificationSelection: selection),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.bySemanticsLabel('课表'), findsOneWidget);
|
||||
expect(find.bySemanticsLabel('我的'), findsOneWidget);
|
||||
await tester.tap(find.bySemanticsLabel('我的'));
|
||||
await tester.pumpAndSettle();
|
||||
selection.value = 'math/2026-09-09';
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('知道了'), findsOneWidget);
|
||||
expect(find.textContaining('08:30–10:05'), findsOneWidget);
|
||||
await tester.tap(find.text('知道了'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(HepanApp), findsOneWidget);
|
||||
controller.dispose();
|
||||
selection.dispose();
|
||||
},
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user