project initialization
Some checks failed
System Monitoring / Health Checks (push) Has been cancelled
System Monitoring / Performance Monitoring (push) Has been cancelled
System Monitoring / Database Monitoring (push) Has been cancelled
System Monitoring / Cache Monitoring (push) Has been cancelled
System Monitoring / Log Monitoring (push) Has been cancelled
System Monitoring / Resource Monitoring (push) Has been cancelled
System Monitoring / Uptime Monitoring (push) Has been cancelled
System Monitoring / Backup Monitoring (push) Has been cancelled
System Monitoring / Security Monitoring (push) Has been cancelled
System Monitoring / Monitoring Dashboard (push) Has been cancelled
System Monitoring / Alerting (push) Has been cancelled
Security Scanning / Dependency Scanning (push) Has been cancelled
Security Scanning / Code Security Scanning (push) Has been cancelled
Security Scanning / Secrets Scanning (push) Has been cancelled
Security Scanning / Container Security Scanning (push) Has been cancelled
Security Scanning / Compliance Checking (push) Has been cancelled
Security Scanning / Security Dashboard (push) Has been cancelled
Security Scanning / Security Remediation (push) Has been cancelled

This commit is contained in:
2025-10-05 02:37:33 +08:00
parent 2cbb6d5fa1
commit b3fff546e9
226 changed files with 97805 additions and 35 deletions

View File

@@ -0,0 +1,413 @@
"""
Unit tests for Education Models
Tests for education module models:
- Student
- Class
Author: Claude
"""
import pytest
from django.test import TestCase
from django.contrib.auth import get_user_model
from django.utils import timezone
from decimal import Decimal
from datetime import date, time, timedelta
from backend.src.core.models.tenant import Tenant
from backend.src.core.models.user import User
from backend.src.modules.education.models.student import Student
from backend.src.modules.education.models.class_model import Class
User = get_user_model()
class StudentModelTest(TestCase):
"""Test cases for Student model"""
def setUp(self):
self.tenant = Tenant.objects.create(
name='Test Education Center',
schema_name='test_education',
domain='testeducation.com',
business_type='education'
)
self.user = User.objects.create_user(
username='admin',
email='admin@test.com',
password='test123',
tenant=self.tenant,
role='admin'
)
self.student_data = {
'tenant': self.tenant,
'student_id': 'S2024010001',
'first_name': 'Ahmad',
'last_name': 'Bin Ibrahim',
'ic_number': '000101-01-0001',
'gender': 'male',
'date_of_birth': date(2010, 1, 1),
'nationality': 'Malaysian',
'religion': 'Islam',
'race': 'Malay',
'email': 'ahmad.student@test.com',
'phone': '+60123456789',
'address': '123 Student Street',
'city': 'Kuala Lumpur',
'state': 'KUL',
'postal_code': '50000',
'father_name': 'Ibrahim Bin Ali',
'father_phone': '+60123456788',
'father_occupation': 'Engineer',
'mother_name': 'Aminah Binti Ahmad',
'mother_phone': '+60123456787',
'mother_occupation': 'Teacher',
'emergency_contact_name': 'Ibrahim Bin Ali',
'emergency_contact_phone': '+60123456788',
'emergency_contact_relationship': 'Father',
'previous_school': 'SK Test Primary',
'previous_grade': '6A',
'current_grade': 'Form 1',
'stream': 'science',
'admission_date': date.today(),
'graduation_date': None,
'status': 'active',
'medical_conditions': 'None',
'allergies': 'None',
'special_needs': 'None',
'is_active': True,
'created_by': self.user
}
def test_create_student(self):
"""Test creating a new student"""
student = Student.objects.create(**self.student_data)
self.assertEqual(student.tenant, self.tenant)
self.assertEqual(student.student_id, self.student_data['student_id'])
self.assertEqual(student.first_name, self.student_data['first_name'])
self.assertEqual(student.last_name, self.student_data['last_name'])
self.assertEqual(student.ic_number, self.student_data['ic_number'])
self.assertEqual(student.gender, self.student_data['gender'])
self.assertEqual(student.current_grade, self.student_data['current_grade'])
self.assertEqual(student.stream, self.student_data['stream'])
self.assertEqual(student.status, self.student_data['status'])
self.assertTrue(student.is_active)
def test_student_string_representation(self):
"""Test student string representation"""
student = Student.objects.create(**self.student_data)
self.assertEqual(str(student), f"{student.first_name} {student.last_name} ({student.student_id})")
def test_student_full_name(self):
"""Test student full name property"""
student = Student.objects.create(**self.student_data)
self.assertEqual(student.full_name, f"{student.first_name} {student.last_name}")
def test_student_age(self):
"""Test student age calculation"""
student = Student.objects.create(**self.student_data)
# Age should be calculated based on date of birth
today = date.today()
expected_age = today.year - student.date_of_birth.year
if today.month < student.date_of_birth.month or (today.month == student.date_of_birth.month and today.day < student.date_of_birth.day):
expected_age -= 1
self.assertEqual(student.age, expected_age)
def test_student_malaysian_ic_validation(self):
"""Test Malaysian IC number validation"""
# Valid IC number
student = Student.objects.create(**self.student_data)
self.assertEqual(student.ic_number, self.student_data['ic_number'])
# Invalid IC number format
invalid_data = self.student_data.copy()
invalid_data['ic_number'] = '123'
with self.assertRaises(Exception):
Student.objects.create(**invalid_data)
def test_student_gender_choices(self):
"""Test student gender validation"""
invalid_data = self.student_data.copy()
invalid_data['gender'] = 'invalid_gender'
with self.assertRaises(Exception):
Student.objects.create(**invalid_data)
def test_student_grade_validation(self):
"""Test student grade validation"""
# Test valid grades
valid_grades = ['Form 1', 'Form 2', 'Form 3', 'Form 4', 'Form 5', 'Form 6']
for grade in valid_grades:
data = self.student_data.copy()
data['current_grade'] = grade
student = Student.objects.create(**data)
self.assertEqual(student.current_grade, grade)
# Test invalid grade
invalid_data = self.student_data.copy()
invalid_data['current_grade'] = 'Form 7'
with self.assertRaises(Exception):
Student.objects.create(**invalid_data)
def test_student_stream_choices(self):
"""Test student stream validation"""
# Test valid streams
valid_streams = ['science', 'arts', 'commerce', 'technical']
for stream in valid_streams:
data = self.student_data.copy()
data['stream'] = stream
student = Student.objects.create(**data)
self.assertEqual(student.stream, stream)
# Test invalid stream
invalid_data = self.student_data.copy()
invalid_data['stream'] = 'invalid_stream'
with self.assertRaises(Exception):
Student.objects.create(**invalid_data)
def test_student_status_choices(self):
"""Test student status validation"""
# Test valid statuses
valid_statuses = ['active', 'inactive', 'graduated', 'transferred', 'suspended']
for status in valid_statuses:
data = self.student_data.copy()
data['status'] = status
student = Student.objects.create(**data)
self.assertEqual(student.status, status)
# Test invalid status
invalid_data = self.student_data.copy()
invalid_data['status'] = 'invalid_status'
with self.assertRaises(Exception):
Student.objects.create(**invalid_data)
def test_student_parent_information(self):
"""Test student parent information validation"""
student = Student.objects.create(**self.student_data)
self.assertEqual(student.father_name, self.student_data['father_name'])
self.assertEqual(student.mother_name, self.student_data['mother_name'])
self.assertEqual(student.emergency_contact_name, self.student_data['emergency_contact_name'])
def test_student_malaysian_education_info(self):
"""Test Malaysian education specific information"""
student = Student.objects.create(**self.student_data)
self.assertEqual(student.religion, self.student_data['religion'])
self.assertEqual(student.race, self.student_data['race'])
self.assertEqual(student.previous_school, self.student_data['previous_school'])
self.assertEqual(student.previous_grade, self.student_data['previous_grade'])
class ClassModelTest(TestCase):
"""Test cases for Class model"""
def setUp(self):
self.tenant = Tenant.objects.create(
name='Test Education Center',
schema_name='test_education',
domain='testeducation.com',
business_type='education'
)
self.teacher = User.objects.create_user(
username='teacher',
email='teacher@test.com',
password='test123',
tenant=self.tenant,
role='staff'
)
self.student = Student.objects.create(
tenant=self.tenant,
student_id='S2024010001',
first_name='Ahmad',
last_name='Bin Ibrahim',
ic_number='000101-01-0001',
gender='male',
date_of_birth=date(2010, 1, 1),
current_grade='Form 1',
stream='science',
admission_date=date.today(),
status='active'
)
self.class_data = {
'tenant': self.tenant,
'class_name': 'Mathematics Form 1',
'class_code': 'MATH-F1-2024',
'grade': 'Form 1',
'stream': 'science',
'subject': 'Mathematics',
'academic_year': '2024',
'semester': '1',
'teacher': self.teacher,
'room': 'B1-01',
'max_students': 30,
'schedule_days': ['Monday', 'Wednesday', 'Friday'],
'start_time': time(8, 0),
'end_time': time(9, 30),
'start_date': date.today(),
'end_date': date.today() + timedelta(days=180),
'is_active': True,
'syllabus': 'KSSM Mathematics Form 1',
'objectives': 'Complete KSSM Mathematics syllabus',
'assessment_methods': 'Tests, Assignments, Projects',
'created_by': self.teacher
}
def test_create_class(self):
"""Test creating a new class"""
class_obj = Class.objects.create(**self.class_data)
self.assertEqual(class_obj.tenant, self.tenant)
self.assertEqual(class_obj.class_name, self.class_data['class_name'])
self.assertEqual(class_obj.class_code, self.class_data['class_code'])
self.assertEqual(class_obj.grade, self.class_data['grade'])
self.assertEqual(class_obj.stream, self.class_data['stream'])
self.assertEqual(class_obj.subject, self.class_data['subject'])
self.assertEqual(class_obj.teacher, self.teacher)
self.assertEqual(class_obj.max_students, self.class_data['max_students'])
self.assertTrue(class_obj.is_active)
def test_class_string_representation(self):
"""Test class string representation"""
class_obj = Class.objects.create(**self.class_data)
self.assertEqual(str(class_obj), f"{class_obj.class_name} ({class_obj.class_code})")
def test_class_duration(self):
"""Test class duration calculation"""
class_obj = Class.objects.create(**self.class_data)
# Duration should be 90 minutes
self.assertEqual(class_obj.duration, 90)
def test_class_grade_validation(self):
"""Test class grade validation"""
# Test valid grades
valid_grades = ['Form 1', 'Form 2', 'Form 3', 'Form 4', 'Form 5', 'Form 6']
for grade in valid_grades:
data = self.class_data.copy()
data['grade'] = grade
class_obj = Class.objects.create(**data)
self.assertEqual(class_obj.grade, grade)
# Test invalid grade
invalid_data = self.class_data.copy()
invalid_data['grade'] = 'Form 7'
with self.assertRaises(Exception):
Class.objects.create(**invalid_data)
def test_class_stream_choices(self):
"""Test class stream validation"""
# Test valid streams
valid_streams = ['science', 'arts', 'commerce', 'technical']
for stream in valid_streams:
data = self.class_data.copy()
data['stream'] = stream
class_obj = Class.objects.create(**data)
self.assertEqual(class_obj.stream, stream)
# Test invalid stream
invalid_data = self.class_data.copy()
invalid_data['stream'] = 'invalid_stream'
with self.assertRaises(Exception):
Class.objects.create(**invalid_data)
def test_class_semester_choices(self):
"""Test class semester validation"""
# Test valid semesters
valid_semesters = ['1', '2']
for semester in valid_semesters:
data = self.class_data.copy()
data['semester'] = semester
class_obj = Class.objects.create(**data)
self.assertEqual(class_obj.semester, semester)
# Test invalid semester
invalid_data = self.class_data.copy()
invalid_data['semester'] = '3'
with self.assertRaises(Exception):
Class.objects.create(**invalid_data)
def test_class_schedule_validation(self):
"""Test class schedule validation"""
# Valid schedule
class_obj = Class.objects.create(**self.class_data)
self.assertEqual(class_obj.schedule_days, self.class_data['schedule_days'])
self.assertEqual(class_obj.start_time, self.class_data['start_time'])
self.assertEqual(class_obj.end_time, self.class_data['end_time'])
# Invalid time range (end before start)
invalid_data = self.class_data.copy()
invalid_data['start_time'] = time(10, 0)
invalid_data['end_time'] = time(9, 30)
with self.assertRaises(Exception):
Class.objects.create(**invalid_data)
def test_class_student_enrollment(self):
"""Test class student enrollment"""
class_obj = Class.objects.create(**self.class_data)
# Add student to class
class_obj.students.add(self.student)
self.assertIn(self.student, class_obj.students.all())
self.assertEqual(class_obj.students.count(), 1)
def test_class_capacity_validation(self):
"""Test class capacity validation"""
class_obj = Class.objects.create(**self.class_data)
# Test capacity
self.assertEqual(class_obj.max_students, 30)
# Test is_full method
self.assertFalse(class_obj.is_full)
# Add students up to capacity
for i in range(30):
student_data = self.student.__dict__.copy()
student_data['student_id'] = f'S202401{i:04d}'
student_data['first_name'] = f'Student{i}'
student_data.pop('id', None)
student_data.pop('_state', None)
student = Student.objects.create(**student_data)
class_obj.students.add(student)
# Should be full now
self.assertTrue(class_obj.is_full)
def test_class_malaysian_education_features(self):
"""Test Malaysian education specific features"""
class_obj = Class.objects.create(**self.class_data)
self.assertEqual(class_obj.subject, self.class_data['subject'])
self.assertEqual(class_obj.academic_year, self.class_data['academic_year'])
self.assertEqual(class_obj.syllabus, self.class_data['syllabus'])
def test_class_date_validation(self):
"""Test class date validation"""
# Valid date range
class_obj = Class.objects.create(**self.class_data)
self.assertLessEqual(class_obj.start_date, class_obj.end_date)
# Invalid date range (end before start)
invalid_data = self.class_data.copy()
invalid_data['start_date'] = date.today()
invalid_data['end_date'] = date.today() - timedelta(days=1)
with self.assertRaises(Exception):
Class.objects.create(**invalid_data)