Files
animaltrack/tests/test_web_responses.py
Petru Paler 229842fb45 feat: implement location events & error handling (Step 10.2)
- Add LocationService with create/rename/archive methods
- Add LocationProjection for event handling
- Add admin-only location management routes at /locations
- Add error response helpers (error_response, error_toast, success_toast)
- Add toast handler JS to base template for HX-Trigger notifications
- Update seeds.py to emit LocationCreated events per spec §23
- Archived locations block animal moves with 422 error

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 17:48:16 +00:00

110 lines
4.0 KiB
Python

# ABOUTME: Tests for web response helper functions.
# ABOUTME: Tests error_response, error_toast, and success_toast helpers.
import json
from starlette.responses import HTMLResponse
from animaltrack.web.responses import error_response, error_toast, success_toast
class TestErrorResponse:
"""Tests for error_response()."""
def test_returns_html_response(self):
"""error_response returns an HTMLResponse."""
response = error_response("<div>Error</div>")
assert isinstance(response, HTMLResponse)
def test_default_status_422(self):
"""error_response defaults to 422 status code."""
response = error_response("<div>Validation error</div>")
assert response.status_code == 422
def test_custom_status_code(self):
"""error_response accepts custom status code."""
response = error_response("<div>Conflict</div>", status_code=409)
assert response.status_code == 409
def test_403_status_code(self):
"""error_response works with 403 status code."""
response = error_response("<div>Forbidden</div>", status_code=403)
assert response.status_code == 403
def test_401_status_code(self):
"""error_response works with 401 status code."""
response = error_response("<div>Unauthorized</div>", status_code=401)
assert response.status_code == 401
def test_content_in_body(self):
"""error_response includes content in body."""
response = error_response("<p>Error message</p>")
assert b"<p>Error message</p>" in response.body
class TestErrorToast:
"""Tests for error_toast()."""
def test_returns_html_response(self):
"""error_toast returns an HTMLResponse."""
response = error_toast("Something went wrong")
assert isinstance(response, HTMLResponse)
def test_default_status_422(self):
"""error_toast defaults to 422 status code."""
response = error_toast("Validation failed")
assert response.status_code == 422
def test_custom_status_code(self):
"""error_toast accepts custom status code."""
response = error_toast("Not allowed", status_code=403)
assert response.status_code == 403
def test_has_hx_trigger_header(self):
"""error_toast sets HX-Trigger header."""
response = error_toast("Error message")
assert "HX-Trigger" in response.headers
def test_toast_message_in_header(self):
"""error_toast includes message in HX-Trigger header."""
response = error_toast("Error message")
trigger = json.loads(response.headers["HX-Trigger"])
assert trigger["showToast"]["message"] == "Error message"
def test_toast_type_error(self):
"""error_toast sets toast type to error."""
response = error_toast("Error message")
trigger = json.loads(response.headers["HX-Trigger"])
assert trigger["showToast"]["type"] == "error"
class TestSuccessToast:
"""Tests for success_toast()."""
def test_returns_dict(self):
"""success_toast returns a dict (for HX-Trigger header)."""
result = success_toast("Action completed")
assert isinstance(result, dict)
def test_has_show_toast_key(self):
"""success_toast dict has showToast key."""
result = success_toast("Action completed")
assert "showToast" in result
def test_message_in_toast(self):
"""success_toast includes message."""
result = success_toast("Created successfully")
assert result["showToast"]["message"] == "Created successfully"
def test_toast_type_success(self):
"""success_toast sets toast type to success."""
result = success_toast("Done")
assert result["showToast"]["type"] == "success"
def test_can_json_dumps(self):
"""success_toast result can be JSON serialized."""
result = success_toast("Test message")
serialized = json.dumps(result)
assert '"showToast"' in serialized
assert '"Test message"' in serialized