From 744a97f58d996b2a1415fcb63b499349f4d1837f Mon Sep 17 00:00:00 2001 From: sepehr Date: Sun, 31 May 2026 23:25:20 +0200 Subject: [PATCH] fix: import datetime in email_service.py to fix NameError, add Stripe emails unit tests --- services/email_service.py | 1 + tests/test_stripe_emails.py | 125 ++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 tests/test_stripe_emails.py diff --git a/services/email_service.py b/services/email_service.py index 67ed0e3..22b3544 100644 --- a/services/email_service.py +++ b/services/email_service.py @@ -8,6 +8,7 @@ Configuration is resolved from settings JSON file, then env vars. import os import logging import smtplib +from datetime import datetime from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from typing import Optional diff --git a/tests/test_stripe_emails.py b/tests/test_stripe_emails.py new file mode 100644 index 0000000..d8713ff --- /dev/null +++ b/tests/test_stripe_emails.py @@ -0,0 +1,125 @@ +""" +Tests for Stripe transactional emails and template rendering. +""" + +import pytest +from unittest.mock import patch, MagicMock +from services.email_service import send_subscription_email_async + + +@pytest.mark.asyncio +async def test_send_subscription_email_activated(): + """Test send_subscription_email_async for activated event renders and calls send_email_async""" + with patch("services.email_service.send_email_async") as mock_send: + mock_send.return_value = True + + result = await send_subscription_email_async( + to_email="customer@example.com", + user_name="Jean Dupont", + event_type="activated", + details={"plan_name": "pro", "ends_at": "15/06/2026"} + ) + + assert result is True + mock_send.assert_called_once() + args, kwargs = mock_send.call_args + to_email, subject, body = args + + assert to_email == "customer@example.com" + assert "activé" in subject or "active" in subject + assert "Jean Dupont" in body + assert "Pro" in body + assert "15/06/2026" in body + + +@pytest.mark.asyncio +async def test_send_subscription_email_cancelled(): + """Test send_subscription_email_async for cancelled event renders correctly""" + with patch("services.email_service.send_email_async") as mock_send: + mock_send.return_value = True + + result = await send_subscription_email_async( + to_email="customer@example.com", + user_name="Jean Dupont", + event_type="cancelled", + details={"ends_at": "15/06/2026"} + ) + + assert result is True + mock_send.assert_called_once() + args, kwargs = mock_send.call_args + _, subject, body = args + + assert "annulation" in subject.lower() + assert "Jean Dupont" in body + assert "15/06/2026" in body + assert "Aucun autre prélèvement" in body + + +@pytest.mark.asyncio +async def test_send_subscription_email_ended(): + """Test send_subscription_email_async for ended event renders correctly""" + with patch("services.email_service.send_email_async") as mock_send: + mock_send.return_value = True + + result = await send_subscription_email_async( + to_email="customer@example.com", + user_name="Jean Dupont", + event_type="ended", + details={} + ) + + assert result is True + mock_send.assert_called_once() + args, kwargs = mock_send.call_args + _, subject, body = args + + assert "expiré" in subject.lower() + assert "Jean Dupont" in body + assert "Gratuit" in body + + +@pytest.mark.asyncio +async def test_send_subscription_email_payment_failed(): + """Test send_subscription_email_async for payment_failed event renders correctly""" + with patch("services.email_service.send_email_async") as mock_send: + mock_send.return_value = True + + result = await send_subscription_email_async( + to_email="customer@example.com", + user_name="Jean Dupont", + event_type="payment_failed", + details={} + ) + + assert result is True + mock_send.assert_called_once() + args, kwargs = mock_send.call_args + _, subject, body = args + + assert "échec" in subject.lower() or "echec" in subject.lower() + assert "Jean Dupont" in body + assert "coordonnées" in body or "coordonnees" in body + + +@pytest.mark.asyncio +async def test_send_subscription_email_credits_purchased(): + """Test send_subscription_email_async for credits_purchased event renders correctly""" + with patch("services.email_service.send_email_async") as mock_send: + mock_send.return_value = True + + result = await send_subscription_email_async( + to_email="customer@example.com", + user_name="Jean Dupont", + event_type="credits_purchased", + details={"credits": 50} + ) + + assert result is True + mock_send.assert_called_once() + args, kwargs = mock_send.call_args + _, subject, body = args + + assert "crédits" in subject.lower() or "credits" in subject.lower() + assert "Jean Dupont" in body + assert "+50" in body