import pytest import json import os import sys from core.logging import StructuredFormatter, log_business_event import logging class TestStructuredLogging: """Tests pour le logging structuré.""" def test_structured_formatter(self): """Test du formateur structuré.""" formatter = StructuredFormatter() # Créer un enregistrement de log record = logging.LogRecord( name='test_logger', level=logging.INFO, pathname='/test/path.py', lineno=42, msg='Test message', args=(), exc_info=None ) # Formater l'enregistrement formatted = formatter.format(record) # Vérifier que c'est du JSON valide log_data = json.loads(formatted) # Vérifier les champs de base assert 'timestamp' in log_data assert log_data['level'] == 'INFO' assert log_data['logger'] == 'test_logger' assert log_data['message'] == 'Test message' assert log_data['module'] == 'path' assert log_data['line'] == 42 def test_structured_formatter_with_exception(self): """Test du formateur avec exception.""" formatter = StructuredFormatter() try: raise ValueError("Test exception") except ValueError: exc_info = sys.exc_info() # Créer un enregistrement avec exception record = logging.LogRecord( name='test_logger', level=logging.ERROR, pathname='/test/path.py', lineno=42, msg='Error occurred', args=(), exc_info=exc_info ) formatted = formatter.format(record) log_data = json.loads(formatted) # Vérifier que l'exception est incluse assert 'exception' in log_data assert log_data['exception']['type'] == 'ValueError' assert 'Test exception' in log_data['exception']['message'] assert 'traceback' in log_data['exception'] def test_structured_formatter_with_extra_data(self): """Test du formateur avec données supplémentaires.""" formatter = StructuredFormatter() record = logging.LogRecord( name='test_logger', level=logging.INFO, pathname='/test/path.py', lineno=42, msg='Test message', args=(), exc_info=None ) # Ajouter des données supplémentaires record.extra_data = {'user_id': 123, 'action': 'create_assessment'} formatted = formatter.format(record) log_data = json.loads(formatted) # Vérifier que les données supplémentaires sont incluses assert 'extra' in log_data assert log_data['extra']['user_id'] == 123 assert log_data['extra']['action'] == 'create_assessment' def test_log_business_event(self, caplog): """Test de la fonction log_business_event.""" with caplog.at_level(logging.INFO): log_business_event('assessment_created', { 'assessment_id': 123, 'title': 'Test Assessment', 'user': 'teacher1' }) # Vérifier qu'un log a été créé assert len(caplog.records) == 1 record = caplog.records[0] assert record.levelname == 'INFO' assert 'Événement métier : assessment_created' in record.message assert hasattr(record, 'extra_data') assert record.extra_data['event_type'] == 'assessment_created' assert record.extra_data['details']['assessment_id'] == 123 def test_logging_setup_creates_logs_directory(self, app, tmp_path): """Test que setup_logging crée le dossier logs.""" from core.logging import setup_logging # Changer temporairement le répertoire de travail old_cwd = os.getcwd() try: os.chdir(tmp_path) with app.app_context(): setup_logging(app) # Vérifier que le dossier logs a été créé assert (tmp_path / 'logs').exists() finally: os.chdir(old_cwd)