Files
saqel/apps/student_app/test/subject_hub_decoupling_test.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());
});
});
}