mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2026-01-02 03:27:02 -05:00
feat: Implement initial schema and add various API, service, and management command enhancements across the application.
This commit is contained in:
@@ -38,13 +38,13 @@ class TestParkPhotoViewSetList(EnhancedAPITestCase):
|
||||
self.user = UserFactory()
|
||||
self.park = ParkFactory()
|
||||
|
||||
@patch('apps.parks.models.ParkPhoto.objects')
|
||||
@patch("apps.parks.models.ParkPhoto.objects")
|
||||
def test__list_park_photos__unauthenticated__can_access(self, mock_queryset):
|
||||
"""Test that unauthenticated users can access park photo list."""
|
||||
# Mock the queryset
|
||||
mock_queryset.select_related.return_value.filter.return_value.order_by.return_value = []
|
||||
|
||||
url = f'/api/v1/parks/{self.park.id}/photos/'
|
||||
url = f"/api/v1/parks/{self.park.id}/photos/"
|
||||
response = self.client.get(url)
|
||||
|
||||
# Should allow access (AllowAny permission for list)
|
||||
@@ -52,7 +52,7 @@ class TestParkPhotoViewSetList(EnhancedAPITestCase):
|
||||
|
||||
def test__list_park_photos__with_invalid_park__returns_empty_or_404(self):
|
||||
"""Test listing photos for non-existent park."""
|
||||
url = '/api/v1/parks/99999/photos/'
|
||||
url = "/api/v1/parks/99999/photos/"
|
||||
response = self.client.get(url)
|
||||
|
||||
# Should handle gracefully
|
||||
@@ -71,7 +71,7 @@ class TestParkPhotoViewSetCreate(EnhancedAPITestCase):
|
||||
|
||||
def test__create_park_photo__unauthenticated__returns_401(self):
|
||||
"""Test that unauthenticated users cannot create photos."""
|
||||
url = f'/api/v1/parks/{self.park.id}/photos/'
|
||||
url = f"/api/v1/parks/{self.park.id}/photos/"
|
||||
response = self.client.post(url, {})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
@@ -79,7 +79,7 @@ class TestParkPhotoViewSetCreate(EnhancedAPITestCase):
|
||||
def test__create_park_photo__authenticated_without_data__returns_400(self):
|
||||
"""Test that creating photo without required data returns 400."""
|
||||
self.client.force_authenticate(user=self.user)
|
||||
url = f'/api/v1/parks/{self.park.id}/photos/'
|
||||
url = f"/api/v1/parks/{self.park.id}/photos/"
|
||||
|
||||
response = self.client.post(url, {})
|
||||
|
||||
@@ -88,9 +88,9 @@ class TestParkPhotoViewSetCreate(EnhancedAPITestCase):
|
||||
def test__create_park_photo__invalid_park__returns_error(self):
|
||||
"""Test creating photo for non-existent park."""
|
||||
self.client.force_authenticate(user=self.user)
|
||||
url = '/api/v1/parks/99999/photos/'
|
||||
url = "/api/v1/parks/99999/photos/"
|
||||
|
||||
response = self.client.post(url, {'caption': 'Test'})
|
||||
response = self.client.post(url, {"caption": "Test"})
|
||||
|
||||
# Should return 400 or 404 for invalid park
|
||||
self.assertIn(response.status_code, [status.HTTP_400_BAD_REQUEST, status.HTTP_404_NOT_FOUND])
|
||||
@@ -106,7 +106,7 @@ class TestParkPhotoViewSetRetrieve(EnhancedAPITestCase):
|
||||
|
||||
def test__retrieve_park_photo__not_found__returns_404(self):
|
||||
"""Test retrieving non-existent photo returns 404."""
|
||||
url = f'/api/v1/parks/{self.park.id}/photos/99999/'
|
||||
url = f"/api/v1/parks/{self.park.id}/photos/99999/"
|
||||
response = self.client.get(url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
@@ -125,8 +125,8 @@ class TestParkPhotoViewSetUpdate(EnhancedAPITestCase):
|
||||
|
||||
def test__update_park_photo__unauthenticated__returns_401(self):
|
||||
"""Test that unauthenticated users cannot update photos."""
|
||||
url = f'/api/v1/parks/{self.park.id}/photos/1/'
|
||||
response = self.client.patch(url, {'caption': 'Updated'})
|
||||
url = f"/api/v1/parks/{self.park.id}/photos/1/"
|
||||
response = self.client.patch(url, {"caption": "Updated"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
@@ -143,7 +143,7 @@ class TestParkPhotoViewSetDelete(EnhancedAPITestCase):
|
||||
|
||||
def test__delete_park_photo__unauthenticated__returns_401(self):
|
||||
"""Test that unauthenticated users cannot delete photos."""
|
||||
url = f'/api/v1/parks/{self.park.id}/photos/1/'
|
||||
url = f"/api/v1/parks/{self.park.id}/photos/1/"
|
||||
response = self.client.delete(url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
@@ -161,7 +161,7 @@ class TestParkPhotoViewSetSetPrimary(EnhancedAPITestCase):
|
||||
|
||||
def test__set_primary__unauthenticated__returns_401(self):
|
||||
"""Test that unauthenticated users cannot set primary photo."""
|
||||
url = f'/api/v1/parks/{self.park.id}/photos/1/set_primary/'
|
||||
url = f"/api/v1/parks/{self.park.id}/photos/1/set_primary/"
|
||||
response = self.client.post(url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
@@ -169,7 +169,7 @@ class TestParkPhotoViewSetSetPrimary(EnhancedAPITestCase):
|
||||
def test__set_primary__photo_not_found__returns_404(self):
|
||||
"""Test setting primary for non-existent photo."""
|
||||
self.client.force_authenticate(user=self.user)
|
||||
url = f'/api/v1/parks/{self.park.id}/photos/99999/set_primary/'
|
||||
url = f"/api/v1/parks/{self.park.id}/photos/99999/set_primary/"
|
||||
response = self.client.post(url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
@@ -187,23 +187,23 @@ class TestParkPhotoViewSetBulkApprove(EnhancedAPITestCase):
|
||||
|
||||
def test__bulk_approve__unauthenticated__returns_401(self):
|
||||
"""Test that unauthenticated users cannot bulk approve."""
|
||||
url = f'/api/v1/parks/{self.park.id}/photos/bulk_approve/'
|
||||
response = self.client.post(url, {'photo_ids': [1, 2], 'approve': True})
|
||||
url = f"/api/v1/parks/{self.park.id}/photos/bulk_approve/"
|
||||
response = self.client.post(url, {"photo_ids": [1, 2], "approve": True})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
def test__bulk_approve__non_staff__returns_403(self):
|
||||
"""Test that non-staff users cannot bulk approve."""
|
||||
self.client.force_authenticate(user=self.user)
|
||||
url = f'/api/v1/parks/{self.park.id}/photos/bulk_approve/'
|
||||
response = self.client.post(url, {'photo_ids': [1, 2], 'approve': True})
|
||||
url = f"/api/v1/parks/{self.park.id}/photos/bulk_approve/"
|
||||
response = self.client.post(url, {"photo_ids": [1, 2], "approve": True})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
|
||||
def test__bulk_approve__missing_data__returns_400(self):
|
||||
"""Test bulk approve with missing required data."""
|
||||
self.client.force_authenticate(user=self.staff_user)
|
||||
url = f'/api/v1/parks/{self.park.id}/photos/bulk_approve/'
|
||||
url = f"/api/v1/parks/{self.park.id}/photos/bulk_approve/"
|
||||
response = self.client.post(url, {})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
@@ -219,7 +219,7 @@ class TestParkPhotoViewSetStats(EnhancedAPITestCase):
|
||||
|
||||
def test__stats__unauthenticated__can_access(self):
|
||||
"""Test that unauthenticated users can access stats."""
|
||||
url = f'/api/v1/parks/{self.park.id}/photos/stats/'
|
||||
url = f"/api/v1/parks/{self.park.id}/photos/stats/"
|
||||
response = self.client.get(url)
|
||||
|
||||
# Stats should be accessible to all
|
||||
@@ -227,7 +227,7 @@ class TestParkPhotoViewSetStats(EnhancedAPITestCase):
|
||||
|
||||
def test__stats__invalid_park__returns_404(self):
|
||||
"""Test stats for non-existent park returns 404."""
|
||||
url = '/api/v1/parks/99999/photos/stats/'
|
||||
url = "/api/v1/parks/99999/photos/stats/"
|
||||
response = self.client.get(url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
@@ -244,15 +244,15 @@ class TestParkPhotoViewSetSaveImage(EnhancedAPITestCase):
|
||||
|
||||
def test__save_image__unauthenticated__returns_401(self):
|
||||
"""Test that unauthenticated users cannot save images."""
|
||||
url = f'/api/v1/parks/{self.park.id}/photos/save_image/'
|
||||
response = self.client.post(url, {'cloudflare_image_id': 'test-id'})
|
||||
url = f"/api/v1/parks/{self.park.id}/photos/save_image/"
|
||||
response = self.client.post(url, {"cloudflare_image_id": "test-id"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
def test__save_image__missing_cloudflare_id__returns_400(self):
|
||||
"""Test saving image without cloudflare_image_id."""
|
||||
self.client.force_authenticate(user=self.user)
|
||||
url = f'/api/v1/parks/{self.park.id}/photos/save_image/'
|
||||
url = f"/api/v1/parks/{self.park.id}/photos/save_image/"
|
||||
response = self.client.post(url, {})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
@@ -260,8 +260,8 @@ class TestParkPhotoViewSetSaveImage(EnhancedAPITestCase):
|
||||
def test__save_image__invalid_park__returns_404(self):
|
||||
"""Test saving image for non-existent park."""
|
||||
self.client.force_authenticate(user=self.user)
|
||||
url = '/api/v1/parks/99999/photos/save_image/'
|
||||
response = self.client.post(url, {'cloudflare_image_id': 'test-id'})
|
||||
url = "/api/v1/parks/99999/photos/save_image/"
|
||||
response = self.client.post(url, {"cloudflare_image_id": "test-id"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
@@ -273,112 +273,112 @@ class TestHybridParkAPIView(EnhancedAPITestCase):
|
||||
"""Set up test data."""
|
||||
self.client = APIClient()
|
||||
# Create several parks for testing
|
||||
self.operator = CompanyFactory(roles=['OPERATOR'])
|
||||
self.operator = CompanyFactory(roles=["OPERATOR"])
|
||||
self.parks = [
|
||||
ParkFactory(operator=self.operator, status='OPERATING', name='Alpha Park'),
|
||||
ParkFactory(operator=self.operator, status='OPERATING', name='Beta Park'),
|
||||
ParkFactory(operator=self.operator, status='CLOSED_PERM', name='Gamma Park'),
|
||||
ParkFactory(operator=self.operator, status="OPERATING", name="Alpha Park"),
|
||||
ParkFactory(operator=self.operator, status="OPERATING", name="Beta Park"),
|
||||
ParkFactory(operator=self.operator, status="CLOSED_PERM", name="Gamma Park"),
|
||||
]
|
||||
|
||||
def test__hybrid_park_api__initial_load__returns_parks(self):
|
||||
"""Test initial load returns parks with metadata."""
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
response = self.client.get(url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertTrue(response.data.get('success', False))
|
||||
self.assertIn('data', response.data)
|
||||
self.assertIn('parks', response.data['data'])
|
||||
self.assertIn('total_count', response.data['data'])
|
||||
self.assertIn('strategy', response.data['data'])
|
||||
self.assertTrue(response.data.get("success", False))
|
||||
self.assertIn("data", response.data)
|
||||
self.assertIn("parks", response.data["data"])
|
||||
self.assertIn("total_count", response.data["data"])
|
||||
self.assertIn("strategy", response.data["data"])
|
||||
|
||||
def test__hybrid_park_api__with_status_filter__returns_filtered_parks(self):
|
||||
"""Test filtering by status."""
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
response = self.client.get(url, {'status': 'OPERATING'})
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
response = self.client.get(url, {"status": "OPERATING"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
# All returned parks should be OPERATING
|
||||
for park in response.data['data']['parks']:
|
||||
self.assertEqual(park['status'], 'OPERATING')
|
||||
for park in response.data["data"]["parks"]:
|
||||
self.assertEqual(park["status"], "OPERATING")
|
||||
|
||||
def test__hybrid_park_api__with_multiple_status_filter__returns_filtered_parks(self):
|
||||
"""Test filtering by multiple statuses."""
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
response = self.client.get(url, {'status': 'OPERATING,CLOSED_PERM'})
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
response = self.client.get(url, {"status": "OPERATING,CLOSED_PERM"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
def test__hybrid_park_api__with_search__returns_matching_parks(self):
|
||||
"""Test search functionality."""
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
response = self.client.get(url, {'search': 'Alpha'})
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
response = self.client.get(url, {"search": "Alpha"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
# Should find Alpha Park
|
||||
parks = response.data['data']['parks']
|
||||
park_names = [p['name'] for p in parks]
|
||||
self.assertIn('Alpha Park', park_names)
|
||||
parks = response.data["data"]["parks"]
|
||||
park_names = [p["name"] for p in parks]
|
||||
self.assertIn("Alpha Park", park_names)
|
||||
|
||||
def test__hybrid_park_api__with_offset__returns_progressive_data(self):
|
||||
"""Test progressive loading with offset."""
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
response = self.client.get(url, {'offset': 0})
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
response = self.client.get(url, {"offset": 0})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertIn('has_more', response.data['data'])
|
||||
self.assertIn("has_more", response.data["data"])
|
||||
|
||||
def test__hybrid_park_api__with_invalid_offset__returns_400(self):
|
||||
"""Test invalid offset parameter."""
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
response = self.client.get(url, {'offset': 'invalid'})
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
response = self.client.get(url, {"offset": "invalid"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def test__hybrid_park_api__with_year_filters__returns_filtered_parks(self):
|
||||
"""Test filtering by opening year range."""
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
response = self.client.get(url, {'opening_year_min': 2000, 'opening_year_max': 2024})
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
response = self.client.get(url, {"opening_year_min": 2000, "opening_year_max": 2024})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
def test__hybrid_park_api__with_rating_filters__returns_filtered_parks(self):
|
||||
"""Test filtering by rating range."""
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
response = self.client.get(url, {'rating_min': 5.0, 'rating_max': 10.0})
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
response = self.client.get(url, {"rating_min": 5.0, "rating_max": 10.0})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
def test__hybrid_park_api__with_size_filters__returns_filtered_parks(self):
|
||||
"""Test filtering by size range."""
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
response = self.client.get(url, {'size_min': 10, 'size_max': 1000})
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
response = self.client.get(url, {"size_min": 10, "size_max": 1000})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
def test__hybrid_park_api__with_ride_count_filters__returns_filtered_parks(self):
|
||||
"""Test filtering by ride count range."""
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
response = self.client.get(url, {'ride_count_min': 5, 'ride_count_max': 100})
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
response = self.client.get(url, {"ride_count_min": 5, "ride_count_max": 100})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
def test__hybrid_park_api__with_coaster_count_filters__returns_filtered_parks(self):
|
||||
"""Test filtering by coaster count range."""
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
response = self.client.get(url, {'coaster_count_min': 1, 'coaster_count_max': 20})
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
response = self.client.get(url, {"coaster_count_min": 1, "coaster_count_max": 20})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
def test__hybrid_park_api__includes_filter_metadata__on_initial_load(self):
|
||||
"""Test that initial load includes filter metadata."""
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
response = self.client.get(url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
# Filter metadata should be included for client-side filtering
|
||||
if 'filter_metadata' in response.data.get('data', {}):
|
||||
self.assertIn('filter_metadata', response.data['data'])
|
||||
if "filter_metadata" in response.data.get("data", {}):
|
||||
self.assertIn("filter_metadata", response.data["data"])
|
||||
|
||||
|
||||
class TestParkFilterMetadataAPIView(EnhancedAPITestCase):
|
||||
@@ -387,7 +387,7 @@ class TestParkFilterMetadataAPIView(EnhancedAPITestCase):
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.client = APIClient()
|
||||
self.operator = CompanyFactory(roles=['OPERATOR'])
|
||||
self.operator = CompanyFactory(roles=["OPERATOR"])
|
||||
self.parks = [
|
||||
ParkFactory(operator=self.operator),
|
||||
ParkFactory(operator=self.operator),
|
||||
@@ -395,32 +395,32 @@ class TestParkFilterMetadataAPIView(EnhancedAPITestCase):
|
||||
|
||||
def test__filter_metadata__unscoped__returns_all_metadata(self):
|
||||
"""Test getting unscoped filter metadata."""
|
||||
url = '/api/v1/parks/filter-metadata/'
|
||||
url = "/api/v1/parks/filter-metadata/"
|
||||
response = self.client.get(url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertTrue(response.data.get('success', False))
|
||||
self.assertIn('data', response.data)
|
||||
self.assertTrue(response.data.get("success", False))
|
||||
self.assertIn("data", response.data)
|
||||
|
||||
def test__filter_metadata__scoped__returns_filtered_metadata(self):
|
||||
"""Test getting scoped filter metadata."""
|
||||
url = '/api/v1/parks/filter-metadata/'
|
||||
response = self.client.get(url, {'scoped': 'true', 'status': 'OPERATING'})
|
||||
url = "/api/v1/parks/filter-metadata/"
|
||||
response = self.client.get(url, {"scoped": "true", "status": "OPERATING"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
def test__filter_metadata__structure__contains_expected_fields(self):
|
||||
"""Test that metadata contains expected structure."""
|
||||
url = '/api/v1/parks/filter-metadata/'
|
||||
url = "/api/v1/parks/filter-metadata/"
|
||||
response = self.client.get(url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
data = response.data.get('data', {})
|
||||
data = response.data.get("data", {})
|
||||
|
||||
# Should contain categorical and range metadata
|
||||
if data:
|
||||
# These are the expected top-level keys based on the view
|
||||
possible_keys = ['categorical', 'ranges', 'total_count']
|
||||
possible_keys = ["categorical", "ranges", "total_count"]
|
||||
for key in possible_keys:
|
||||
if key in data:
|
||||
self.assertIsNotNone(data[key])
|
||||
@@ -464,7 +464,7 @@ class TestParkAPIQueryOptimization(EnhancedAPITestCase):
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.client = APIClient()
|
||||
self.operator = CompanyFactory(roles=['OPERATOR'])
|
||||
self.operator = CompanyFactory(roles=["OPERATOR"])
|
||||
|
||||
def test__park_list__uses_select_related(self):
|
||||
"""Test that park list uses select_related for optimization."""
|
||||
@@ -472,7 +472,7 @@ class TestParkAPIQueryOptimization(EnhancedAPITestCase):
|
||||
for _i in range(5):
|
||||
ParkFactory(operator=self.operator)
|
||||
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
|
||||
# This test verifies the query is executed without N+1
|
||||
response = self.client.get(url)
|
||||
@@ -483,13 +483,13 @@ class TestParkAPIQueryOptimization(EnhancedAPITestCase):
|
||||
"""Test that park list handles larger datasets efficiently."""
|
||||
# Create a batch of parks
|
||||
for i in range(10):
|
||||
ParkFactory(operator=self.operator, name=f'Park {i}')
|
||||
ParkFactory(operator=self.operator, name=f"Park {i}")
|
||||
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
response = self.client.get(url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertGreaterEqual(response.data['data']['total_count'], 10)
|
||||
self.assertGreaterEqual(response.data["data"]["total_count"], 10)
|
||||
|
||||
|
||||
class TestParkAPIEdgeCases(EnhancedAPITestCase):
|
||||
@@ -504,16 +504,16 @@ class TestParkAPIEdgeCases(EnhancedAPITestCase):
|
||||
# Delete all parks for this test
|
||||
Park.objects.all().delete()
|
||||
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
response = self.client.get(url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data['data']['parks'], [])
|
||||
self.assertEqual(response.data['data']['total_count'], 0)
|
||||
self.assertEqual(response.data["data"]["parks"], [])
|
||||
self.assertEqual(response.data["data"]["total_count"], 0)
|
||||
|
||||
def test__hybrid_park__special_characters_in_search__handled_safely(self):
|
||||
"""Test that special characters in search are handled safely."""
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
|
||||
# Test with special characters
|
||||
special_searches = [
|
||||
@@ -525,21 +525,24 @@ class TestParkAPIEdgeCases(EnhancedAPITestCase):
|
||||
]
|
||||
|
||||
for search_term in special_searches:
|
||||
response = self.client.get(url, {'search': search_term})
|
||||
response = self.client.get(url, {"search": search_term})
|
||||
# Should not crash, either 200 or error with proper message
|
||||
self.assertIn(response.status_code, [status.HTTP_200_OK, status.HTTP_400_BAD_REQUEST])
|
||||
|
||||
def test__hybrid_park__extreme_filter_values__handled_safely(self):
|
||||
"""Test that extreme filter values are handled safely."""
|
||||
url = '/api/v1/parks/hybrid/'
|
||||
url = "/api/v1/parks/hybrid/"
|
||||
|
||||
# Test with extreme values
|
||||
response = self.client.get(url, {
|
||||
'rating_min': -100,
|
||||
'rating_max': 10000,
|
||||
'opening_year_min': 1,
|
||||
'opening_year_max': 9999,
|
||||
})
|
||||
response = self.client.get(
|
||||
url,
|
||||
{
|
||||
"rating_min": -100,
|
||||
"rating_max": 10000,
|
||||
"opening_year_min": 1,
|
||||
"opening_year_max": 9999,
|
||||
},
|
||||
)
|
||||
|
||||
# Should handle gracefully
|
||||
self.assertIn(response.status_code, [status.HTTP_200_OK, status.HTTP_400_BAD_REQUEST])
|
||||
|
||||
Reference in New Issue
Block a user