test: add feedback endpoint tests including DB persistence

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-02-18 17:56:29 -05:00
parent 72e801eca6
commit 8b05afaf8f

View File

@@ -0,0 +1,128 @@
import pytest
from unittest.mock import patch, AsyncMock
@pytest.mark.asyncio
async def test_submit_feedback(client, auth_headers):
"""Test successful feedback submission — saves to DB and sends emails."""
with patch("app.api.endpoints.feedback.settings") as mock_settings, \
patch("app.api.endpoints.feedback.EmailService") as mock_email:
mock_settings.FEEDBACK_EMAIL = "support@test.com"
mock_email.send_feedback_email = AsyncMock(return_value=True)
mock_email.send_feedback_confirmation_email = AsyncMock(return_value=True)
response = await client.post(
"/api/v1/feedback",
json={
"email": "test@example.com",
"feedback_type": "Bug Report",
"message": "Something is broken in the tree editor when I try to save.",
},
headers=auth_headers,
)
assert response.status_code == 200
data = response.json()
assert data["success"] is True
assert "submitted" in data["message"].lower()
# Verify both emails were called
mock_email.send_feedback_email.assert_called_once()
mock_email.send_feedback_confirmation_email.assert_called_once()
@pytest.mark.asyncio
async def test_submit_feedback_saves_to_db_even_if_email_fails(client, auth_headers, test_db):
"""Test that feedback is persisted even when email sending fails."""
from sqlalchemy import select, func
from app.models.feedback import Feedback
with patch("app.api.endpoints.feedback.settings") as mock_settings, \
patch("app.api.endpoints.feedback.EmailService") as mock_email:
mock_settings.FEEDBACK_EMAIL = "support@test.com"
mock_email.send_feedback_email = AsyncMock(return_value=False)
mock_email.send_feedback_confirmation_email = AsyncMock(return_value=False)
response = await client.post(
"/api/v1/feedback",
json={
"email": "test@example.com",
"feedback_type": "Feature Request",
"message": "Please add dark mode to the export preview screen.",
},
headers=auth_headers,
)
# Should still succeed — DB write happened
assert response.status_code == 200
assert response.json()["success"] is True
# Verify it was saved to the database
result = await test_db.execute(select(func.count()).select_from(Feedback))
count = result.scalar()
assert count >= 1
@pytest.mark.asyncio
async def test_submit_feedback_not_configured(client, auth_headers):
"""Test 503 when FEEDBACK_EMAIL is not set."""
with patch("app.api.endpoints.feedback.settings") as mock_settings:
mock_settings.FEEDBACK_EMAIL = None
response = await client.post(
"/api/v1/feedback",
json={
"email": "test@example.com",
"feedback_type": "General Feedback",
"message": "This is a general feedback message for testing.",
},
headers=auth_headers,
)
assert response.status_code == 503
@pytest.mark.asyncio
async def test_submit_feedback_validation_message_too_short(client, auth_headers):
"""Test validation — message too short."""
response = await client.post(
"/api/v1/feedback",
json={
"email": "test@example.com",
"feedback_type": "Bug Report",
"message": "short",
},
headers=auth_headers,
)
assert response.status_code == 422
@pytest.mark.asyncio
async def test_submit_feedback_invalid_type(client, auth_headers):
"""Test validation — invalid feedback type."""
response = await client.post(
"/api/v1/feedback",
json={
"email": "test@example.com",
"feedback_type": "Invalid Type",
"message": "This should fail because the type is invalid.",
},
headers=auth_headers,
)
assert response.status_code == 422
@pytest.mark.asyncio
async def test_submit_feedback_requires_auth(client):
"""Test that unauthenticated requests are rejected."""
response = await client.post(
"/api/v1/feedback",
json={
"email": "anon@example.com",
"feedback_type": "General Feedback",
"message": "This should fail because I'm not logged in.",
},
)
assert response.status_code == 401