diff --git a/backend/bookings/emailing.py b/backend/bookings/emailing.py index 5de1ca8..112ffb8 100644 --- a/backend/bookings/emailing.py +++ b/backend/bookings/emailing.py @@ -50,11 +50,14 @@ def send_confirmation_email(*, reservation, raw_confirmation_token): fail_silently=False, ) except Exception: - _log_confirmation_link_for_local_debug( - reservation=reservation, - confirmation_link=confirmation_link, - reason="email send failure fallback", - ) + if settings.LOG_RESERVATION_CONFIRMATION_URLS: + logger.warning( + "Failed to send confirmation email for reservation %s in local/debug mode.", + reservation.id, + exc_info=True, + ) + return + logger.exception( "Failed to send confirmation email for reservation %s.", reservation.id, diff --git a/backend/bookings/test_services.py b/backend/bookings/test_services.py index 9aa0f82..aa0f0a4 100644 --- a/backend/bookings/test_services.py +++ b/backend/bookings/test_services.py @@ -156,7 +156,7 @@ class BookingServiceTests(TestCase): SITE_BASE_URL="https://tickets.azionelab.example", ) @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, mocked_send_mail, ): @@ -171,16 +171,50 @@ class BookingServiceTests(TestCase): self.assertEqual(result.reservation.status, Reservation.Status.PENDING) mocked_send_mail.assert_called_once() - self.assertTrue( - any( - ( - "Local reservation confirmation link for manual testing " - "(email send failure fallback)" - ) in log_entry - and result.raw_confirmation_token in log_entry - for log_entry in captured_logs.output - ) + confirmation_log_index = next( + index + for index, log_entry in enumerate(captured_logs.output) + if ( + "Local reservation confirmation link for manual testing " + "(email send attempt)" + ) 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 + ), + 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): reservation = self.create_reservation()