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)