import pytest from django.urls import reverse from django.test import Client from parks.models import Park from 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"]