"""Unit tests for booking_mail.py (#18): sender-address resolution and the skip-if-not-an-email guard, per the acceptance criterion that customer_contact (free-text "E-Mail oder Telefon") may not actually be an email address. """ from datetime import datetime, timedelta, timezone import pytest import booking_mail from app import app as flask_app @pytest.mark.parametrize("contact,expected", [ ("alice@example.com", True), ("Alice@Example.COM", True), ("+49 151 2345678", False), ("0151-2345678", False), ("not-an-email", False), ("", False), (None, False), ]) def test_looks_like_email(contact, expected): assert booking_mail.looks_like_email(contact) is expected def test_manage_url_embeds_token(monkeypatch): monkeypatch.setattr(booking_mail, "PUBLIC_BASE_URL", "https://onboard.example.com") assert booking_mail.manage_url("abc.def.ghi") == \ "https://onboard.example.com/manage/abc.def.ghi" def test_sender_uses_client_domain_when_configured(): client = {"domain": "happynails.de"} assert booking_mail._sender_for(client) == "noreply@happynails.de" def test_sender_falls_back_when_client_has_no_domain(monkeypatch): monkeypatch.setattr(booking_mail.mailer, "MAIL_FALLBACK_FROM", "noreply@mivanchenko.de") assert booking_mail._sender_for({"domain": None}) == "noreply@mivanchenko.de" assert booking_mail._sender_for({}) == "noreply@mivanchenko.de" assert booking_mail._sender_for(None) == "noreply@mivanchenko.de" @pytest.mark.parametrize("raw,expected", [ ("happynails.de", "happynails.de"), ("https://happynails.de", "happynails.de"), ("https://happynails.de/", "happynails.de"), ("http://happynails.de/shop", "happynails.de"), (" happynails.de ", "happynails.de"), ("HappyNails.de", "happynails.de"), ]) def test_sender_sanitizes_domain_entered_with_scheme_or_path(raw, expected): assert booking_mail._sender_for({"domain": raw}) == f"noreply@{expected}" def _booking(contact="alice@example.com"): start = datetime.now(timezone.utc) + timedelta(days=1) return { "customer_name": "Alice", "customer_contact": contact, "service": "Haircut", "start_time": start, "status": "confirmed", } def test_send_booking_confirmation_sends_when_contact_is_email(monkeypatch): captured = [] monkeypatch.setattr(booking_mail.mailer, "send_email", lambda to, subject, html, from_addr=None: captured.append((to, subject, html, from_addr))) client = {"domain": "happynails.de", "business_name": "Happy Nails", "timezone": "Europe/Berlin"} with flask_app.test_request_context(): booking_mail.send_booking_confirmation(client, _booking(), "sometoken") assert len(captured) == 1 to, subject, html, from_addr = captured[0] assert to == "alice@example.com" assert from_addr == "noreply@happynails.de" assert "Happy Nails" in subject assert "/manage/sometoken" in html assert "Haircut" in html def test_send_booking_confirmation_skips_when_contact_is_phone(monkeypatch): captured = [] monkeypatch.setattr(booking_mail.mailer, "send_email", lambda *a, **kw: captured.append((a, kw))) client = {"business_name": "Happy Nails", "timezone": "Europe/Berlin"} with flask_app.test_request_context(): booking_mail.send_booking_confirmation(client, _booking(contact="0151-2345678"), "sometoken") assert captured == []