feat: 完善听力口语辅助状态记录、练习分块与复习抽查间隔机制
This commit is contained in:
@@ -4,9 +4,7 @@ import 'package:kouyu_english/core/app_state.dart';
|
||||
import 'package:kouyu_english/core/models.dart';
|
||||
import 'package:kouyu_english/core/courses/course_repository.dart';
|
||||
|
||||
/// The A0 → A1 → A2 → B1 unlock chain. Crossing out of A0 into A1 additionally
|
||||
/// requires passing the A0 stage assessment; higher levels then chain linearly
|
||||
/// (finishing the previous unit unlocks the next), with no extra assessment.
|
||||
/// Draft packs are loaded for editing and validation but are not learnable.
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
@@ -72,13 +70,13 @@ void main() {
|
||||
reason: 'A1 stays locked until A0 is passed',
|
||||
);
|
||||
|
||||
// Passing the A0 stage assessment opens the first A1 unit.
|
||||
// Passing the A0 stage assessment does not bypass editorial approval.
|
||||
makeA0Passed(state);
|
||||
expect(state.a0Passed, isTrue);
|
||||
expect(state.isLessonUnlocked(firstA1.id), isTrue);
|
||||
expect(state.isLessonUnlocked(firstA1.id), isFalse);
|
||||
});
|
||||
|
||||
test('A1 → A2 → B1 chain linearly by finishing the previous unit', () {
|
||||
test('draft packs stay locked even when prerequisites are complete', () {
|
||||
final state = AppState();
|
||||
makeA0Passed(state);
|
||||
for (final lesson in a0SeedLessons) {
|
||||
@@ -89,34 +87,32 @@ void main() {
|
||||
final a2 = byLevel('A2');
|
||||
final b1 = byLevel('B1');
|
||||
|
||||
// A1 opened, but only the first unit; the second waits on the first.
|
||||
expect(state.isLessonUnlocked(a1.first.id), isTrue);
|
||||
expect(state.isLessonUnlocked(a1.first.id), isFalse);
|
||||
expect(state.isLessonUnlocked(a1[1].id), isFalse);
|
||||
|
||||
// Finishing the first A1 unit unlocks the second — no extra gate.
|
||||
state.completedLessonIds.add(a1.first.id);
|
||||
expect(state.isLessonUnlocked(a1[1].id), isTrue);
|
||||
|
||||
// A2 stays locked until the last A1 unit is finished.
|
||||
expect(state.isLessonUnlocked(a1[1].id), isFalse);
|
||||
expect(state.isLessonUnlocked(a2.first.id), isFalse);
|
||||
for (final lesson in a1) {
|
||||
state.completedLessonIds.add(lesson.id);
|
||||
}
|
||||
expect(
|
||||
state.isLessonUnlocked(a2.first.id),
|
||||
isTrue,
|
||||
reason: 'A1 → A2 chains linearly, no separate assessment',
|
||||
isFalse,
|
||||
reason: 'Completing draft prerequisites must not open another draft',
|
||||
);
|
||||
|
||||
// B1 likewise unlocks only after the last A2 unit.
|
||||
expect(state.isLessonUnlocked(b1.first.id), isFalse);
|
||||
for (final lesson in a2) {
|
||||
state.completedLessonIds.add(lesson.id);
|
||||
}
|
||||
expect(
|
||||
state.isLessonUnlocked(b1.first.id),
|
||||
isTrue,
|
||||
reason: 'A2 → B1 chains linearly',
|
||||
isFalse,
|
||||
reason: 'B1 remains closed until approved',
|
||||
);
|
||||
expect(state.nextIncompleteLessonId, isNull);
|
||||
expect(state.allLessonsComplete, isTrue);
|
||||
state.setPlacementStartLesson(a1.first.id);
|
||||
expect(state.placementStartLessonId, 'a0-01');
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user