From 80f7926985061b9c86abd57dc73917d67e5160c9 Mon Sep 17 00:00:00 2001 From: Phil Skentelbery Date: Mon, 22 Dec 2025 18:16:48 -0700 Subject: [PATCH] fix: use print instead of logger for dev mode email output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Logger.info wasn't visible in gunicorn container logs. Using print with flush=True ensures magic link URLs are visible in container logs for QA testing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/services/email.py | 18 ++++++------- tests/unit/test_email_service.py | 43 ++++++++++++++++---------------- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/services/email.py b/src/services/email.py index d89ff50..539ddcc 100644 --- a/src/services/email.py +++ b/src/services/email.py @@ -61,13 +61,13 @@ class EmailService: Exception: If email sending fails """ if self.dev_mode: - # In dev mode, just log the email - logger.info("=" * 80) - logger.info("DEV MODE: Email not sent") - logger.info(f"To: {to}") - logger.info(f"Subject: {subject}") - logger.info(f"Body preview: {html_body[:200]}...") - logger.info("=" * 80) + # In dev mode, print email details to stdout for QA testing + print("=" * 80) + print("DEV MODE: Email not sent") + print(f"To: {to}") + print(f"Subject: {subject}") + print(f"Body preview: {html_body[:200]}...") + print("=" * 80, flush=True) # Return a mock success response return {"id": f"dev-mode-{os.urandom(8).hex()}"} @@ -99,7 +99,7 @@ class EmailService: Response from email service """ if self.dev_mode: - logger.info(f"DEV MODE: Magic link URL: {magic_link_url}") + print(f"DEV MODE: Magic link URL: {magic_link_url}", flush=True) subject = f"Access your {exchange_name} Secret Santa" html_body = f""" @@ -143,7 +143,7 @@ class EmailService: Response from email service """ if self.dev_mode: - logger.info(f"DEV MODE: Magic link URL: {magic_link_url}") + print(f"DEV MODE: Magic link URL: {magic_link_url}", flush=True) subject = f"Welcome to {exchange_name}!" diff --git a/tests/unit/test_email_service.py b/tests/unit/test_email_service.py index 7c0d263..d5cf62f 100644 --- a/tests/unit/test_email_service.py +++ b/tests/unit/test_email_service.py @@ -1,6 +1,5 @@ """Tests for email service.""" -import logging from unittest.mock import patch import pytest @@ -89,26 +88,26 @@ class TestEmailService: assert call_args["from"] == "custom@example.com" @patch("resend.Emails.send") - def test_send_email_in_dev_mode_logs_instead(self, mock_send, app, caplog): - """Test that email sending logs in dev mode instead of actually sending.""" + def test_send_email_in_dev_mode_logs_instead(self, mock_send, app, capsys): + """Test that email sending prints in dev mode instead of actually sending.""" with app.app_context(): app.config["FLASK_ENV"] = "development" service = EmailService() - with caplog.at_level(logging.INFO): - result = service.send_email( - to="test@example.com", - subject="Test Subject", - html_body="

Test body

", - ) + result = service.send_email( + to="test@example.com", + subject="Test Subject", + html_body="

Test body

", + ) # Should not actually send email mock_send.assert_not_called() - # Should log the email details - assert "DEV MODE: Email not sent" in caplog.text - assert "test@example.com" in caplog.text - assert "Test Subject" in caplog.text + # Should print the email details + captured = capsys.readouterr() + assert "DEV MODE: Email not sent" in captured.out + assert "test@example.com" in captured.out + assert "Test Subject" in captured.out # Should return a mock success response assert result["id"].startswith("dev-mode-") @@ -182,20 +181,20 @@ class TestEmailService: assert "$25-50" in call_args["html_body"] assert "2025-12-20" in call_args["html_body"] - def test_dev_mode_logs_magic_link_url(self, app, caplog): - """Test that magic link URLs are logged in dev mode.""" + def test_dev_mode_logs_magic_link_url(self, app, capsys): + """Test that magic link URLs are printed in dev mode.""" with app.app_context(): app.config["FLASK_ENV"] = "development" service = EmailService() - with caplog.at_level(logging.INFO): - service.send_magic_link( - to="test@example.com", - magic_link_url="https://example.com/magic/abc123", - exchange_name="Secret Santa 2025", - ) + service.send_magic_link( + to="test@example.com", + magic_link_url="https://example.com/magic/abc123", + exchange_name="Secret Santa 2025", + ) + captured = capsys.readouterr() assert ( "DEV MODE: Magic link URL: https://example.com/magic/abc123" - in caplog.text + in captured.out )