整个课程和数据UI重新设计版本
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:kouyu_english/core/app_state.dart';
|
||||
import 'package:kouyu_english/core/models.dart';
|
||||
import 'package:kouyu_english/core/courses/courses.dart';
|
||||
import 'package:kouyu_english/core/courses/course_pack.dart';
|
||||
import 'package:kouyu_english/core/courses/course_repository.dart';
|
||||
import 'package:kouyu_english/features/lesson/lesson_flow.dart';
|
||||
|
||||
/// Widget smoke test for the JSON units' 听读材料 (listening/reading
|
||||
/// comprehension) step: it must be reached only on the last segment of a unit
|
||||
/// that has materials, render from the real loaded content, and let the learner
|
||||
/// continue to writing once every question is answered.
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
setUpAll(() async {
|
||||
await CourseRepository.instance.load();
|
||||
});
|
||||
|
||||
tearDownAll(() => CourseRepository.instance.resetForTest());
|
||||
|
||||
/// The first loaded unit whose materials contain at least one question.
|
||||
CoursePack unitWithQuestions() => CourseRepository.instance.units.firstWhere(
|
||||
(u) => u.materials.any((m) => m.questions.isNotEmpty),
|
||||
);
|
||||
|
||||
AppState stateOn(String unitId, int segmentIndex) {
|
||||
final state = AppState();
|
||||
state.activeLessonId = unitId;
|
||||
state.activeSegmentIndexes[unitId] = segmentIndex;
|
||||
return state;
|
||||
}
|
||||
|
||||
testWidgets(
|
||||
'material step is reached only on the last segment with materials',
|
||||
(tester) async {
|
||||
final unit = unitWithQuestions();
|
||||
final lesson = lessonById(unit.id);
|
||||
expect(
|
||||
lesson.segments.length,
|
||||
greaterThan(1),
|
||||
reason: 'need a multi-segment unit to prove the gate',
|
||||
);
|
||||
|
||||
// Finishing reading on an earlier segment skips straight to writing.
|
||||
final early = stateOn(unit.id, 0);
|
||||
early.lessonStep = LessonStep.reading;
|
||||
early.completeReading();
|
||||
expect(early.lessonStep, LessonStep.writing);
|
||||
|
||||
// Finishing reading on the final segment opens the comprehension step.
|
||||
final last = stateOn(unit.id, lesson.segments.length - 1);
|
||||
last.lessonStep = LessonStep.reading;
|
||||
last.completeReading();
|
||||
expect(last.lessonStep, LessonStep.material);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'renders the unit materials and continues once every question is answered',
|
||||
(tester) async {
|
||||
final unit = unitWithQuestions();
|
||||
final lesson = lessonById(unit.id);
|
||||
final state = stateOn(unit.id, lesson.segments.length - 1);
|
||||
state.lessonStep = LessonStep.material;
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: LessonFlow(
|
||||
state: state,
|
||||
onOpenDialogue: () {},
|
||||
onFinish: () {},
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// The step rendered from the real loaded content.
|
||||
expect(find.text('读一段真实的小材料,做完理解题。'), findsOneWidget);
|
||||
// Continue is gated until every question is answered.
|
||||
expect(find.text('答对所有理解题后继续'), findsOneWidget);
|
||||
expect(find.text('继续写一写'), findsNothing);
|
||||
|
||||
// Answer every question by tapping its correct option (answer == the
|
||||
// parsed contract's first option; the widget shuffles their display order).
|
||||
for (final material in unit.materials) {
|
||||
for (final question in material.questions) {
|
||||
final option = find.text(question.answer).first;
|
||||
await tester.ensureVisible(option);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(option);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
}
|
||||
|
||||
// Now the button is enabled and advances the lesson to writing.
|
||||
final go = find.text('继续写一写');
|
||||
expect(go, findsOneWidget);
|
||||
await tester.ensureVisible(go);
|
||||
await tester.tap(go);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(state.lessonStep, LessonStep.writing);
|
||||
},
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user