121 lines
4.1 KiB
Python
121 lines
4.1 KiB
Python
|
|
"""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
|