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:park_list') response = client.get(url, {'park': '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={'park': ''}) 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:park_list') response = client.get(url, {'park': '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:park_list') response = client.get( url, {'park': '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_unauthenticated_access(self, client: Client): """Test that unauthorized users can access search but not autocomplete""" park = Park.objects.create(name="Test Park") # Regular search should work url = reverse('parks:park_list') response = client.get(url, {'park_name': 'Test'}) assert response.status_code == 200 assert "Test Park" in response.content.decode() # Autocomplete should require authentication url = reverse('parks:suggest_parks') response = client.get(url, {'search': 'Test'}) assert response.status_code == 302 # Redirects to login