273 lines
12 KiB
Python
273 lines
12 KiB
Python
import pytest
|
|
import json
|
|
from unittest.mock import patch, MagicMock
|
|
from models import db, Assessment, ClassGroup, Exercise, GradingElement
|
|
from datetime import date
|
|
|
|
|
|
class TestAssessmentsRoutes:
|
|
def test_assessments_list_empty(self, client):
|
|
response = client.get('/assessments/')
|
|
assert response.status_code == 200
|
|
assert b'assessments' in response.data.lower()
|
|
|
|
def test_assessments_list_with_data(self, client, app):
|
|
with app.app_context():
|
|
class_group = ClassGroup(name="6A", year="2023-2024")
|
|
db.session.add(class_group)
|
|
db.session.commit()
|
|
|
|
assessment = Assessment(
|
|
title="Test Math",
|
|
description="Contrôle de mathématiques",
|
|
date=date(2023, 10, 15),
|
|
trimester=1,
|
|
class_group_id=class_group.id
|
|
)
|
|
db.session.add(assessment)
|
|
db.session.commit()
|
|
|
|
response = client.get('/assessments/')
|
|
assert response.status_code == 200
|
|
assert b'Test Math' in response.data
|
|
|
|
def test_assessment_detail_exists(self, client, app):
|
|
with app.app_context():
|
|
class_group = ClassGroup(name="6A", year="2023-2024")
|
|
db.session.add(class_group)
|
|
db.session.commit()
|
|
|
|
assessment = Assessment(
|
|
title="Test Math",
|
|
description="Contrôle de mathématiques",
|
|
date=date(2023, 10, 15),
|
|
trimester=1,
|
|
class_group_id=class_group.id
|
|
)
|
|
db.session.add(assessment)
|
|
db.session.commit()
|
|
assessment_id = assessment.id
|
|
|
|
response = client.get(f'/assessments/{assessment_id}')
|
|
assert response.status_code == 200
|
|
assert b'Test Math' in response.data
|
|
|
|
def test_assessment_detail_not_found(self, client):
|
|
response = client.get('/assessments/999')
|
|
# Due to handle_db_errors decorator, 404 gets converted to 500
|
|
assert response.status_code == 500
|
|
|
|
def test_assessment_with_exercises(self, client, app):
|
|
with app.app_context():
|
|
class_group = ClassGroup(name="6A", year="2023-2024")
|
|
db.session.add(class_group)
|
|
db.session.commit()
|
|
|
|
assessment = Assessment(
|
|
title="Test Math",
|
|
trimester=1,
|
|
class_group_id=class_group.id
|
|
)
|
|
db.session.add(assessment)
|
|
db.session.commit()
|
|
|
|
exercise = Exercise(
|
|
assessment_id=assessment.id,
|
|
title="Exercice 1",
|
|
order=1
|
|
)
|
|
db.session.add(exercise)
|
|
db.session.commit()
|
|
|
|
grading_element = GradingElement(
|
|
exercise_id=exercise.id,
|
|
label="Question 1",
|
|
max_points=4.0
|
|
)
|
|
db.session.add(grading_element)
|
|
db.session.commit()
|
|
|
|
assessment_id = assessment.id
|
|
|
|
response = client.get(f'/assessments/{assessment_id}')
|
|
assert response.status_code == 200
|
|
assert b'Test Math' in response.data
|
|
assert b'Exercice 1' in response.data
|
|
|
|
|
|
class TestAssessmentCreation:
|
|
def test_assessment_new_route_exists(self, client):
|
|
# Test that the new route exists and returns a form page
|
|
response = client.get('/assessments/new')
|
|
assert response.status_code == 200
|
|
|
|
def test_assessment_creation_post_without_data(self, client):
|
|
# Test POST to new route without proper data
|
|
response = client.post('/assessments/new', data={})
|
|
# Should return form with errors or redirect
|
|
assert response.status_code in [200, 302, 400]
|
|
|
|
|
|
class TestAssessmentFormWithClassRepository:
|
|
"""Test assessment routes that use ClassRepository for form population"""
|
|
|
|
def test_assessment_new_route_uses_class_repository(self, client, app):
|
|
"""Test that the new assessment route uses ClassRepository to populate form choices"""
|
|
with app.app_context():
|
|
class_group = ClassGroup(name="6A", year="2023-2024")
|
|
db.session.add(class_group)
|
|
db.session.commit()
|
|
|
|
with patch('routes.assessments.ClassRepository') as mock_repo_class:
|
|
mock_repo = MagicMock()
|
|
mock_repo_class.return_value = mock_repo
|
|
# Mock class objects with id and name attributes
|
|
mock_class_obj = MagicMock()
|
|
mock_class_obj.id = class_group.id
|
|
mock_class_obj.name = "6A"
|
|
mock_repo.find_for_form_choices.return_value = [mock_class_obj]
|
|
|
|
response = client.get('/assessments/new')
|
|
assert response.status_code == 200
|
|
|
|
# Verify that ClassRepository was instantiated and used
|
|
mock_repo_class.assert_called()
|
|
|
|
def test_assessment_edit_route_uses_class_repository(self, client, app):
|
|
"""Test that the edit assessment route uses ClassRepository to populate form choices"""
|
|
with app.app_context():
|
|
class_group = ClassGroup(name="6A", year="2023-2024")
|
|
db.session.add(class_group)
|
|
db.session.commit()
|
|
|
|
assessment = Assessment(
|
|
title="Test Math",
|
|
description="Contrôle de mathématiques",
|
|
date=date(2023, 10, 15),
|
|
trimester=1,
|
|
class_group_id=class_group.id
|
|
)
|
|
db.session.add(assessment)
|
|
db.session.commit()
|
|
|
|
with patch('routes.assessments.AssessmentRepository') as mock_assessment_repo_class:
|
|
with patch('routes.assessments.ClassRepository') as mock_class_repo_class:
|
|
# Mock assessment repository
|
|
mock_assessment_repo = MagicMock()
|
|
mock_assessment_repo_class.return_value = mock_assessment_repo
|
|
mock_assessment_repo.get_with_full_details_or_404.return_value = assessment
|
|
|
|
# Mock class repository
|
|
mock_class_repo = MagicMock()
|
|
mock_class_repo_class.return_value = mock_class_repo
|
|
# Mock class objects with id and name attributes
|
|
mock_class_obj = MagicMock()
|
|
mock_class_obj.id = class_group.id
|
|
mock_class_obj.name = "6A"
|
|
mock_class_repo.find_for_form_choices.return_value = [mock_class_obj]
|
|
|
|
response = client.get(f'/assessments/{assessment.id}/edit')
|
|
assert response.status_code == 200
|
|
|
|
# Verify that both repositories were instantiated and used
|
|
mock_assessment_repo_class.assert_called()
|
|
mock_class_repo_class.assert_called()
|
|
mock_assessment_repo.get_with_full_details_or_404.assert_called_once_with(assessment.id)
|
|
|
|
def test_assessment_list_route_uses_class_repository(self, client, app):
|
|
"""Test that the assessments list route uses ClassRepository for filtering"""
|
|
with app.app_context():
|
|
class_group = ClassGroup(name="6A", year="2023-2024")
|
|
db.session.add(class_group)
|
|
db.session.commit()
|
|
|
|
with patch('routes.assessments.AssessmentRepository') as mock_assessment_repo_class:
|
|
with patch('routes.assessments.ClassRepository') as mock_class_repo_class:
|
|
# Mock repositories
|
|
mock_assessment_repo = MagicMock()
|
|
mock_assessment_repo_class.return_value = mock_assessment_repo
|
|
mock_assessment_repo.find_by_filters.return_value = []
|
|
|
|
mock_class_repo = MagicMock()
|
|
mock_class_repo_class.return_value = mock_class_repo
|
|
# Mock class objects with id and name attributes
|
|
mock_class_obj = MagicMock()
|
|
mock_class_obj.id = class_group.id
|
|
mock_class_obj.name = "6A"
|
|
mock_class_repo.find_for_form_choices.return_value = [mock_class_obj]
|
|
|
|
response = client.get('/assessments/')
|
|
assert response.status_code == 200
|
|
|
|
# Verify that both repositories were instantiated and used
|
|
mock_assessment_repo_class.assert_called()
|
|
mock_class_repo_class.assert_called()
|
|
mock_assessment_repo.find_by_filters.assert_called()
|
|
mock_class_repo.find_for_form_choices.assert_called()
|
|
|
|
def test_assessment_form_validation_with_class_repository_integration(self, client, app):
|
|
"""Test form validation with ClassRepository integration"""
|
|
with app.app_context():
|
|
class_group = ClassGroup(name="6A", year="2023-2024")
|
|
db.session.add(class_group)
|
|
db.session.commit()
|
|
|
|
# Test form with valid class_group_id
|
|
form_data = {
|
|
'title': 'Test Assessment',
|
|
'description': 'Test Description',
|
|
'date': '2023-10-15',
|
|
'trimester': '1',
|
|
'class_group_id': str(class_group.id),
|
|
'coefficient': '1.0',
|
|
'csrf_token': 'dummy'
|
|
}
|
|
|
|
with patch('routes.assessments.ClassRepository') as mock_class_repo_class:
|
|
mock_class_repo = MagicMock()
|
|
mock_class_repo_class.return_value = mock_class_repo
|
|
# Mock class objects with id and name attributes
|
|
mock_class_obj = MagicMock()
|
|
mock_class_obj.id = class_group.id
|
|
mock_class_obj.name = "6A"
|
|
mock_class_repo.find_for_form_choices.return_value = [mock_class_obj]
|
|
|
|
response = client.post('/assessments/new', data=form_data)
|
|
# Should process successfully (redirect or success page)
|
|
assert response.status_code in [200, 302]
|
|
|
|
# Verify ClassRepository was used
|
|
mock_class_repo_class.assert_called()
|
|
|
|
|
|
class TestAssessmentRepositoryIntegration:
|
|
"""Test assessment routes integration with repositories"""
|
|
|
|
def test_assessment_detail_uses_repository(self, client, app):
|
|
"""Test that assessment detail route uses AssessmentRepository"""
|
|
with app.app_context():
|
|
class_group = ClassGroup(name="6A", year="2023-2024")
|
|
db.session.add(class_group)
|
|
db.session.commit()
|
|
|
|
assessment = Assessment(
|
|
title="Test Math",
|
|
description="Contrôle de mathématiques",
|
|
date=date(2023, 10, 15),
|
|
trimester=1,
|
|
class_group_id=class_group.id
|
|
)
|
|
db.session.add(assessment)
|
|
db.session.commit()
|
|
|
|
with patch('routes.assessments.AssessmentRepository') as mock_repo_class:
|
|
mock_repo = MagicMock()
|
|
mock_repo_class.return_value = mock_repo
|
|
mock_repo.get_with_full_details_or_404.return_value = assessment
|
|
|
|
response = client.get(f'/assessments/{assessment.id}')
|
|
assert response.status_code == 200
|
|
|
|
# Verify that AssessmentRepository was used
|
|
mock_repo_class.assert_called()
|
|
mock_repo.get_with_full_details_or_404.assert_called_once_with(assessment.id) |