feat: Implement initial schema and add various API, service, and management command enhancements across the application.

This commit is contained in:
pacnpal
2026-01-01 15:13:01 -05:00
parent c95f99ca10
commit b243b17af7
413 changed files with 11164 additions and 17433 deletions

View File

@@ -45,25 +45,16 @@ class TestRideListAPIView(EnhancedAPITestCase):
park=self.park,
manufacturer=self.manufacturer,
designer=self.designer,
name='Alpha Coaster',
status='OPERATING',
category='RC'
name="Alpha Coaster",
status="OPERATING",
category="RC",
),
RideFactory(
park=self.park,
manufacturer=self.manufacturer,
name='Beta Ride',
status='OPERATING',
category='DR'
),
RideFactory(
park=self.park,
name='Gamma Coaster',
status='CLOSED_TEMP',
category='RC'
park=self.park, manufacturer=self.manufacturer, name="Beta Ride", status="OPERATING", category="DR"
),
RideFactory(park=self.park, name="Gamma Coaster", status="CLOSED_TEMP", category="RC"),
]
self.url = '/api/v1/rides/'
self.url = "/api/v1/rides/"
def test__ride_list__unauthenticated__can_access(self):
"""Test that unauthenticated users can access ride list."""
@@ -77,119 +68,109 @@ class TestRideListAPIView(EnhancedAPITestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK)
# Should have pagination info
self.assertIn('results', response.data)
self.assertIn('count', response.data)
self.assertIn("results", response.data)
self.assertIn("count", response.data)
def test__ride_list__with_search__returns_matching_rides(self):
"""Test search functionality."""
response = self.client.get(self.url, {'search': 'Alpha'})
response = self.client.get(self.url, {"search": "Alpha"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
# Should find Alpha Coaster
results = response.data.get('results', [])
results = response.data.get("results", [])
if results:
names = [r.get('name', '') for r in results]
self.assertTrue(any('Alpha' in name for name in names))
names = [r.get("name", "") for r in results]
self.assertTrue(any("Alpha" in name for name in names))
def test__ride_list__with_park_slug__returns_filtered_rides(self):
"""Test filtering by park slug."""
response = self.client.get(self.url, {'park_slug': self.park.slug})
response = self.client.get(self.url, {"park_slug": self.park.slug})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_park_id__returns_filtered_rides(self):
"""Test filtering by park ID."""
response = self.client.get(self.url, {'park_id': self.park.id})
response = self.client.get(self.url, {"park_id": self.park.id})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_category_filter__returns_filtered_rides(self):
"""Test filtering by category."""
response = self.client.get(self.url, {'category': 'RC'})
response = self.client.get(self.url, {"category": "RC"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
# All returned rides should be roller coasters
for ride in response.data.get('results', []):
self.assertEqual(ride.get('category'), 'RC')
for ride in response.data.get("results", []):
self.assertEqual(ride.get("category"), "RC")
def test__ride_list__with_status_filter__returns_filtered_rides(self):
"""Test filtering by status."""
response = self.client.get(self.url, {'status': 'OPERATING'})
response = self.client.get(self.url, {"status": "OPERATING"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
for ride in response.data.get('results', []):
self.assertEqual(ride.get('status'), 'OPERATING')
for ride in response.data.get("results", []):
self.assertEqual(ride.get("status"), "OPERATING")
def test__ride_list__with_manufacturer_filter__returns_filtered_rides(self):
"""Test filtering by manufacturer ID."""
response = self.client.get(self.url, {'manufacturer_id': self.manufacturer.id})
response = self.client.get(self.url, {"manufacturer_id": self.manufacturer.id})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_manufacturer_slug__returns_filtered_rides(self):
"""Test filtering by manufacturer slug."""
response = self.client.get(self.url, {'manufacturer_slug': self.manufacturer.slug})
response = self.client.get(self.url, {"manufacturer_slug": self.manufacturer.slug})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_designer_filter__returns_filtered_rides(self):
"""Test filtering by designer ID."""
response = self.client.get(self.url, {'designer_id': self.designer.id})
response = self.client.get(self.url, {"designer_id": self.designer.id})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_rating_filters__returns_filtered_rides(self):
"""Test filtering by rating range."""
response = self.client.get(self.url, {'min_rating': 5, 'max_rating': 10})
response = self.client.get(self.url, {"min_rating": 5, "max_rating": 10})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_height_requirement_filters__returns_filtered_rides(self):
"""Test filtering by height requirement."""
response = self.client.get(self.url, {
'min_height_requirement': 36,
'max_height_requirement': 54
})
response = self.client.get(self.url, {"min_height_requirement": 36, "max_height_requirement": 54})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_capacity_filters__returns_filtered_rides(self):
"""Test filtering by capacity."""
response = self.client.get(self.url, {'min_capacity': 500, 'max_capacity': 3000})
response = self.client.get(self.url, {"min_capacity": 500, "max_capacity": 3000})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_opening_year_filters__returns_filtered_rides(self):
"""Test filtering by opening year."""
response = self.client.get(self.url, {
'min_opening_year': 2000,
'max_opening_year': 2024
})
response = self.client.get(self.url, {"min_opening_year": 2000, "max_opening_year": 2024})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_ordering__returns_ordered_results(self):
"""Test ordering functionality."""
response = self.client.get(self.url, {'ordering': '-name'})
response = self.client.get(self.url, {"ordering": "-name"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_multiple_filters__returns_combined_results(self):
"""Test combining multiple filters."""
response = self.client.get(self.url, {
'category': 'RC',
'status': 'OPERATING',
'ordering': 'name'
})
response = self.client.get(self.url, {"category": "RC", "status": "OPERATING", "ordering": "name"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__pagination__page_size_respected(self):
"""Test that page_size parameter is respected."""
response = self.client.get(self.url, {'page_size': 1})
response = self.client.get(self.url, {"page_size": 1})
self.assertEqual(response.status_code, status.HTTP_200_OK)
results = response.data.get('results', [])
results = response.data.get("results", [])
self.assertLessEqual(len(results), 1)
@@ -203,14 +184,14 @@ class TestRideCreateAPIView(EnhancedAPITestCase):
self.staff_user = StaffUserFactory()
self.park = ParkFactory()
self.manufacturer = ManufacturerCompanyFactory()
self.url = '/api/v1/rides/'
self.url = "/api/v1/rides/"
self.valid_ride_data = {
'name': 'New Test Ride',
'description': 'A test ride for API testing',
'park_id': self.park.id,
'category': 'RC',
'status': 'OPERATING',
"name": "New Test Ride",
"description": "A test ride for API testing",
"park_id": self.park.id,
"category": "RC",
"status": "OPERATING",
}
def test__ride_create__unauthenticated__returns_401(self):
@@ -219,11 +200,9 @@ class TestRideCreateAPIView(EnhancedAPITestCase):
# Based on the view, AllowAny is used, so it might allow creation
# If not, it should be 401
self.assertIn(response.status_code, [
status.HTTP_201_CREATED,
status.HTTP_401_UNAUTHORIZED,
status.HTTP_400_BAD_REQUEST
])
self.assertIn(
response.status_code, [status.HTTP_201_CREATED, status.HTTP_401_UNAUTHORIZED, status.HTTP_400_BAD_REQUEST]
)
def test__ride_create__with_valid_data__creates_ride(self):
"""Test creating ride with valid data."""
@@ -231,39 +210,36 @@ class TestRideCreateAPIView(EnhancedAPITestCase):
response = self.client.post(self.url, self.valid_ride_data)
# Should create or return validation error if models not available
self.assertIn(response.status_code, [
status.HTTP_201_CREATED,
status.HTTP_400_BAD_REQUEST,
status.HTTP_501_NOT_IMPLEMENTED
])
self.assertIn(
response.status_code,
[status.HTTP_201_CREATED, status.HTTP_400_BAD_REQUEST, status.HTTP_501_NOT_IMPLEMENTED],
)
def test__ride_create__with_invalid_park__returns_error(self):
"""Test creating ride with invalid park ID."""
self.client.force_authenticate(user=self.user)
invalid_data = self.valid_ride_data.copy()
invalid_data['park_id'] = 99999
invalid_data["park_id"] = 99999
response = self.client.post(self.url, invalid_data)
self.assertIn(response.status_code, [
status.HTTP_400_BAD_REQUEST,
status.HTTP_404_NOT_FOUND,
status.HTTP_501_NOT_IMPLEMENTED
])
self.assertIn(
response.status_code,
[status.HTTP_400_BAD_REQUEST, status.HTTP_404_NOT_FOUND, status.HTTP_501_NOT_IMPLEMENTED],
)
def test__ride_create__with_manufacturer__creates_ride_with_relationship(self):
"""Test creating ride with manufacturer relationship."""
self.client.force_authenticate(user=self.user)
data_with_manufacturer = self.valid_ride_data.copy()
data_with_manufacturer['manufacturer_id'] = self.manufacturer.id
data_with_manufacturer["manufacturer_id"] = self.manufacturer.id
response = self.client.post(self.url, data_with_manufacturer)
self.assertIn(response.status_code, [
status.HTTP_201_CREATED,
status.HTTP_400_BAD_REQUEST,
status.HTTP_501_NOT_IMPLEMENTED
])
self.assertIn(
response.status_code,
[status.HTTP_201_CREATED, status.HTTP_400_BAD_REQUEST, status.HTTP_501_NOT_IMPLEMENTED],
)
class TestRideDetailAPIView(EnhancedAPITestCase):
@@ -275,7 +251,7 @@ class TestRideDetailAPIView(EnhancedAPITestCase):
self.user = UserFactory()
self.park = ParkFactory()
self.ride = RideFactory(park=self.park)
self.url = f'/api/v1/rides/{self.ride.id}/'
self.url = f"/api/v1/rides/{self.ride.id}/"
def test__ride_detail__unauthenticated__can_access(self):
"""Test that unauthenticated users can access ride detail."""
@@ -289,13 +265,13 @@ class TestRideDetailAPIView(EnhancedAPITestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK)
expected_fields = ['id', 'name', 'description', 'category', 'status', 'park']
expected_fields = ["id", "name", "description", "category", "status", "park"]
for field in expected_fields:
self.assertIn(field, response.data)
def test__ride_detail__invalid_id__returns_404(self):
"""Test that invalid ride ID returns 404."""
response = self.client.get('/api/v1/rides/99999/')
response = self.client.get("/api/v1/rides/99999/")
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
@@ -309,34 +285,30 @@ class TestRideUpdateAPIView(EnhancedAPITestCase):
self.user = UserFactory()
self.park = ParkFactory()
self.ride = RideFactory(park=self.park)
self.url = f'/api/v1/rides/{self.ride.id}/'
self.url = f"/api/v1/rides/{self.ride.id}/"
def test__ride_update__partial_update__updates_field(self):
"""Test partial update (PATCH)."""
self.client.force_authenticate(user=self.user)
update_data = {'description': 'Updated description'}
update_data = {"description": "Updated description"}
response = self.client.patch(self.url, update_data)
self.assertIn(response.status_code, [
status.HTTP_200_OK,
status.HTTP_401_UNAUTHORIZED,
status.HTTP_403_FORBIDDEN
])
self.assertIn(
response.status_code, [status.HTTP_200_OK, status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN]
)
def test__ride_update__move_to_new_park__updates_relationship(self):
"""Test moving ride to a different park."""
self.client.force_authenticate(user=self.user)
new_park = ParkFactory()
update_data = {'park_id': new_park.id}
update_data = {"park_id": new_park.id}
response = self.client.patch(self.url, update_data)
self.assertIn(response.status_code, [
status.HTTP_200_OK,
status.HTTP_401_UNAUTHORIZED,
status.HTTP_403_FORBIDDEN
])
self.assertIn(
response.status_code, [status.HTTP_200_OK, status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN]
)
class TestRideDeleteAPIView(EnhancedAPITestCase):
@@ -348,18 +320,16 @@ class TestRideDeleteAPIView(EnhancedAPITestCase):
self.user = UserFactory()
self.park = ParkFactory()
self.ride = RideFactory(park=self.park)
self.url = f'/api/v1/rides/{self.ride.id}/'
self.url = f"/api/v1/rides/{self.ride.id}/"
def test__ride_delete__authenticated__deletes_ride(self):
"""Test deleting a ride."""
self.client.force_authenticate(user=self.user)
response = self.client.delete(self.url)
self.assertIn(response.status_code, [
status.HTTP_204_NO_CONTENT,
status.HTTP_401_UNAUTHORIZED,
status.HTTP_403_FORBIDDEN
])
self.assertIn(
response.status_code, [status.HTTP_204_NO_CONTENT, status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN]
)
class TestFilterOptionsAPIView(EnhancedAPITestCase):
@@ -368,7 +338,7 @@ class TestFilterOptionsAPIView(EnhancedAPITestCase):
def setUp(self):
"""Set up test data."""
self.client = APIClient()
self.url = '/api/v1/rides/filter-options/'
self.url = "/api/v1/rides/filter-options/"
def test__filter_options__returns_all_options(self):
"""Test that filter options endpoint returns all filter options."""
@@ -377,7 +347,7 @@ class TestFilterOptionsAPIView(EnhancedAPITestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK)
# Check for expected filter categories
expected_keys = ['categories', 'statuses']
expected_keys = ["categories", "statuses"]
for key in expected_keys:
self.assertIn(key, response.data)
@@ -386,14 +356,14 @@ class TestFilterOptionsAPIView(EnhancedAPITestCase):
response = self.client.get(self.url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertIn('ranges', response.data)
self.assertIn("ranges", response.data)
def test__filter_options__includes_ordering_options(self):
"""Test that filter options include ordering options."""
response = self.client.get(self.url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertIn('ordering_options', response.data)
self.assertIn("ordering_options", response.data)
class TestHybridRideAPIView(EnhancedAPITestCase):
@@ -405,92 +375,86 @@ class TestHybridRideAPIView(EnhancedAPITestCase):
self.park = ParkFactory()
self.manufacturer = ManufacturerCompanyFactory()
self.rides = [
RideFactory(park=self.park, manufacturer=self.manufacturer, status='OPERATING', category='RC'),
RideFactory(park=self.park, status='OPERATING', category='DR'),
RideFactory(park=self.park, status='CLOSED_TEMP', category='RC'),
RideFactory(park=self.park, manufacturer=self.manufacturer, status="OPERATING", category="RC"),
RideFactory(park=self.park, status="OPERATING", category="DR"),
RideFactory(park=self.park, status="CLOSED_TEMP", category="RC"),
]
self.url = '/api/v1/rides/hybrid/'
self.url = "/api/v1/rides/hybrid/"
def test__hybrid_ride__initial_load__returns_rides(self):
"""Test initial load returns rides with metadata."""
response = self.client.get(self.url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertTrue(response.data.get('success', False))
self.assertIn('data', response.data)
self.assertIn('rides', response.data['data'])
self.assertIn('total_count', response.data['data'])
self.assertTrue(response.data.get("success", False))
self.assertIn("data", response.data)
self.assertIn("rides", response.data["data"])
self.assertIn("total_count", response.data["data"])
def test__hybrid_ride__with_category_filter__returns_filtered_rides(self):
"""Test filtering by category."""
response = self.client.get(self.url, {'category': 'RC'})
response = self.client.get(self.url, {"category": "RC"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__hybrid_ride__with_status_filter__returns_filtered_rides(self):
"""Test filtering by status."""
response = self.client.get(self.url, {'status': 'OPERATING'})
response = self.client.get(self.url, {"status": "OPERATING"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__hybrid_ride__with_park_slug__returns_filtered_rides(self):
"""Test filtering by park slug."""
response = self.client.get(self.url, {'park_slug': self.park.slug})
response = self.client.get(self.url, {"park_slug": self.park.slug})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__hybrid_ride__with_manufacturer_filter__returns_filtered_rides(self):
"""Test filtering by manufacturer."""
response = self.client.get(self.url, {'manufacturer': self.manufacturer.slug})
response = self.client.get(self.url, {"manufacturer": self.manufacturer.slug})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__hybrid_ride__with_offset__returns_progressive_data(self):
"""Test progressive loading with offset."""
response = self.client.get(self.url, {'offset': 0})
response = self.client.get(self.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_ride__with_invalid_offset__returns_400(self):
"""Test invalid offset parameter."""
response = self.client.get(self.url, {'offset': 'invalid'})
response = self.client.get(self.url, {"offset": "invalid"})
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
def test__hybrid_ride__with_search__returns_matching_rides(self):
"""Test search functionality."""
response = self.client.get(self.url, {'search': 'test'})
response = self.client.get(self.url, {"search": "test"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__hybrid_ride__with_rating_filters__returns_filtered_rides(self):
"""Test filtering by rating range."""
response = self.client.get(self.url, {'rating_min': 5.0, 'rating_max': 10.0})
response = self.client.get(self.url, {"rating_min": 5.0, "rating_max": 10.0})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__hybrid_ride__with_height_filters__returns_filtered_rides(self):
"""Test filtering by height requirement range."""
response = self.client.get(self.url, {
'height_requirement_min': 36,
'height_requirement_max': 54
})
response = self.client.get(self.url, {"height_requirement_min": 36, "height_requirement_max": 54})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__hybrid_ride__with_roller_coaster_filters__returns_filtered_rides(self):
"""Test filtering by roller coaster specific fields."""
response = self.client.get(self.url, {
'roller_coaster_type': 'SITDOWN',
'track_material': 'STEEL'
})
response = self.client.get(self.url, {"roller_coaster_type": "SITDOWN", "track_material": "STEEL"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__hybrid_ride__with_inversions_filter__returns_filtered_rides(self):
"""Test filtering by inversions."""
response = self.client.get(self.url, {'has_inversions': 'true'})
response = self.client.get(self.url, {"has_inversions": "true"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -501,19 +465,19 @@ class TestRideFilterMetadataAPIView(EnhancedAPITestCase):
def setUp(self):
"""Set up test data."""
self.client = APIClient()
self.url = '/api/v1/rides/filter-metadata/'
self.url = "/api/v1/rides/filter-metadata/"
def test__filter_metadata__unscoped__returns_all_metadata(self):
"""Test getting unscoped filter metadata."""
response = self.client.get(self.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."""
response = self.client.get(self.url, {'scoped': 'true', 'category': 'RC'})
response = self.client.get(self.url, {"scoped": "true", "category": "RC"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -524,19 +488,19 @@ class TestCompanySearchAPIView(EnhancedAPITestCase):
def setUp(self):
"""Set up test data."""
self.client = APIClient()
self.manufacturer = ManufacturerCompanyFactory(name='Bolliger & Mabillard')
self.url = '/api/v1/rides/search/companies/'
self.manufacturer = ManufacturerCompanyFactory(name="Bolliger & Mabillard")
self.url = "/api/v1/rides/search/companies/"
def test__company_search__with_query__returns_matching_companies(self):
"""Test searching for companies."""
response = self.client.get(self.url, {'q': 'Bolliger'})
response = self.client.get(self.url, {"q": "Bolliger"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertIsInstance(response.data, list)
def test__company_search__empty_query__returns_empty_list(self):
"""Test empty query returns empty list."""
response = self.client.get(self.url, {'q': ''})
response = self.client.get(self.url, {"q": ""})
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data, [])
@@ -555,19 +519,19 @@ class TestRideModelSearchAPIView(EnhancedAPITestCase):
def setUp(self):
"""Set up test data."""
self.client = APIClient()
self.ride_model = RideModelFactory(name='Hyper Coaster')
self.url = '/api/v1/rides/search-ride-models/'
self.ride_model = RideModelFactory(name="Hyper Coaster")
self.url = "/api/v1/rides/search-ride-models/"
def test__ride_model_search__with_query__returns_matching_models(self):
"""Test searching for ride models."""
response = self.client.get(self.url, {'q': 'Hyper'})
response = self.client.get(self.url, {"q": "Hyper"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertIsInstance(response.data, list)
def test__ride_model_search__empty_query__returns_empty_list(self):
"""Test empty query returns empty list."""
response = self.client.get(self.url, {'q': ''})
response = self.client.get(self.url, {"q": ""})
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data, [])
@@ -580,19 +544,19 @@ class TestRideSearchSuggestionsAPIView(EnhancedAPITestCase):
"""Set up test data."""
self.client = APIClient()
self.park = ParkFactory()
self.ride = RideFactory(park=self.park, name='Superman: Escape from Krypton')
self.url = '/api/v1/rides/search-suggestions/'
self.ride = RideFactory(park=self.park, name="Superman: Escape from Krypton")
self.url = "/api/v1/rides/search-suggestions/"
def test__search_suggestions__with_query__returns_suggestions(self):
"""Test getting search suggestions."""
response = self.client.get(self.url, {'q': 'Superman'})
response = self.client.get(self.url, {"q": "Superman"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertIsInstance(response.data, list)
def test__search_suggestions__empty_query__returns_empty_list(self):
"""Test empty query returns empty list."""
response = self.client.get(self.url, {'q': ''})
response = self.client.get(self.url, {"q": ""})
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data, [])
@@ -607,7 +571,7 @@ class TestRideImageSettingsAPIView(EnhancedAPITestCase):
self.user = UserFactory()
self.park = ParkFactory()
self.ride = RideFactory(park=self.park)
self.url = f'/api/v1/rides/{self.ride.id}/image-settings/'
self.url = f"/api/v1/rides/{self.ride.id}/image-settings/"
def test__image_settings__patch__updates_settings(self):
"""Test updating ride image settings."""
@@ -616,17 +580,15 @@ class TestRideImageSettingsAPIView(EnhancedAPITestCase):
response = self.client.patch(self.url, {})
# Should handle the request
self.assertIn(response.status_code, [
status.HTTP_200_OK,
status.HTTP_400_BAD_REQUEST,
status.HTTP_401_UNAUTHORIZED
])
self.assertIn(
response.status_code, [status.HTTP_200_OK, status.HTTP_400_BAD_REQUEST, status.HTTP_401_UNAUTHORIZED]
)
def test__image_settings__invalid_ride__returns_404(self):
"""Test updating image settings for non-existent ride."""
self.client.force_authenticate(user=self.user)
response = self.client.patch('/api/v1/rides/99999/image-settings/', {})
response = self.client.patch("/api/v1/rides/99999/image-settings/", {})
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
@@ -639,55 +601,55 @@ class TestRideAPIRollerCoasterFilters(EnhancedAPITestCase):
self.client = APIClient()
self.park = ParkFactory()
# Create coasters with different stats
self.coaster1 = CoasterFactory(park=self.park, name='Steel Vengeance')
self.coaster2 = CoasterFactory(park=self.park, name='Millennium Force')
self.url = '/api/v1/rides/'
self.coaster1 = CoasterFactory(park=self.park, name="Steel Vengeance")
self.coaster2 = CoasterFactory(park=self.park, name="Millennium Force")
self.url = "/api/v1/rides/"
def test__ride_list__with_roller_coaster_type__filters_correctly(self):
"""Test filtering by roller coaster type."""
response = self.client.get(self.url, {'roller_coaster_type': 'SITDOWN'})
response = self.client.get(self.url, {"roller_coaster_type": "SITDOWN"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_track_material__filters_correctly(self):
"""Test filtering by track material."""
response = self.client.get(self.url, {'track_material': 'STEEL'})
response = self.client.get(self.url, {"track_material": "STEEL"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_propulsion_system__filters_correctly(self):
"""Test filtering by propulsion system."""
response = self.client.get(self.url, {'propulsion_system': 'CHAIN'})
response = self.client.get(self.url, {"propulsion_system": "CHAIN"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_height_ft_range__filters_correctly(self):
"""Test filtering by height in feet."""
response = self.client.get(self.url, {'min_height_ft': 100, 'max_height_ft': 500})
response = self.client.get(self.url, {"min_height_ft": 100, "max_height_ft": 500})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_speed_mph_range__filters_correctly(self):
"""Test filtering by speed in mph."""
response = self.client.get(self.url, {'min_speed_mph': 50, 'max_speed_mph': 150})
response = self.client.get(self.url, {"min_speed_mph": 50, "max_speed_mph": 150})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__with_inversions_range__filters_correctly(self):
"""Test filtering by number of inversions."""
response = self.client.get(self.url, {'min_inversions': 0, 'max_inversions': 14})
response = self.client.get(self.url, {"min_inversions": 0, "max_inversions": 14})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__ordering_by_height__orders_correctly(self):
"""Test ordering by height."""
response = self.client.get(self.url, {'ordering': '-height_ft'})
response = self.client.get(self.url, {"ordering": "-height_ft"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test__ride_list__ordering_by_speed__orders_correctly(self):
"""Test ordering by speed."""
response = self.client.get(self.url, {'ordering': '-speed_mph'})
response = self.client.get(self.url, {"ordering": "-speed_mph"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -702,7 +664,7 @@ class TestRideAPIEdgeCases(EnhancedAPITestCase):
def test__ride_list__empty_database__returns_empty_list(self):
"""Test API behavior with no rides in database."""
# This depends on existing data, just verify no error
response = self.client.get('/api/v1/rides/')
response = self.client.get("/api/v1/rides/")
self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -716,20 +678,20 @@ class TestRideAPIEdgeCases(EnhancedAPITestCase):
]
for search_term in special_searches:
response = self.client.get('/api/v1/rides/', {'search': search_term})
response = self.client.get("/api/v1/rides/", {"search": search_term})
# Should not crash
self.assertIn(response.status_code, [status.HTTP_200_OK, status.HTTP_400_BAD_REQUEST])
def test__ride_list__extreme_pagination__handled_safely(self):
"""Test extreme pagination values."""
response = self.client.get('/api/v1/rides/', {'page': 99999, 'page_size': 1000})
response = self.client.get("/api/v1/rides/", {"page": 99999, "page_size": 1000})
# Should handle gracefully
self.assertIn(response.status_code, [status.HTTP_200_OK, status.HTTP_404_NOT_FOUND])
def test__ride_list__invalid_ordering__handled_safely(self):
"""Test invalid ordering parameter."""
response = self.client.get('/api/v1/rides/', {'ordering': 'invalid_field'})
response = self.client.get("/api/v1/rides/", {"ordering": "invalid_field"})
# Should use default ordering
self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -749,7 +711,7 @@ class TestRideAPIQueryOptimization(EnhancedAPITestCase):
for _i in range(5):
RideFactory(park=self.park)
response = self.client.get('/api/v1/rides/')
response = self.client.get("/api/v1/rides/")
self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -757,8 +719,8 @@ class TestRideAPIQueryOptimization(EnhancedAPITestCase):
"""Test that ride list handles larger datasets efficiently."""
# Create batch of rides
for i in range(10):
RideFactory(park=self.park, name=f'Ride {i}')
RideFactory(park=self.park, name=f"Ride {i}")
response = self.client.get('/api/v1/rides/')
response = self.client.get("/api/v1/rides/")
self.assertEqual(response.status_code, status.HTTP_200_OK)