142 lines
4.8 KiB
Dart
142 lines
4.8 KiB
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/app_settings.dart';
|
|
import 'package:hepan_everyday/domain/semester.dart';
|
|
import 'package:hepan_everyday/domain/school_term.dart';
|
|
import 'package:hepan_everyday/domain/exam_schedule.dart';
|
|
import 'package:hepan_everyday/domain/course.dart';
|
|
import 'package:hepan_everyday/data/json_schedule_import.dart';
|
|
|
|
import '../support/fakes.dart';
|
|
import '../domain/schedule_engine_test.dart' show course;
|
|
|
|
void main() {
|
|
test('term labels and both query URLs follow the school numbering', () {
|
|
expect(SchoolTerm(73).label, '2026-2027年秋');
|
|
expect(SchoolTerm(72).label, '2025-2026年春');
|
|
expect(SchoolTerm(71).label, '2025-2026年秋');
|
|
expect(SchoolTerm(74).label, '2026-2027年春');
|
|
expect(SchoolTerm(75).label, '2027-2028年秋');
|
|
expect(SchoolTerm(73).timetableUri.path, '/pyxx/pygl/xskbcx/index/73');
|
|
expect(SchoolTerm(72).examUri.queryParameters, {'xq': '72'});
|
|
});
|
|
test('selected school term survives settings copies and restart', () {
|
|
final saved = AppSnapshot(schoolTerm: SchoolTerm(72));
|
|
final loaded = AppSnapshot.fromJson(
|
|
saved
|
|
.copyWith(settings: saved.settings.copyWith(reminderMinutes: 30))
|
|
.toJson(),
|
|
);
|
|
expect(loaded.schoolTerm, SchoolTerm(72));
|
|
final legacy = saved.toJson()..remove('schoolTerm');
|
|
expect(AppSnapshot.fromJson(legacy).schoolTerm, isNull);
|
|
expect(() => SchoolTerm(0), throwsArgumentError);
|
|
});
|
|
test(
|
|
'previous app saves recover the actual HTML term for subsequent refresh',
|
|
() {
|
|
final legacy = AppSnapshot(
|
|
examSchedule: ExamSchedule(
|
|
semesterLabel: '2026-2027秋',
|
|
termId: '73',
|
|
records: [],
|
|
),
|
|
).toJson()..remove('schoolTerm');
|
|
expect(AppSnapshot.fromJson(legacy).schoolTerm, SchoolTerm(73));
|
|
},
|
|
);
|
|
for (final exams in [false, true]) {
|
|
test(
|
|
'successful new term ${exams ? 'exam' : 'course'} import isolates old dates and data',
|
|
() async {
|
|
final old = AppSnapshot(
|
|
schoolTerm: SchoolTerm(73),
|
|
courses: [course()],
|
|
examSchedule: ExamSchedule(
|
|
semesterLabel: 'old',
|
|
termId: '73',
|
|
records: [],
|
|
),
|
|
settings: AppSettings(
|
|
semester: Semester(startDate: DateTime(2026, 9, 7), totalWeeks: 20),
|
|
),
|
|
);
|
|
final store = MemoryStore(old);
|
|
final c = AppController(
|
|
store,
|
|
FakeNotifications(),
|
|
FakeCalendar(),
|
|
() => DateTime(2026, 10, 13),
|
|
);
|
|
await c.initialize();
|
|
if (exams) {
|
|
await c.applyExams(
|
|
ExamSchedule(
|
|
semesterLabel: SchoolTerm(72).label,
|
|
termId: '72',
|
|
records: [],
|
|
),
|
|
);
|
|
expect(c.snapshot.courses, isEmpty);
|
|
} else {
|
|
await c.applyImport(
|
|
ImportDraft(
|
|
courses: [course()],
|
|
explicitlyEmpty: false,
|
|
source: CourseSource.file,
|
|
parserVersion: 'test',
|
|
schoolTerm: SchoolTerm(72),
|
|
),
|
|
confirmedEmpty: false,
|
|
);
|
|
expect(c.snapshot.examSchedule, isNull);
|
|
}
|
|
expect(c.lastError, isNull);
|
|
expect(c.snapshot.schoolTerm, SchoolTerm(72));
|
|
expect(c.snapshot.settings.semester, isNull);
|
|
c.dispose();
|
|
},
|
|
);
|
|
}
|
|
test('same-term refresh keeps date and exams; failed term change keeps all old data', () async {
|
|
final old = AppSnapshot(
|
|
schoolTerm: SchoolTerm(73),
|
|
courses: [course()],
|
|
examSchedule: ExamSchedule(
|
|
semesterLabel: 'old',
|
|
termId: '73',
|
|
records: [],
|
|
),
|
|
settings: AppSettings(
|
|
semester: Semester(startDate: DateTime(2026, 9, 7), totalWeeks: 20),
|
|
),
|
|
);
|
|
final store = MemoryStore(old);
|
|
final c = AppController(
|
|
store,
|
|
FakeNotifications(),
|
|
FakeCalendar(),
|
|
() => DateTime(2026, 10, 13),
|
|
);
|
|
await c.initialize();
|
|
ImportDraft draft(int id) => ImportDraft(
|
|
courses: [course()],
|
|
explicitlyEmpty: false,
|
|
source: CourseSource.file,
|
|
parserVersion: 'test',
|
|
schoolTerm: SchoolTerm(id),
|
|
);
|
|
await c.applyImport(draft(73), confirmedEmpty: false);
|
|
expect(c.snapshot.settings.semester, old.settings.semester);
|
|
expect(c.snapshot.examSchedule, old.examSchedule);
|
|
store.failSave = true;
|
|
await c.applyImport(draft(72), confirmedEmpty: false);
|
|
expect(c.lastError, isNotNull);
|
|
expect(c.snapshot.schoolTerm, SchoolTerm(73));
|
|
expect(c.snapshot.settings.semester, old.settings.semester);
|
|
expect(c.snapshot.examSchedule, old.examSchedule);
|
|
c.dispose();
|
|
});
|
|
}
|