test: add survey invite tracking tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
115
backend/tests/test_survey.py
Normal file
115
backend/tests/test_survey.py
Normal file
@@ -0,0 +1,115 @@
|
||||
"""Tests for the public survey submission endpoint."""
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_submit_survey_success(client):
|
||||
"""POST valid survey data returns 200 with id."""
|
||||
payload = {
|
||||
"respondent_name": "Test Engineer",
|
||||
"responses": {
|
||||
"prereqs": ["Who's affected", "What changed recently"],
|
||||
"verify_fix": "Have the user confirm it's working",
|
||||
"steps_at_a_time": "5 steps",
|
||||
},
|
||||
}
|
||||
response = await client.post("/api/v1/survey/submit", json=payload)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "id" in data
|
||||
assert data["message"] == "Thank you for your response!"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_submit_survey_anonymous(client):
|
||||
"""Survey works without respondent_name."""
|
||||
payload = {
|
||||
"responses": {
|
||||
"first_step": "Check if it's one user or many",
|
||||
},
|
||||
}
|
||||
response = await client.post("/api/v1/survey/submit", json=payload)
|
||||
assert response.status_code == 200
|
||||
assert "id" in response.json()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_submit_survey_missing_responses(client):
|
||||
"""Missing responses field returns 422."""
|
||||
payload = {"respondent_name": "Test"}
|
||||
response = await client.post("/api/v1/survey/submit", json=payload)
|
||||
assert response.status_code == 422
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_submit_survey_empty_body(client):
|
||||
"""Empty body returns 422."""
|
||||
response = await client.post("/api/v1/survey/submit", json={})
|
||||
assert response.status_code == 422
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_check_invite_status_not_found(client):
|
||||
"""Invalid token returns 404."""
|
||||
response = await client.get("/api/v1/survey/invite/nonexistent")
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_submit_with_completed_token_returns_409(client, admin_auth_headers):
|
||||
"""Submitting with an already-used token returns 409."""
|
||||
# Create invite
|
||||
create_res = await client.post(
|
||||
"/api/v1/admin/survey-invites",
|
||||
json={"recipient_name": "Test User"},
|
||||
headers=admin_auth_headers,
|
||||
)
|
||||
assert create_res.status_code == 200
|
||||
token = create_res.json()["token"]
|
||||
|
||||
# First submit succeeds
|
||||
submit_res = await client.post(
|
||||
"/api/v1/survey/submit",
|
||||
json={"responses": {"q1": "answer"}, "token": token},
|
||||
)
|
||||
assert submit_res.status_code == 200
|
||||
|
||||
# Second submit with same token returns 409
|
||||
submit_res2 = await client.post(
|
||||
"/api/v1/survey/submit",
|
||||
json={"responses": {"q1": "answer"}, "token": token},
|
||||
)
|
||||
assert submit_res2.status_code == 409
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_invite_requires_admin(client, auth_headers):
|
||||
"""Non-admin users cannot create invites."""
|
||||
response = await client.post(
|
||||
"/api/v1/admin/survey-invites",
|
||||
json={"recipient_name": "Test"},
|
||||
headers=auth_headers,
|
||||
)
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_and_list_invites(client, admin_auth_headers):
|
||||
"""Admin can create and list invites."""
|
||||
# Create
|
||||
create_res = await client.post(
|
||||
"/api/v1/admin/survey-invites",
|
||||
json={"recipient_name": "John Smith", "recipient_email": "john@msp.example.com"},
|
||||
headers=admin_auth_headers,
|
||||
)
|
||||
assert create_res.status_code == 200
|
||||
data = create_res.json()
|
||||
assert data["recipient_name"] == "John Smith"
|
||||
assert data["status"] == "pending"
|
||||
assert "survey_url" in data
|
||||
|
||||
# List
|
||||
list_res = await client.get("/api/v1/admin/survey-invites", headers=admin_auth_headers)
|
||||
assert list_res.status_code == 200
|
||||
invites = list_res.json()
|
||||
assert len(invites) >= 1
|
||||
Reference in New Issue
Block a user