fix: log confirmation link before email delivery

This commit is contained in:
bisco
2026-04-30 01:18:04 +02:00
parent ff9f9f2716
commit 8a47740049
2 changed files with 52 additions and 15 deletions

View File

@@ -50,11 +50,14 @@ def send_confirmation_email(*, reservation, raw_confirmation_token):
fail_silently=False, fail_silently=False,
) )
except Exception: except Exception:
_log_confirmation_link_for_local_debug( if settings.LOG_RESERVATION_CONFIRMATION_URLS:
reservation=reservation, logger.warning(
confirmation_link=confirmation_link, "Failed to send confirmation email for reservation %s in local/debug mode.",
reason="email send failure fallback", reservation.id,
exc_info=True,
) )
return
logger.exception( logger.exception(
"Failed to send confirmation email for reservation %s.", "Failed to send confirmation email for reservation %s.",
reservation.id, reservation.id,

View File

@@ -156,7 +156,7 @@ class BookingServiceTests(TestCase):
SITE_BASE_URL="https://tickets.azionelab.example", SITE_BASE_URL="https://tickets.azionelab.example",
) )
@patch("bookings.emailing.send_mail", side_effect=RuntimeError("SMTP down")) @patch("bookings.emailing.send_mail", side_effect=RuntimeError("SMTP down"))
def test_create_pending_reservation_logs_confirmation_link_on_email_failure_in_local_mode( def test_create_pending_reservation_logs_confirmation_link_before_email_failure_in_local_mode(
self, self,
mocked_send_mail, mocked_send_mail,
): ):
@@ -171,16 +171,50 @@ class BookingServiceTests(TestCase):
self.assertEqual(result.reservation.status, Reservation.Status.PENDING) self.assertEqual(result.reservation.status, Reservation.Status.PENDING)
mocked_send_mail.assert_called_once() mocked_send_mail.assert_called_once()
self.assertTrue( confirmation_log_index = next(
any( index
( for index, log_entry in enumerate(captured_logs.output)
if (
"Local reservation confirmation link for manual testing " "Local reservation confirmation link for manual testing "
"(email send failure fallback)" "(email send attempt)"
) in log_entry ) in log_entry
and result.raw_confirmation_token in log_entry and result.raw_confirmation_token in log_entry
)
failure_log_index = next(
index
for index, log_entry in enumerate(captured_logs.output)
if "Failed to send confirmation email for reservation" in log_entry
)
self.assertLess(confirmation_log_index, failure_log_index)
self.assertEqual(
sum(
result.raw_confirmation_token in log_entry
for log_entry in captured_logs.output for log_entry in captured_logs.output
),
1,
) )
@override_settings(
LOG_RESERVATION_CONFIRMATION_URLS=False,
SITE_BASE_URL="https://tickets.azionelab.example",
) )
@patch("bookings.emailing.send_mail")
def test_create_pending_reservation_does_not_log_confirmation_link_outside_local_mode(
self,
mocked_send_mail,
):
with self.assertNoLogs("bookings.emailing", level="INFO"):
with self.captureOnCommitCallbacks(execute=True):
result = create_pending_reservation(
performance_id=self.performance.id,
name="Maria Rossi",
email="maria@example.com",
party_size=1,
)
self.assertEqual(result.reservation.status, Reservation.Status.PENDING)
mocked_send_mail.assert_called_once()
def test_generate_confirmation_token_returns_raw_token_once(self): def test_generate_confirmation_token_returns_raw_token_once(self):
reservation = self.create_reservation() reservation = self.create_reservation()