104 lines
3.9 KiB
Dart
104 lines
3.9 KiB
Dart
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/app_controller.dart';
|
|
import 'package:hepan_everyday/domain/app_snapshot.dart';
|
|
import 'package:hepan_everyday/domain/app_settings.dart';
|
|
import 'package:hepan_everyday/domain/school_identity.dart';
|
|
import 'package:hepan_everyday/domain/school_term.dart';
|
|
import 'package:hepan_everyday/domain/schedule_engine.dart';
|
|
import 'package:hepan_everyday/features/timetable/timetable_page.dart';
|
|
import 'package:hepan_everyday/features/timetable/week_grid.dart';
|
|
import 'package:hepan_everyday/services/local_notification_service.dart';
|
|
import 'package:hepan_everyday/services/android_calendar_service.dart';
|
|
|
|
import '../support/fakes.dart';
|
|
import '../domain/schedule_engine_test.dart' show course;
|
|
import '../services/notification_service_test.dart' show AlarmGateway;
|
|
import '../services/calendar_service_test.dart' show CalendarProvider;
|
|
|
|
void main() {
|
|
setUpAll(tzdata.initializeTimeZones);
|
|
testWidgets('row count follows imported school across empty weeks and demo', (
|
|
tester,
|
|
) async {
|
|
tester.view.physicalSize = const Size(360, 800);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.resetPhysicalSize);
|
|
addTearDown(tester.view.resetDevicePixelRatio);
|
|
final controller = AppController(
|
|
MemoryStore(),
|
|
FakeNotifications(),
|
|
FakeCalendar(),
|
|
() => DateTime.utc(2026, 9, 7),
|
|
);
|
|
addTearDown(controller.dispose);
|
|
final settings = AppSettings(
|
|
semester: Semester(startDate: DateTime(2026, 9, 7), totalWeeks: 20),
|
|
);
|
|
controller.snapshot = AppSnapshot(
|
|
settings: settings,
|
|
schoolTerm: SchoolTerm(523, school: SupportedSchool.uestcUndergraduate),
|
|
courses: [
|
|
course(first: 9, last: 12, weeks: {2}),
|
|
],
|
|
selectedSchool: SupportedSchool.uestcGraduate,
|
|
);
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(body: TimetablePage(controller: controller)),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
expect(tester.widget<WeekGrid>(find.byType(WeekGrid)).periodCount, 12);
|
|
expect(
|
|
find.byWidgetPredicate(
|
|
(w) => w is Text && w.data == '12' && w.style?.color == null,
|
|
),
|
|
findsOneWidget,
|
|
);
|
|
expect(tester.getRect(find.text('周日')).right, lessThanOrEqualTo(360));
|
|
await controller.showDemo();
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(body: TimetablePage(controller: controller)),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
expect(tester.widget<WeekGrid>(find.byType(WeekGrid)).periodCount, 11);
|
|
});
|
|
test('period twelve drives reminders and calendar ending at 22:45', () async {
|
|
final term = Semester(startDate: DateTime(2026, 9, 7), totalWeeks: 1),
|
|
events = ScheduleEngine.occurrences([
|
|
course(day: 1, first: 12, last: 12),
|
|
], Semester(startDate: DateTime(2026, 9, 7), totalWeeks: 1));
|
|
expect(events.single.start.hour, 22);
|
|
expect(events.single.end.hour, 22);
|
|
expect(events.single.end.minute, 45);
|
|
final night = ScheduleEngine.occurrences([
|
|
course(day: 1, first: 9, last: 12),
|
|
], term).single;
|
|
expect(night.start.hour, 19);
|
|
expect(night.start.minute, 30);
|
|
expect(night.end.minute, 45);
|
|
final gateway = AlarmGateway();
|
|
await LocalNotificationService(gateway).reconcile(
|
|
events,
|
|
AppSettings(semester: term, reminderOffsets: [5, 15]),
|
|
DateTime.utc(2026, 9, 6),
|
|
);
|
|
expect(
|
|
gateway.alarms.values
|
|
.map((a) => '${a.fireAt.hour}:${a.fireAt.minute}')
|
|
.toSet(),
|
|
{'21:55', '21:45'},
|
|
);
|
|
final provider = CalendarProvider();
|
|
await AndroidCalendarService(provider).sync(events, 'local', {});
|
|
expect(
|
|
provider.drafts.values.single.endMs,
|
|
events.single.end.millisecondsSinceEpoch,
|
|
);
|
|
});
|
|
}
|