mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 11:51:10 -05:00
174 lines
6.0 KiB
Python
174 lines
6.0 KiB
Python
import pytest
|
|
from django.urls import reverse
|
|
from django.test import Client
|
|
|
|
from apps.parks.models import Park
|
|
from apps.parks.forms import ParkAutocomplete, ParkSearchForm
|
|
|
|
|
|
@pytest.mark.django_db
|
|
class TestParkSearch:
|
|
def test_autocomplete_results(self, client: Client):
|
|
"""Test that autocomplete returns correct results"""
|
|
# Create test parks
|
|
park1 = Park.objects.create(name="Test Park")
|
|
park2 = Park.objects.create(name="Another Park")
|
|
park3 = Park.objects.create(name="Test Garden")
|
|
|
|
# Get autocomplete results
|
|
url = reverse("parks:suggest_parks")
|
|
response = client.get(url, {"search": "Test"})
|
|
|
|
# Check response
|
|
assert response.status_code == 200
|
|
content = response.content.decode()
|
|
assert park1.name in content
|
|
assert park3.name in content
|
|
assert park2.name not in content
|
|
|
|
def test_search_form_valid(self):
|
|
"""Test ParkSearchForm validation"""
|
|
form = ParkSearchForm(data={})
|
|
assert form.is_valid()
|
|
|
|
def test_autocomplete_class(self):
|
|
"""Test ParkAutocomplete configuration"""
|
|
ac = ParkAutocomplete()
|
|
assert ac.model == Park
|
|
assert "name" in ac.search_attrs
|
|
|
|
def test_search_with_filters(self, client: Client):
|
|
"""Test search works with filters"""
|
|
park = Park.objects.create(name="Test Park", status="OPERATING")
|
|
|
|
# Search with status filter
|
|
url = reverse("parks:park_list")
|
|
response = client.get(url, {"park": str(park.pk), "status": "OPERATING"})
|
|
|
|
assert response.status_code == 200
|
|
assert park.name in response.content.decode()
|
|
|
|
def test_empty_search(self, client: Client):
|
|
"""Test empty search returns all parks"""
|
|
Park.objects.create(name="Test Park")
|
|
Park.objects.create(name="Another Park")
|
|
|
|
url = reverse("parks:park_list")
|
|
response = client.get(url)
|
|
|
|
assert response.status_code == 200
|
|
content = response.content.decode()
|
|
assert "Test Park" in content
|
|
assert "Another Park" in content
|
|
|
|
def test_partial_match_search(self, client: Client):
|
|
"""Test partial matching in search"""
|
|
Park.objects.create(name="Adventure World")
|
|
Park.objects.create(name="Water Adventure")
|
|
|
|
url = reverse("parks:suggest_parks")
|
|
response = client.get(url, {"search": "Adv"})
|
|
|
|
assert response.status_code == 200
|
|
content = response.content.decode()
|
|
assert "Adventure World" in content
|
|
assert "Water Adventure" in content
|
|
|
|
def test_htmx_request_handling(self, client: Client):
|
|
"""Test HTMX-specific request handling"""
|
|
Park.objects.create(name="Test Park")
|
|
|
|
url = reverse("parks:suggest_parks")
|
|
response = client.get(url, {"search": "Test"}, HTTP_HX_REQUEST="true")
|
|
|
|
assert response.status_code == 200
|
|
assert "Test Park" in response.content.decode()
|
|
|
|
def test_view_mode_persistence(self, client: Client):
|
|
"""Test view mode is maintained during search"""
|
|
Park.objects.create(name="Test Park")
|
|
|
|
url = reverse("parks:park_list")
|
|
response = client.get(url, {"park": "Test", "view_mode": "list"})
|
|
|
|
assert response.status_code == 200
|
|
assert 'data-view-mode="list"' in response.content.decode()
|
|
|
|
def test_suggestion_limit(self, client: Client):
|
|
"""Test that suggestions are limited to 8 items"""
|
|
# Create 10 parks
|
|
for i in range(10):
|
|
Park.objects.create(name=f"Test Park {i}")
|
|
|
|
url = reverse("parks:suggest_parks")
|
|
response = client.get(url, {"search": "Test"})
|
|
|
|
content = response.content.decode()
|
|
result_count = content.count("Test Park")
|
|
assert result_count == 8 # Verify limit is enforced
|
|
|
|
def test_search_json_format(self, client: Client):
|
|
"""Test that search returns properly formatted JSON"""
|
|
park = Park.objects.create(
|
|
name="Test Park",
|
|
status="OPERATING",
|
|
city="Test City",
|
|
state="Test State",
|
|
)
|
|
|
|
url = reverse("parks:suggest_parks")
|
|
response = client.get(url, {"search": "Test"})
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "results" in data
|
|
assert len(data["results"]) == 1
|
|
|
|
result = data["results"][0]
|
|
assert result["id"] == str(park.pk)
|
|
assert result["name"] == "Test Park"
|
|
assert result["status"] == "Operating"
|
|
assert result["location"] == park.formatted_location
|
|
assert result["url"] == reverse("parks:park_detail", kwargs={"slug": park.slug})
|
|
|
|
def test_empty_search_json(self, client: Client):
|
|
"""Test empty search returns empty results array"""
|
|
url = reverse("parks:suggest_parks")
|
|
response = client.get(url, {"search": ""})
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "results" in data
|
|
assert len(data["results"]) == 0
|
|
|
|
def test_search_format_validation(self, client: Client):
|
|
"""Test that all fields are properly formatted in search results"""
|
|
Park.objects.create(
|
|
name="Test Park",
|
|
status="OPERATING",
|
|
city="Test City",
|
|
state="Test State",
|
|
country="Test Country",
|
|
)
|
|
|
|
expected_fields = {"id", "name", "status", "location", "url"}
|
|
|
|
url = reverse("parks:suggest_parks")
|
|
response = client.get(url, {"search": "Test"})
|
|
data = response.json()
|
|
result = data["results"][0]
|
|
|
|
# Check all expected fields are present
|
|
assert set(result.keys()) == expected_fields
|
|
|
|
# Check field types
|
|
assert isinstance(result["id"], str)
|
|
assert isinstance(result["name"], str)
|
|
assert isinstance(result["status"], str)
|
|
assert isinstance(result["location"], str)
|
|
assert isinstance(result["url"], str)
|
|
|
|
# Check formatted location includes city and state
|
|
assert "Test City" in result["location"]
|
|
assert "Test State" in result["location"]
|