Metatron_Student_ERP/flutter_app/test/models_and_parsing_test.dart

306 lines
9.8 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:metatron_student_erp/core/utils/safe_convert.dart';
import 'package:metatron_student_erp/models/attendance.dart';
import 'package:metatron_student_erp/models/dashboard.dart';
import 'package:metatron_student_erp/models/exam.dart';
import 'package:metatron_student_erp/models/result.dart';
import 'package:metatron_student_erp/models/student.dart';
import 'package:metatron_student_erp/models/timetable.dart';
import 'package:metatron_student_erp/models/user.dart';
void main() {
group('SafeConvert Utility Tests', () {
test('handles Odoo false, null, and empty values gracefully', () {
expect(SafeConvert.toNullableString(false), isNull);
expect(SafeConvert.toNullableString(null), isNull);
expect(SafeConvert.toNullableString('hello'), 'hello');
expect(SafeConvert.toSafeString(false, 'default'), 'default');
expect(SafeConvert.toNullableInt(false), isNull);
expect(SafeConvert.toNullableInt(null), isNull);
expect(SafeConvert.toNullableInt(42), 42);
expect(SafeConvert.toNullableInt('42'), 42);
expect(SafeConvert.toSafeInt(false, 0), 0);
expect(SafeConvert.toNullableDouble(false), isNull);
expect(SafeConvert.toNullableDouble(null), isNull);
expect(SafeConvert.toNullableDouble(85.5), 85.5);
expect(SafeConvert.toNullableDouble('85.5'), 85.5);
expect(SafeConvert.toSafeDouble(false, 0.0), 0.0);
expect(SafeConvert.toSafeBool(false), isFalse);
expect(SafeConvert.toSafeBool(true), isTrue);
expect(SafeConvert.toSafeBool(null), isFalse);
expect(SafeConvert.toSafeBool('true'), isTrue);
expect(SafeConvert.toNullableMap(false), isNull);
expect(SafeConvert.toNullableMap({'a': 1}), {'a': 1});
expect(SafeConvert.toSafeList(false, (x) => x), isEmpty);
expect(SafeConvert.toSafeList([1, 2], (x) => x * 2), [2, 4]);
});
});
group('Student Profile Parsing with Odoo false fields', () {
test('parses full student profile with mixed false and real values', () {
final json = {
'id': 4,
'student_id': 'STU-9999',
'admission_number': 'ADM-9999',
'roll_number': false, // Odoo boolean false
'full_name': 'Demo Student',
'email': false, // Odoo boolean false
'mobile': '9876543210',
'gender': 'male',
'date_of_birth': '2000-01-01',
'status': 'active',
'campus': {'id': 11, 'name': 'Main Campus'},
'department': false, // Odoo boolean false
'program': {'id': 11, 'name': 'B.Tech CS'},
'level': false,
'academic_year': {'id': 10, 'name': '2026-2027'},
'academic_term': {'id': 9, 'name': 'Semester 1'},
'batch': {'id': 3, 'name': 'Batch 2026'},
'semester': {'id': 3, 'name': 'Sem 1'},
'section': {'id': 2, 'name': 'Section A'},
};
final profile = StudentProfile.fromJson(json);
expect(profile.id, 4);
expect(profile.studentId, 'STU-9999');
expect(profile.admissionNumber, 'ADM-9999');
expect(profile.rollNumber, isNull); // Was false in JSON
expect(profile.email, isNull); // Was false in JSON
expect(profile.mobile, '9876543210');
expect(profile.fullName, 'Demo Student');
expect(profile.campus?.name, 'Main Campus');
expect(profile.department, isNull); // Was false in JSON
expect(profile.program?.name, 'B.Tech CS');
expect(profile.academicYear?.name, '2026-2027');
});
});
group('Attendance Parsing Tests', () {
test('parses attendance summary and record lines', () {
final json = {
'summary': {
'percentage': 87.5,
'present': 14,
'absent': 2,
'late': 1,
'medical_leave': 0,
'on_duty': 0,
},
'records': [
{'id': 101, 'date': '2026-10-12', 'status': 'present'},
{'id': 102, 'date': '2026-10-11', 'status': 'absent'},
],
};
final data = AttendanceData.fromJson(json);
expect(data.summary.percentage, 87.5);
expect(data.summary.present, 14);
expect(data.summary.absent, 2);
expect(data.records.length, 2);
expect(data.records[0].date, '2026-10-12');
expect(data.records[0].status, 'present');
expect(data.records[1].status, 'absent');
});
test('handles empty or false attendance gracefully', () {
final data = AttendanceData.fromJson({
'summary': false,
'records': false,
});
expect(data.summary.percentage, 0.0);
expect(data.summary.present, 0);
expect(data.records, isEmpty);
});
});
group('Timetable Parsing Tests', () {
test('parses timetable slots with faculty and room', () {
final json = {
'id': 1,
'date': '2026-10-13',
'day': 'Tuesday',
'start_time': '09:00 AM',
'end_time': '10:00 AM',
'subject': {'id': 1, 'name': 'Algorithms'},
'faculty': {'id': 2, 'name': 'Dr. Raman'},
'room': {'id': 3, 'name': 'Hall A'},
};
final slot = TimetableSlot.fromJson(json);
expect(slot.id, 1);
expect(slot.day, 'Tuesday');
expect(slot.startTime, '09:00 AM');
expect(slot.subject?.name, 'Algorithms');
expect(slot.faculty?.name, 'Dr. Raman');
expect(slot.room?.name, 'Hall A');
});
});
group('Exam and Result Parsing Tests', () {
test('parses exam details', () {
final json = {
'id': 5,
'name': 'Semester End Exam',
'state': 'scheduled',
'start_date': '2026-12-01',
'end_date': '2026-12-15',
'program': {'id': 1, 'name': 'B.Tech CS'},
};
final exam = Exam.fromJson(json);
expect(exam.id, 5);
expect(exam.name, 'Semester End Exam');
expect(exam.state, 'scheduled');
expect(exam.startDate, '2026-12-01');
expect(exam.program?.name, 'B.Tech CS');
});
test('parses exam results with breakdown lines', () {
final json = {
'id': 10,
'exam': {'id': 5, 'name': 'Midterm Exam'},
'total_max_marks': 200,
'total_obtained_marks': 175,
'percentage': 87.5,
'grade': 'A',
'status': 'pass',
'published_date': '2026-10-01',
'lines': [
{
'subject': {'id': 1, 'name': 'Mathematics'},
'max_marks': 100,
'pass_marks': 40,
'obtained_marks': 90,
'percentage': 90.0,
'grade': 'A+',
'status': 'pass',
},
{
'subject': {'id': 2, 'name': 'Physics'},
'max_marks': 100,
'pass_marks': 40,
'obtained_marks': 85,
'percentage': 85.0,
'grade': 'A',
'status': 'pass',
}
],
};
final result = ExamResult.fromJson(json);
expect(result.id, 10);
expect(result.exam?.name, 'Midterm Exam');
expect(result.totalMaxMarks, 200.0);
expect(result.totalObtainedMarks, 175.0);
expect(result.percentage, 87.5);
expect(result.grade, 'A');
expect(result.status, 'pass');
expect(result.lines.length, 2);
expect(result.lines[0].subject?.name, 'Mathematics');
expect(result.lines[0].obtainedMarks, 90.0);
expect(result.lines[1].subject?.name, 'Physics');
});
});
group('Dashboard Parsing Tests', () {
test('parses complete dashboard payload', () {
final json = {
'student': {
'id': 4,
'full_name': 'Demo Student',
'program': {'id': 11, 'name': 'B.Tech CS'},
},
'attendance': {
'percentage': 92.0,
'present': 23,
'absent': 2,
'late': 0,
'medical_leave': 0,
'on_duty': 0,
},
'today_timetable': [
{
'id': 1,
'date': '2026-10-13',
'day': 'Tuesday',
'start_time': '09:00 AM',
'end_time': '10:00 AM',
'subject': {'id': 1, 'name': 'Operating Systems'},
'faculty': {'id': 2, 'name': 'Prof. Kumar'},
'room': {'id': 3, 'name': 'Lab 2'},
}
],
'upcoming_exams': [
{
'id': 1,
'name': 'Midterm Assessment',
'state': 'scheduled',
'start_date': '2026-11-01',
}
],
'recent_results': [
{
'id': 1,
'exam': {'id': 1, 'name': 'Unit Test 1'},
'percentage': 88.0,
'grade': 'A',
'status': 'pass',
}
],
'announcements': [
{
'id': 1,
'name': 'College Symposium',
'date': '2026-10-20',
'summary': 'Annual tech symposium registrations open.',
}
],
};
final dashboard = DashboardData.fromJson(json);
expect(dashboard.student?.fullName, 'Demo Student');
expect(dashboard.attendance.percentage, 92.0);
expect(dashboard.todayTimetable.length, 1);
expect(dashboard.todayTimetable[0].subject?.name, 'Operating Systems');
expect(dashboard.upcomingExams.length, 1);
expect(dashboard.upcomingExams[0].name, 'Midterm Assessment');
expect(dashboard.recentResults.length, 1);
expect(dashboard.recentResults[0].status, 'pass');
expect(dashboard.announcements.length, 1);
expect(dashboard.announcements[0].name, 'College Symposium');
});
});
group('User Model Tests', () {
test('parses student and non-student users', () {
final studentUser = User.fromJson({
'id': 1,
'name': 'Demo Student',
'email': 'demo.student',
'role': 'student',
});
expect(studentUser.isStudent, isTrue);
final adminUser = User.fromJson({
'id': 2,
'name': 'Admin User',
'email': 'admin',
'role': 'user',
});
expect(adminUser.isStudent, isFalse);
});
});
}