✨ Changements majeurs: - Suppression complète du code Flask legacy - Migration backend FastAPI vers racine /backend - Migration frontend Vue.js vers racine /frontend - Suppression de notytex-v2/ (code monté à la racine) ✅ Validations: - Backend démarre correctement (port 8000) - API /api/v2/health répond healthy - 99/99 tests unitaires passent - Frontend configuré avec proxy Vite 📝 Documentation: - README.md réécrit pour v2 - Instructions de démarrage mises à jour - .gitignore adapté pour backend/frontend/ 🎯 Architecture finale: notytex/ ├── backend/ # FastAPI + SQLAlchemy + Pydantic ├── frontend/ # Vue 3 + Vite + TailwindCSS ├── docs/ # Documentation └── school_management.db # Base de données (inchangée) Jalon 6 complété: Application v2 prête pour utilisation!
201 lines
6.4 KiB
Python
201 lines
6.4 KiB
Python
"""
|
|
Tests unitaires pour le service d'email.
|
|
"""
|
|
|
|
import pytest
|
|
from infrastructure.external.email_service import EmailService, SMTPConfig
|
|
|
|
|
|
class TestSMTPConfig:
|
|
"""Tests pour la configuration SMTP."""
|
|
|
|
def test_valid_localhost_config(self):
|
|
"""Configuration locale valide sans authentification."""
|
|
config = SMTPConfig(
|
|
host="localhost",
|
|
port=1025,
|
|
username="",
|
|
password="",
|
|
use_tls=False,
|
|
from_name="Test",
|
|
from_address="test@example.com"
|
|
)
|
|
assert config.is_valid() is True
|
|
|
|
def test_valid_production_config(self):
|
|
"""Configuration production valide avec authentification."""
|
|
config = SMTPConfig(
|
|
host="smtp.gmail.com",
|
|
port=587,
|
|
username="user@gmail.com",
|
|
password="password123",
|
|
use_tls=True,
|
|
from_name="Notytex",
|
|
from_address="notytex@school.com"
|
|
)
|
|
assert config.is_valid() is True
|
|
|
|
def test_invalid_config_missing_host(self):
|
|
"""Configuration invalide sans host."""
|
|
config = SMTPConfig(
|
|
host="",
|
|
port=587,
|
|
username="user",
|
|
password="pass",
|
|
use_tls=True,
|
|
from_name="Test",
|
|
from_address="test@example.com"
|
|
)
|
|
assert config.is_valid() is False
|
|
|
|
def test_invalid_config_missing_from_address(self):
|
|
"""Configuration invalide sans adresse expéditeur."""
|
|
config = SMTPConfig(
|
|
host="smtp.gmail.com",
|
|
port=587,
|
|
username="user",
|
|
password="pass",
|
|
use_tls=True,
|
|
from_name="Test",
|
|
from_address=""
|
|
)
|
|
assert config.is_valid() is False
|
|
|
|
def test_invalid_production_config_no_auth(self):
|
|
"""Configuration production invalide sans authentification."""
|
|
config = SMTPConfig(
|
|
host="smtp.gmail.com",
|
|
port=587,
|
|
username="",
|
|
password="",
|
|
use_tls=True,
|
|
from_name="Test",
|
|
from_address="test@example.com"
|
|
)
|
|
assert config.is_valid() is False
|
|
|
|
|
|
class TestEmailService:
|
|
"""Tests pour le service d'email."""
|
|
|
|
def test_service_not_configured(self):
|
|
"""Service non configuré."""
|
|
service = EmailService()
|
|
assert service.is_configured() is False
|
|
|
|
def test_service_with_config(self):
|
|
"""Service avec configuration valide."""
|
|
config = SMTPConfig(
|
|
host="localhost",
|
|
port=1025,
|
|
username="",
|
|
password="",
|
|
use_tls=False,
|
|
from_name="Test",
|
|
from_address="test@example.com"
|
|
)
|
|
service = EmailService(config)
|
|
assert service.is_configured() is True
|
|
|
|
def test_set_config(self):
|
|
"""Définir la configuration après initialisation."""
|
|
service = EmailService()
|
|
assert service.is_configured() is False
|
|
|
|
config = SMTPConfig(
|
|
host="localhost",
|
|
port=1025,
|
|
username="",
|
|
password="",
|
|
use_tls=False,
|
|
from_name="Test",
|
|
from_address="test@example.com"
|
|
)
|
|
service.set_config(config)
|
|
assert service.is_configured() is True
|
|
|
|
def test_send_email_not_configured(self):
|
|
"""Envoi d'email échoue si non configuré."""
|
|
service = EmailService()
|
|
result = service.send_email(
|
|
to_emails=["test@example.com"],
|
|
subject="Test",
|
|
html_body="<p>Test</p>"
|
|
)
|
|
assert result['success'] is False
|
|
assert 'incomplète' in result['error']
|
|
|
|
def test_from_database_config(self):
|
|
"""Création du service depuis la configuration DB."""
|
|
db_config = {
|
|
'email.smtp_host': 'localhost',
|
|
'email.smtp_port': '1025',
|
|
'email.username': '',
|
|
'email.password': '',
|
|
'email.use_tls': 'false',
|
|
'email.from_name': 'Notytex',
|
|
'email.from_address': 'test@example.com'
|
|
}
|
|
|
|
service = EmailService.from_database_config(db_config)
|
|
assert service.is_configured() is True
|
|
assert service.config.host == 'localhost'
|
|
assert service.config.port == 1025
|
|
assert service.config.from_name == 'Notytex'
|
|
|
|
def test_from_database_config_defaults(self):
|
|
"""Valeurs par défaut pour la configuration DB."""
|
|
db_config = {}
|
|
|
|
service = EmailService.from_database_config(db_config)
|
|
assert service.config.port == 587
|
|
assert service.config.use_tls is True
|
|
assert service.config.from_name == 'Notytex'
|
|
|
|
|
|
class TestEmailValidation:
|
|
"""Tests pour la validation d'adresses email."""
|
|
|
|
def test_validate_valid_emails(self):
|
|
"""Validation d'adresses valides."""
|
|
emails = ["test@example.com", "user.name@domain.org", "a@b.co"]
|
|
result = EmailService.validate_email_addresses(emails)
|
|
|
|
assert result['valid_count'] == 3
|
|
assert result['invalid_count'] == 0
|
|
assert len(result['valid']) == 3
|
|
|
|
def test_validate_invalid_emails(self):
|
|
"""Validation d'adresses invalides."""
|
|
emails = ["invalid", "no-at-sign", "@nodomain", "space @test.com"]
|
|
result = EmailService.validate_email_addresses(emails)
|
|
|
|
assert result['valid_count'] == 0
|
|
assert result['invalid_count'] == 4
|
|
|
|
def test_validate_mixed_emails(self):
|
|
"""Validation d'un mélange d'adresses."""
|
|
emails = ["valid@test.com", "invalid", "another@valid.org"]
|
|
result = EmailService.validate_email_addresses(emails)
|
|
|
|
assert result['valid_count'] == 2
|
|
assert result['invalid_count'] == 1
|
|
assert "valid@test.com" in result['valid']
|
|
assert "invalid" in result['invalid']
|
|
|
|
def test_validate_empty_emails(self):
|
|
"""Validation d'une liste vide."""
|
|
result = EmailService.validate_email_addresses([])
|
|
|
|
assert result['valid_count'] == 0
|
|
assert result['invalid_count'] == 0
|
|
|
|
def test_validate_whitespace_emails(self):
|
|
"""Les espaces sont supprimés lors de la validation."""
|
|
emails = [" test@example.com ", " user@domain.org"]
|
|
result = EmailService.validate_email_addresses(emails)
|
|
|
|
assert result['valid_count'] == 2
|
|
assert "test@example.com" in result['valid']
|
|
assert "user@domain.org" in result['valid']
|