mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 07:31:07 -05:00
remove backend
This commit is contained in:
382
tests/test_parks_api.py
Normal file
382
tests/test_parks_api.py
Normal file
@@ -0,0 +1,382 @@
|
||||
"""
|
||||
Test cases for Parks API following Django styleguide patterns.
|
||||
Comprehensive API endpoint testing with proper naming conventions.
|
||||
"""
|
||||
|
||||
from django.urls import reverse
|
||||
from rest_framework.test import APITestCase, APIClient
|
||||
from rest_framework import status
|
||||
|
||||
from apps.parks.models import Park
|
||||
from tests.factories import (
|
||||
UserFactory,
|
||||
StaffUserFactory,
|
||||
CompanyFactory,
|
||||
ParkFactory,
|
||||
)
|
||||
|
||||
|
||||
class TestParkListApi(APITestCase):
|
||||
"""Test cases for Park list API endpoint."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.client = APIClient()
|
||||
self.user = UserFactory()
|
||||
self.company = CompanyFactory(roles=["OPERATOR"])
|
||||
self.parks = [
|
||||
ParkFactory(operator=self.company, name="Park A"),
|
||||
ParkFactory(operator=self.company, name="Park B", status="CLOSED_TEMP"),
|
||||
ParkFactory(operator=self.company, name="Park C"),
|
||||
]
|
||||
self.url = reverse("parks_api:park-list")
|
||||
|
||||
def test__park_list_api__unauthenticated_user__can_access(self):
|
||||
"""Test that unauthenticated users can access park list."""
|
||||
response = self.client.get(self.url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["status"], "success")
|
||||
self.assertIsInstance(response.data["data"], list)
|
||||
|
||||
def test__park_list_api__returns_all_parks__in_correct_format(self):
|
||||
"""Test that park list returns all parks in correct format."""
|
||||
response = self.client.get(self.url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(len(response.data["data"]), 3)
|
||||
|
||||
# Check response structure
|
||||
park_data = response.data["data"][0]
|
||||
expected_fields = [
|
||||
"id",
|
||||
"name",
|
||||
"slug",
|
||||
"status",
|
||||
"description",
|
||||
"average_rating",
|
||||
"coaster_count",
|
||||
"ride_count",
|
||||
"location",
|
||||
"operator",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
]
|
||||
|
||||
for field in expected_fields:
|
||||
self.assertIn(field, park_data)
|
||||
|
||||
def test__park_list_api__with_status_filter__returns_filtered_results(
|
||||
self,
|
||||
):
|
||||
"""Test that status filter works correctly."""
|
||||
response = self.client.get(self.url, {"status": "OPERATING"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
# Should return only operating parks (2 out of 3)
|
||||
operating_parks = [
|
||||
p for p in response.data["data"] if p["status"] == "OPERATING"
|
||||
]
|
||||
self.assertEqual(len(operating_parks), 2)
|
||||
|
||||
def test__park_list_api__with_search_query__returns_matching_results(self):
|
||||
"""Test that search functionality works correctly."""
|
||||
response = self.client.get(self.url, {"search": "Park A"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(len(response.data["data"]), 1)
|
||||
self.assertEqual(response.data["data"][0]["name"], "Park A")
|
||||
|
||||
def test__park_list_api__with_ordering__returns_ordered_results(self):
|
||||
"""Test that ordering functionality works correctly."""
|
||||
response = self.client.get(self.url, {"ordering": "-name"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
# Should be ordered by name descending (C, B, A)
|
||||
names = [park["name"] for park in response.data["data"]]
|
||||
self.assertEqual(names, ["Park C", "Park B", "Park A"])
|
||||
|
||||
|
||||
class TestParkDetailApi(APITestCase):
|
||||
"""Test cases for Park detail API endpoint."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.client = APIClient()
|
||||
self.company = CompanyFactory(roles=["OPERATOR"])
|
||||
self.park = ParkFactory(operator=self.company)
|
||||
self.url = reverse("parks_api:park-detail", kwargs={"slug": self.park.slug})
|
||||
|
||||
def test__park_detail_api__with_valid_slug__returns_park_details(self):
|
||||
"""Test that park detail API returns correct park information."""
|
||||
response = self.client.get(self.url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["status"], "success")
|
||||
|
||||
park_data = response.data["data"]
|
||||
self.assertEqual(park_data["id"], self.park.id)
|
||||
self.assertEqual(park_data["name"], self.park.name)
|
||||
self.assertEqual(park_data["slug"], self.park.slug)
|
||||
|
||||
# Check that detailed fields are included
|
||||
detailed_fields = [
|
||||
"opening_date",
|
||||
"closing_date",
|
||||
"operating_season",
|
||||
"size_acres",
|
||||
"website",
|
||||
"areas",
|
||||
"operator",
|
||||
"property_owner",
|
||||
]
|
||||
|
||||
for field in detailed_fields:
|
||||
self.assertIn(field, park_data)
|
||||
|
||||
def test__park_detail_api__with_invalid_slug__returns_404(self):
|
||||
"""Test that invalid slug returns 404 error."""
|
||||
invalid_url = reverse("parks_api:park-detail", kwargs={"slug": "nonexistent"})
|
||||
response = self.client.get(invalid_url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
self.assertEqual(response.data["status"], "error")
|
||||
self.assertEqual(response.data["error"]["code"], "NOT_FOUND")
|
||||
|
||||
|
||||
class TestParkCreateApi(APITestCase):
|
||||
"""Test cases for Park creation API endpoint."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.client = APIClient()
|
||||
self.user = UserFactory()
|
||||
self.staff_user = StaffUserFactory()
|
||||
self.company = CompanyFactory(roles=["OPERATOR"])
|
||||
self.url = reverse("parks_api:park-list") # POST to list endpoint
|
||||
|
||||
self.valid_park_data = {
|
||||
"name": "New Test Park",
|
||||
"description": "A test park for API testing",
|
||||
"operator_id": self.company.id,
|
||||
"status": "OPERATING",
|
||||
}
|
||||
|
||||
def test__park_create_api__unauthenticated_user__returns_401(self):
|
||||
"""Test that unauthenticated users cannot create parks."""
|
||||
response = self.client.post(self.url, self.valid_park_data)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
def test__park_create_api__authenticated_user__can_create_park(self):
|
||||
"""Test that authenticated users can create parks."""
|
||||
self.client.force_authenticate(user=self.user)
|
||||
response = self.client.post(self.url, self.valid_park_data)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
self.assertEqual(response.data["status"], "success")
|
||||
|
||||
# Verify park was created
|
||||
park_data = response.data["data"]
|
||||
self.assertEqual(park_data["name"], "New Test Park")
|
||||
self.assertTrue(Park.objects.filter(name="New Test Park").exists())
|
||||
|
||||
def test__park_create_api__with_invalid_data__returns_validation_errors(
|
||||
self,
|
||||
):
|
||||
"""Test that invalid data returns proper validation errors."""
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
invalid_data = self.valid_park_data.copy()
|
||||
invalid_data["name"] = "" # Empty name should be invalid
|
||||
|
||||
response = self.client.post(self.url, invalid_data)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertEqual(response.data["status"], "error")
|
||||
self.assertIn("name", response.data["error"]["details"])
|
||||
|
||||
def test__park_create_api__with_invalid_date_range__returns_validation_error(
|
||||
self,
|
||||
):
|
||||
"""Test that invalid date ranges are caught by validation."""
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
invalid_data = self.valid_park_data.copy()
|
||||
invalid_data.update(
|
||||
{
|
||||
"opening_date": "2020-06-01",
|
||||
"closing_date": "2020-05-01", # Before opening date
|
||||
}
|
||||
)
|
||||
|
||||
response = self.client.post(self.url, invalid_data)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertIn("Closing date cannot be before opening date", str(response.data))
|
||||
|
||||
|
||||
class TestParkUpdateApi(APITestCase):
|
||||
"""Test cases for Park update API endpoint."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.client = APIClient()
|
||||
self.user = UserFactory()
|
||||
self.company = CompanyFactory(roles=["OPERATOR"])
|
||||
self.park = ParkFactory(operator=self.company)
|
||||
self.url = reverse("parks_api:park-detail", kwargs={"slug": self.park.slug})
|
||||
|
||||
def test__park_update_api__authenticated_user__can_update_park(self):
|
||||
"""Test that authenticated users can update parks."""
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
update_data = {
|
||||
"name": "Updated Park Name",
|
||||
"description": "Updated description",
|
||||
}
|
||||
|
||||
response = self.client.patch(self.url, update_data)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["status"], "success")
|
||||
|
||||
# Verify park was updated
|
||||
self.park.refresh_from_db()
|
||||
self.assertEqual(self.park.name, "Updated Park Name")
|
||||
self.assertEqual(self.park.description, "Updated description")
|
||||
|
||||
def test__park_update_api__with_invalid_data__returns_validation_errors(
|
||||
self,
|
||||
):
|
||||
"""Test that invalid update data returns validation errors."""
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
invalid_data = {
|
||||
"opening_date": "2020-06-01",
|
||||
"closing_date": "2020-05-01", # Invalid date range
|
||||
}
|
||||
|
||||
response = self.client.patch(self.url, invalid_data)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
class TestParkStatsApi(APITestCase):
|
||||
"""Test cases for Park statistics API endpoint."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.client = APIClient()
|
||||
self.company = CompanyFactory(roles=["OPERATOR"])
|
||||
|
||||
# Create parks with different statuses
|
||||
ParkFactory(operator=self.company, status="OPERATING")
|
||||
ParkFactory(operator=self.company, status="OPERATING")
|
||||
ParkFactory(operator=self.company, status="CLOSED_TEMP")
|
||||
|
||||
self.url = reverse("parks_api:park-stats")
|
||||
|
||||
def test__park_stats_api__returns_correct_statistics(self):
|
||||
"""Test that park statistics API returns correct data."""
|
||||
response = self.client.get(self.url)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["status"], "success")
|
||||
|
||||
stats = response.data["data"]
|
||||
expected_fields = [
|
||||
"total_parks",
|
||||
"operating_parks",
|
||||
"closed_parks",
|
||||
"under_construction",
|
||||
"average_rating",
|
||||
"recently_added_count",
|
||||
]
|
||||
|
||||
for field in expected_fields:
|
||||
self.assertIn(field, stats)
|
||||
|
||||
# Verify counts are correct
|
||||
self.assertEqual(stats["total_parks"], 3)
|
||||
self.assertEqual(stats["operating_parks"], 2)
|
||||
|
||||
|
||||
class TestParkApiErrorHandling(APITestCase):
|
||||
"""Test cases for Park API error handling."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.client = APIClient()
|
||||
|
||||
def test__park_api__with_malformed_json__returns_parse_error(self):
|
||||
"""Test that malformed JSON returns proper error."""
|
||||
url = reverse("parks_api:park-list")
|
||||
|
||||
response = self.client.post(
|
||||
url, data='{"invalid": json}', content_type="application/json"
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertEqual(response.data["status"], "error")
|
||||
|
||||
def test__park_api__with_unsupported_method__returns_405(self):
|
||||
"""Test that unsupported HTTP methods return 405."""
|
||||
park = ParkFactory()
|
||||
url = reverse("parks_api:park-detail", kwargs={"slug": park.slug})
|
||||
|
||||
response = self.client.head(url) # HEAD not supported
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)
|
||||
|
||||
|
||||
class TestParkApiIntegration(APITestCase):
|
||||
"""Integration tests for Park API with complete scenarios."""
|
||||
|
||||
def test__complete_park_workflow__create_update_retrieve_delete(self):
|
||||
"""Test complete CRUD workflow for parks."""
|
||||
user = UserFactory()
|
||||
company = CompanyFactory(roles=["OPERATOR"])
|
||||
self.client.force_authenticate(user=user)
|
||||
|
||||
# 1. Create park
|
||||
create_data = {
|
||||
"name": "Integration Test Park",
|
||||
"description": "A park for integration testing",
|
||||
"operator_id": company.id,
|
||||
}
|
||||
|
||||
create_response = self.client.post(reverse("parks_api:park-list"), create_data)
|
||||
|
||||
self.assertEqual(create_response.status_code, status.HTTP_201_CREATED)
|
||||
park_slug = create_response.data["data"]["slug"]
|
||||
|
||||
# 2. Retrieve park
|
||||
detail_url = reverse("parks_api:park-detail", kwargs={"slug": park_slug})
|
||||
retrieve_response = self.client.get(detail_url)
|
||||
|
||||
self.assertEqual(retrieve_response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(
|
||||
retrieve_response.data["data"]["name"], "Integration Test Park"
|
||||
)
|
||||
|
||||
# 3. Update park
|
||||
update_data = {"description": "Updated integration test description"}
|
||||
update_response = self.client.patch(detail_url, update_data)
|
||||
|
||||
self.assertEqual(update_response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(
|
||||
update_response.data["data"]["description"],
|
||||
"Updated integration test description",
|
||||
)
|
||||
|
||||
# 4. Delete park
|
||||
delete_response = self.client.delete(detail_url)
|
||||
|
||||
self.assertEqual(delete_response.status_code, status.HTTP_204_NO_CONTENT)
|
||||
|
||||
# 5. Verify park is deleted
|
||||
verify_response = self.client.get(detail_url)
|
||||
self.assertEqual(verify_response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
Reference in New Issue
Block a user