171 lines
6.5 KiB
Dart
171 lines
6.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:student_app/data/repositories/curriculum_question_bank.dart';
|
|
import 'package:student_app/presentation/screens/curriculum/lesson_homework_sheet.dart';
|
|
import 'package:student_app/presentation/screens/exams/adaptive_exam_screen.dart';
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
group('CurriculumQuestionBank Subject Isolation & Decoupling', () {
|
|
test('Islamic Studies question bank contains ZERO math equations', () {
|
|
final exam = CurriculumQuestionBank.getUnitExam(
|
|
subjectId: 'islamic_10',
|
|
unitKey: 'unit_01',
|
|
);
|
|
|
|
expect(exam.title, contains('القرآن الكريم'));
|
|
expect(exam.questions.isNotEmpty, isTrue);
|
|
|
|
for (final q in exam.questions) {
|
|
// Assert zero math contamination
|
|
expect(q.questionText.contains('x²'), isFalse, reason: 'Math leaked into Islamic exam: ${q.questionText}');
|
|
expect(q.questionText.contains('معادلة'), isFalse, reason: 'Math leaked into Islamic exam: ${q.questionText}');
|
|
expect(q.questionText.contains('مشتق'), isFalse, reason: 'Calculus leaked into Islamic exam: ${q.questionText}');
|
|
// Assert Islamic topic relevance
|
|
expect(
|
|
q.topicTag.contains('قرآن') ||
|
|
q.topicTag.contains('بيع') ||
|
|
q.topicTag.contains('معاملات') ||
|
|
q.topicTag.contains('فقه') ||
|
|
q.topicTag.contains('سيرة') ||
|
|
q.topicTag.contains('إسلام') ||
|
|
q.topicTag.contains('حديث') ||
|
|
q.topicTag.contains('آداب'),
|
|
isTrue,
|
|
reason: 'Non-Islamic topic tag in Islamic exam: ${q.topicTag}',
|
|
);
|
|
}
|
|
});
|
|
|
|
test('Physics question bank contains authentic physics concepts', () {
|
|
final examU1 = CurriculumQuestionBank.getUnitExam(
|
|
subjectId: 'physics_10',
|
|
unitKey: 'unit_01',
|
|
);
|
|
expect(examU1.title, contains('المتجهات'));
|
|
expect(examU1.questions.any((q) => q.questionText.contains('متجه')), isTrue);
|
|
|
|
final examU2 = CurriculumQuestionBank.getUnitExam(
|
|
subjectId: 'physics_10',
|
|
unitKey: 'unit_02',
|
|
);
|
|
expect(examU2.title, contains('المقذوفات'));
|
|
expect(examU2.questions.any((q) => q.questionText.contains('أقصى ارتفاع')), isTrue);
|
|
});
|
|
|
|
test('Arabic question bank contains authentic grammar and literature', () {
|
|
final exam = CurriculumQuestionBank.getUnitExam(
|
|
subjectId: 'arabic_10',
|
|
unitKey: 'unit_01',
|
|
);
|
|
expect(exam.title, contains('الشرط'));
|
|
expect(exam.questions.any((q) => q.topicTag.contains('الشرط')), isTrue);
|
|
});
|
|
|
|
test('Lesson homework returns 3 focused questions with explanations', () {
|
|
final hw = CurriculumQuestionBank.getLessonHomework(
|
|
subjectId: 'islamic_10',
|
|
lessonId: 'lesson_01',
|
|
lessonTitle: 'واجب المسلم تجاه القرآن الكريم',
|
|
);
|
|
|
|
expect(hw.questions.length, greaterThanOrEqualTo(3));
|
|
for (final q in hw.questions) {
|
|
expect(q.questionText.isNotEmpty, isTrue);
|
|
expect(q.options.length, 4);
|
|
expect(q.explanation.isNotEmpty, isTrue);
|
|
expect(q.correctIndex >= 0 && q.correctIndex < 4, isTrue);
|
|
}
|
|
});
|
|
|
|
test('Subject worksheets are populated and isolated per subject', () {
|
|
final islamicSheets = CurriculumQuestionBank.getSubjectWorksheets(
|
|
subjectId: 'islamic_10',
|
|
subjectTitle: 'التربية الإسلامية',
|
|
);
|
|
expect(islamicSheets.isNotEmpty, isTrue);
|
|
expect(islamicSheets.any((s) => s.title.contains('القرآن')), isTrue);
|
|
|
|
final physicsSheets = CurriculumQuestionBank.getSubjectWorksheets(
|
|
subjectId: 'physics_10',
|
|
subjectTitle: 'الفيزياء',
|
|
);
|
|
expect(physicsSheets.isNotEmpty, isTrue);
|
|
expect(physicsSheets.any((s) => s.title.contains('المتجهات')), isTrue);
|
|
});
|
|
});
|
|
|
|
group('LessonHomeworkSheet UI Test', () {
|
|
testWidgets('renders homework questions and verifies answer', (tester) async {
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: Scaffold(
|
|
body: LessonHomeworkSheet(
|
|
subjectId: 'islamic_10',
|
|
subjectTitle: 'التربية الإسلامية',
|
|
lessonId: 'lesson_01',
|
|
lessonTitle: 'واجب المسلم تجاه القرآن الكريم',
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.textContaining('واجب الدرس'), findsOneWidget);
|
|
expect(find.textContaining('التمرين 1'), findsOneWidget);
|
|
expect(find.text('تحقق من الإجابة 🚀'), findsOneWidget);
|
|
|
|
// Tap first option
|
|
await tester.tap(find.textContaining('استحباب تلاوة القرآن'));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Tap check answer
|
|
await tester.tap(find.text('تحقق من الإجابة 🚀'));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Check explanation shows up
|
|
expect(find.textContaining('الشرح التوضيحي'), findsOneWidget);
|
|
});
|
|
});
|
|
|
|
group('AdaptiveExamScreen Subject Decoupling UI Test', () {
|
|
testWidgets('opening Islamic exam does NOT show math equations', (tester) async {
|
|
final initialExam = CurriculumQuestionBank.getUnitExam(
|
|
subjectId: 'islamic_10',
|
|
unitKey: 'unit_01',
|
|
);
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: AdaptiveExamScreen(
|
|
examId: 9999,
|
|
title: 'اختبار الفهم التكيفي: القرآن الكريم',
|
|
subjectTitle: 'التربية الإسلامية',
|
|
subjectCode: 'islamic_10',
|
|
unitKey: 'unit_01',
|
|
initialExam: initialExam,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.pump();
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
|
|
// Verify header
|
|
expect(find.text('التربية الإسلامية'), findsOneWidget);
|
|
expect(find.text('اختبار الفهم التكيفي: القرآن الكريم'), findsOneWidget);
|
|
|
|
// Verify that math equations never appear
|
|
expect(find.textContaining('x³'), findsNothing);
|
|
expect(find.textContaining('معادلة تربيعية'), findsNothing);
|
|
|
|
// Unmount to cancel BlocProvider and ExamCubit countdown timer cleanly
|
|
await tester.pumpWidget(const SizedBox());
|
|
});
|
|
});
|
|
}
|