Files
thrillwiki_django_no_react/tests/test_parks_models.py
pacnpal 75cc618c2b update
2025-09-21 20:04:42 -04:00

250 lines
9.2 KiB
Python

"""
Test cases for Parks models following Django styleguide patterns.
Uses proper naming conventions and comprehensive coverage.
"""
from datetime import date, timedelta
from django.test import TestCase
from django.db import IntegrityError
from django.utils import timezone
from apps.parks.models import Park, Company
from tests.factories import (
UserFactory,
CompanyFactory,
ParkFactory,
ParkAreaFactory,
ParkReviewFactory,
TestScenarios,
)
class TestParkModel(TestCase):
"""Test cases for the Park model."""
def setUp(self):
"""Set up test data."""
self.company = CompanyFactory(roles=["OPERATOR"])
self.user = UserFactory()
def test__park_creation__with_valid_data__succeeds(self):
"""Test that park can be created with valid data."""
park = ParkFactory(operator=self.company)
self.assertIsInstance(park.id, int)
self.assertEqual(park.operator, self.company)
self.assertEqual(park.status, "OPERATING")
self.assertIsNotNone(park.created_at)
def test__park_str_representation__returns_park_name(self):
"""Test that park string representation returns the name."""
park = ParkFactory(name="Test Park", operator=self.company)
self.assertEqual(str(park), "Test Park")
def test__park_slug__is_automatically_generated(self):
"""Test that park slug is generated from name."""
park = ParkFactory(name="Amazing Theme Park", operator=self.company)
self.assertEqual(park.slug, "amazing-theme-park")
def test__park_constraints__closing_date_after_opening__is_enforced(self):
"""Test that closing date must be after opening date."""
with self.assertRaises(IntegrityError):
ParkFactory(
operator=self.company,
opening_date=date(2020, 6, 1),
closing_date=date(2020, 5, 1), # Before opening
)
def test__park_constraints__positive_size__is_enforced(self):
"""Test that park size must be positive."""
with self.assertRaises(IntegrityError):
ParkFactory(operator=self.company, size_acres=-10)
def test__park_constraints__rating_range__is_enforced(self):
"""Test that rating must be within valid range."""
# Test upper bound
with self.assertRaises(IntegrityError):
ParkFactory(operator=self.company, average_rating=11)
# Test lower bound
with self.assertRaises(IntegrityError):
ParkFactory(operator=self.company, average_rating=0)
def test__park_constraints__coaster_count_lte_ride_count__is_enforced(
self,
):
"""Test that coaster count cannot exceed ride count."""
with self.assertRaises(IntegrityError):
ParkFactory(
operator=self.company,
ride_count=5,
coaster_count=10, # More coasters than total rides
)
def test__park_relationships__operator_is_required(self):
"""Test that park must have an operator."""
with self.assertRaises(IntegrityError):
Park.objects.create(
name="Test Park",
slug="test-park",
# Missing operator
)
def test__park_relationships__property_owner_is_optional(self):
"""Test that property owner is optional."""
park = ParkFactory(operator=self.company, property_owner=None)
self.assertIsNone(park.property_owner)
self.assertEqual(park.operator, self.company)
class TestParkModelManagers(TestCase):
"""Test cases for Park model custom managers."""
def setUp(self):
"""Set up test data."""
self.company = CompanyFactory(roles=["OPERATOR"])
self.operating_park = ParkFactory(operator=self.company, status="OPERATING")
self.closed_park = ParkFactory(operator=self.company, status="CLOSED_TEMP")
def test__park_manager__operating_filter__returns_only_operating_parks(
self,
):
"""Test that operating() filter returns only operating parks."""
operating_parks = Park.objects.operating()
self.assertEqual(operating_parks.count(), 1)
self.assertEqual(operating_parks.first(), self.operating_park)
def test__park_manager__closed_filter__returns_only_closed_parks(self):
"""Test that closed() filter returns only closed parks."""
closed_parks = Park.objects.closed()
self.assertEqual(closed_parks.count(), 1)
self.assertEqual(closed_parks.first(), self.closed_park)
def test__park_manager__optimized_for_list__includes_stats(self):
"""Test that optimized_for_list includes statistical annotations."""
parks = Park.objects.optimized_for_list()
park = parks.first()
# Check that statistical fields are available
self.assertTrue(hasattr(park, "ride_count_calculated"))
self.assertTrue(hasattr(park, "coaster_count_calculated"))
self.assertTrue(hasattr(park, "area_count"))
class TestParkAreaModel(TestCase):
"""Test cases for the ParkArea model."""
def setUp(self):
"""Set up test data."""
self.company = CompanyFactory(roles=["OPERATOR"])
self.park = ParkFactory(operator=self.company)
def test__park_area_creation__with_valid_data__succeeds(self):
"""Test that park area can be created with valid data."""
area = ParkAreaFactory(park=self.park)
self.assertIsInstance(area.id, int)
self.assertEqual(area.park, self.park)
self.assertIsNotNone(area.created_at)
def test__park_area_unique_constraint__park_and_slug__is_enforced(self):
"""Test that park+slug combination must be unique."""
ParkAreaFactory(park=self.park, slug="test-area")
with self.assertRaises(IntegrityError):
ParkAreaFactory(park=self.park, slug="test-area") # Duplicate
class TestCompanyModel(TestCase):
"""Test cases for the Company model."""
def test__company_creation__with_valid_data__succeeds(self):
"""Test that company can be created with valid data."""
company = CompanyFactory()
self.assertIsInstance(company.id, int)
self.assertIsInstance(company.roles, list)
self.assertIsNotNone(company.created_at)
def test__company_manager__operators_filter__returns_only_operators(self):
"""Test that operators() filter works correctly."""
operator = CompanyFactory(roles=["OPERATOR"])
manufacturer = CompanyFactory(roles=["MANUFACTURER"])
operators = Company.objects.operators()
self.assertIn(operator, operators)
self.assertNotIn(manufacturer, operators)
class TestParkReviewModel(TestCase):
"""Test cases for the ParkReview model."""
def setUp(self):
"""Set up test data."""
self.company = CompanyFactory(roles=["OPERATOR"])
self.park = ParkFactory(operator=self.company)
self.user = UserFactory()
def test__park_review_creation__with_valid_data__succeeds(self):
"""Test that park review can be created with valid data."""
review = ParkReviewFactory(park=self.park, user=self.user)
self.assertIsInstance(review.id, int)
self.assertEqual(review.park, self.park)
self.assertEqual(review.user, self.user)
self.assertTrue(1 <= review.rating <= 10)
def test__park_review_constraints__rating_range__is_enforced(self):
"""Test that review rating must be within valid range."""
with self.assertRaises(IntegrityError):
ParkReviewFactory(park=self.park, user=self.user, rating=11)
def test__park_review_constraints__visit_date_not_future__is_enforced(
self,
):
"""Test that visit date cannot be in the future."""
future_date = timezone.now().date() + timedelta(days=1)
with self.assertRaises(IntegrityError):
ParkReviewFactory(park=self.park, user=self.user, visit_date=future_date)
def test__park_review_unique_constraint__park_and_user__is_enforced(self):
"""Test that user can only review each park once."""
ParkReviewFactory(park=self.park, user=self.user)
with self.assertRaises(IntegrityError):
ParkReviewFactory(park=self.park, user=self.user) # Duplicate
class TestParkModelIntegration(TestCase):
"""Integration tests for Park model with related models."""
def test__complete_park_scenario__with_all_relationships__works_correctly(
self,
):
"""Test complete park creation with all relationships."""
scenario = TestScenarios.complete_park_with_rides(num_rides=3)
park = scenario["park"]
scenario["rides"]
areas = scenario["areas"]
reviews = scenario["reviews"]
# Verify all relationships are properly created
self.assertEqual(park.rides.count(), 3)
self.assertEqual(park.areas.count(), len(areas))
self.assertEqual(park.reviews.filter(is_published=True).count(), len(reviews))
# Test that park statistics are calculated correctly
parks_with_stats = Park.objects.with_complete_stats()
park_with_stats = parks_with_stats.get(id=park.id)
self.assertEqual(park_with_stats.ride_count_calculated, 3)
self.assertIsNotNone(park_with_stats.average_rating_calculated)