Files

121 lines
4.1 KiB
Python
Raw Permalink Normal View History

"""Tests for contact router (T05)."""
import pytest
from unittest.mock import AsyncMock, patch, MagicMock
from sqlalchemy import select
from app.models.contact import Contact
@pytest.mark.asyncio
async def test_contact_valid_returns_200(client):
"""POST /api/contact with valid data returns 200 and saves to contacts table."""
with patch(
"app.services.email_service.EmailService.send_contact_email",
new_callable=AsyncMock,
return_value=True,
):
resp = await client.post("/api/contact", json={
"name": "Max Mustermann",
"email": "max@example.com",
"phone": "+49 123 456789",
"message": "Ich brauche eine PA-Anlage fuer ein Festival.",
"privacy_consent": True,
})
assert resp.status_code == 200
data = resp.json()
assert data["success"] is True
@pytest.mark.asyncio
async def test_contact_invalid_email_returns_422(client):
"""POST /api/contact with invalid email returns 422."""
resp = await client.post("/api/contact", json={
"name": "Max Mustermann",
"email": "not-an-email",
"phone": "+49 123 456789",
"message": "Test message",
"privacy_consent": True,
})
assert resp.status_code == 422
@pytest.mark.asyncio
async def test_contact_privacy_consent_false_returns_422(client):
"""POST /api/contact with privacy_consent=false returns 422."""
resp = await client.post("/api/contact", json={
"name": "Max Mustermann",
"email": "max@example.com",
"phone": "+49 123 456789",
"message": "Test message",
"privacy_consent": False,
})
assert resp.status_code == 422
@pytest.mark.asyncio
async def test_contact_triggers_email(client):
"""POST /api/contact triggers send_contact_email on EmailService."""
with patch(
"app.services.email_service.EmailService.send_contact_email",
new_callable=AsyncMock,
return_value=True,
) as mock_send:
resp = await client.post("/api/contact", json={
"name": "Erika Musterfrau",
"email": "erika@example.com",
"phone": "+49 987 654321",
"message": "Ich benoetige Beleuchtung fuer eine Gala.",
"privacy_consent": True,
})
assert resp.status_code == 200
mock_send.assert_awaited_once()
call_args = mock_send.call_args[0][0]
assert call_args["name"] == "Erika Musterfrau"
assert call_args["email"] == "erika@example.com"
assert call_args["message"] == "Ich benoetige Beleuchtung fuer eine Gala."
@pytest.mark.asyncio
async def test_contact_saved_to_db(client, test_db):
"""POST /api/contact saves a record to the contacts table."""
with patch(
"app.services.email_service.EmailService.send_contact_email",
new_callable=AsyncMock,
return_value=True,
):
resp = await client.post("/api/contact", json={
"name": "DB Testuser",
"email": "db@example.com",
"phone": "+49 111 222333",
"message": "Datenbank-Verifikation",
"privacy_consent": True,
})
assert resp.status_code == 200
result = await test_db.execute(select(Contact).where(Contact.email == "db@example.com"))
contact = result.scalar_one_or_none()
assert contact is not None
assert contact.name == "DB Testuser"
assert contact.message == "Datenbank-Verifikation"
assert contact.privacy_consent is True
assert contact.email_sent is True
@pytest.mark.asyncio
async def test_contact_email_failure_does_not_break_response(client):
"""POST /api/contact still returns 200 when email sending fails."""
with patch(
"app.services.email_service.EmailService.send_contact_email",
new_callable=AsyncMock,
return_value=False,
):
resp = await client.post("/api/contact", json={
"name": "Fail Test",
"email": "fail@example.com",
"phone": "+49 000 000000",
"message": "Email soll fehlschlagen",
"privacy_consent": True,
})
assert resp.status_code == 200
assert resp.json()["success"] is True