Files
notytex/tests/test_routes_assessments.py

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)