mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-23 05:11:10 -05:00
382 lines
13 KiB
Python
382 lines
13 KiB
Python
"""
|
|
Tests for Park managers and querysets.
|
|
|
|
Following Django styleguide pattern: test__<context>__<action>__<expected_outcome>
|
|
"""
|
|
|
|
import pytest
|
|
from django.test import TestCase
|
|
from django.utils import timezone
|
|
from datetime import timedelta
|
|
|
|
from apps.parks.models import Park, ParkArea, ParkReview, Company
|
|
from apps.parks.managers import (
|
|
ParkQuerySet,
|
|
ParkManager,
|
|
ParkAreaQuerySet,
|
|
ParkAreaManager,
|
|
ParkReviewQuerySet,
|
|
ParkReviewManager,
|
|
CompanyQuerySet,
|
|
CompanyManager,
|
|
)
|
|
|
|
from tests.factories import (
|
|
ParkFactory,
|
|
ParkAreaFactory,
|
|
ParkReviewFactory,
|
|
RideFactory,
|
|
CoasterFactory,
|
|
UserFactory,
|
|
OperatorCompanyFactory,
|
|
ManufacturerCompanyFactory,
|
|
)
|
|
|
|
|
|
@pytest.mark.django_db
|
|
class TestParkQuerySet(TestCase):
|
|
"""Tests for ParkQuerySet."""
|
|
|
|
def test__with_complete_stats__annotates_ride_counts(self):
|
|
"""Test with_complete_stats adds ride count annotations."""
|
|
park = ParkFactory()
|
|
RideFactory(park=park, category="TR")
|
|
RideFactory(park=park, category="TR")
|
|
CoasterFactory(park=park, category="RC")
|
|
|
|
result = Park.objects.with_complete_stats().get(pk=park.pk)
|
|
|
|
assert result.ride_count_calculated == 3
|
|
assert result.coaster_count_calculated == 1
|
|
|
|
def test__with_complete_stats__annotates_review_stats(self):
|
|
"""Test with_complete_stats adds review statistics."""
|
|
park = ParkFactory()
|
|
user1 = UserFactory()
|
|
user2 = UserFactory()
|
|
ParkReviewFactory(park=park, user=user1, is_published=True, rating=8)
|
|
ParkReviewFactory(park=park, user=user2, is_published=True, rating=6)
|
|
|
|
result = Park.objects.with_complete_stats().get(pk=park.pk)
|
|
|
|
assert result.review_count == 2
|
|
assert result.average_rating_calculated == 7.0
|
|
|
|
def test__with_complete_stats__excludes_unpublished_reviews(self):
|
|
"""Test review stats exclude unpublished reviews."""
|
|
park = ParkFactory()
|
|
user1 = UserFactory()
|
|
user2 = UserFactory()
|
|
ParkReviewFactory(park=park, user=user1, is_published=True, rating=10)
|
|
ParkReviewFactory(park=park, user=user2, is_published=False, rating=2)
|
|
|
|
result = Park.objects.with_complete_stats().get(pk=park.pk)
|
|
|
|
assert result.review_count == 1
|
|
assert result.average_rating_calculated == 10.0
|
|
|
|
def test__optimized_for_list__returns_prefetched_data(self):
|
|
"""Test optimized_for_list prefetches related data."""
|
|
ParkFactory()
|
|
ParkFactory()
|
|
|
|
queryset = Park.objects.optimized_for_list()
|
|
|
|
# Should have prefetch cache populated
|
|
assert queryset.count() == 2
|
|
|
|
def test__by_operator__filters_by_operator_id(self):
|
|
"""Test by_operator filters parks by operator."""
|
|
operator = OperatorCompanyFactory()
|
|
other_operator = OperatorCompanyFactory()
|
|
park1 = ParkFactory(operator=operator)
|
|
park2 = ParkFactory(operator=other_operator)
|
|
|
|
result = Park.objects.by_operator(operator_id=operator.pk)
|
|
|
|
assert park1 in result
|
|
assert park2 not in result
|
|
|
|
def test__by_property_owner__filters_by_owner_id(self):
|
|
"""Test by_property_owner filters parks by property owner."""
|
|
owner = OperatorCompanyFactory()
|
|
park1 = ParkFactory(property_owner=owner)
|
|
park2 = ParkFactory()
|
|
|
|
result = Park.objects.get_queryset().by_property_owner(owner_id=owner.pk)
|
|
|
|
assert park1 in result
|
|
assert park2 not in result
|
|
|
|
def test__with_minimum_coasters__filters_by_coaster_count(self):
|
|
"""Test with_minimum_coasters filters parks with enough coasters."""
|
|
park1 = ParkFactory()
|
|
park2 = ParkFactory()
|
|
|
|
# Add 5 coasters to park1
|
|
for _ in range(5):
|
|
CoasterFactory(park=park1)
|
|
|
|
# Add only 2 coasters to park2
|
|
for _ in range(2):
|
|
CoasterFactory(park=park2)
|
|
|
|
result = Park.objects.with_minimum_coasters(min_coasters=5)
|
|
|
|
assert park1 in result
|
|
assert park2 not in result
|
|
|
|
def test__large_parks__filters_by_size(self):
|
|
"""Test large_parks filters by minimum acreage."""
|
|
large_park = ParkFactory(size_acres=200)
|
|
small_park = ParkFactory(size_acres=50)
|
|
|
|
result = Park.objects.large_parks(min_acres=100)
|
|
|
|
assert large_park in result
|
|
assert small_park not in result
|
|
|
|
def test__seasonal_parks__excludes_empty_operating_season(self):
|
|
"""Test seasonal_parks excludes parks with empty operating_season."""
|
|
seasonal_park = ParkFactory(operating_season="Summer only")
|
|
year_round_park = ParkFactory(operating_season="")
|
|
|
|
result = Park.objects.get_queryset().seasonal_parks()
|
|
|
|
assert seasonal_park in result
|
|
assert year_round_park not in result
|
|
|
|
def test__search_autocomplete__searches_by_name(self):
|
|
"""Test search_autocomplete searches park names."""
|
|
park1 = ParkFactory(name="Cedar Point")
|
|
park2 = ParkFactory(name="Kings Island")
|
|
|
|
result = list(Park.objects.get_queryset().search_autocomplete(query="Cedar"))
|
|
|
|
assert park1 in result
|
|
assert park2 not in result
|
|
|
|
def test__search_autocomplete__limits_results(self):
|
|
"""Test search_autocomplete respects limit parameter."""
|
|
for i in range(15):
|
|
ParkFactory(name=f"Test Park {i}")
|
|
|
|
result = list(Park.objects.get_queryset().search_autocomplete(query="Test", limit=5))
|
|
|
|
assert len(result) == 5
|
|
|
|
|
|
@pytest.mark.django_db
|
|
class TestParkManager(TestCase):
|
|
"""Tests for ParkManager."""
|
|
|
|
def test__get_queryset__returns_park_queryset(self):
|
|
"""Test get_queryset returns ParkQuerySet."""
|
|
queryset = Park.objects.get_queryset()
|
|
|
|
assert isinstance(queryset, ParkQuerySet)
|
|
|
|
def test__operating__filters_operating_parks(self):
|
|
"""Test operating filters for operating status."""
|
|
operating = ParkFactory(status="OPERATING")
|
|
closed = ParkFactory(status="CLOSED_PERM")
|
|
|
|
result = Park.objects.operating()
|
|
|
|
assert operating in result
|
|
assert closed not in result
|
|
|
|
def test__closed__filters_closed_parks(self):
|
|
"""Test closed filters for closed statuses."""
|
|
operating = ParkFactory(status="OPERATING")
|
|
closed_temp = ParkFactory(status="CLOSED_TEMP")
|
|
closed_perm = ParkFactory(status="CLOSED_PERM")
|
|
|
|
result = Park.objects.closed()
|
|
|
|
assert operating not in result
|
|
assert closed_temp in result
|
|
assert closed_perm in result
|
|
|
|
|
|
@pytest.mark.django_db
|
|
class TestParkAreaQuerySet(TestCase):
|
|
"""Tests for ParkAreaQuerySet."""
|
|
|
|
def test__with_ride_counts__annotates_ride_count(self):
|
|
"""Test with_ride_counts adds ride count annotation."""
|
|
park = ParkFactory()
|
|
area = ParkAreaFactory(park=park)
|
|
RideFactory(park=park, park_area=area)
|
|
RideFactory(park=park, park_area=area)
|
|
CoasterFactory(park=park, park_area=area)
|
|
|
|
result = ParkArea.objects.with_ride_counts().get(pk=area.pk)
|
|
|
|
assert result.ride_count == 3
|
|
assert result.coaster_count == 1
|
|
|
|
def test__by_park__filters_by_park_id(self):
|
|
"""Test by_park filters areas by park."""
|
|
park1 = ParkFactory()
|
|
park2 = ParkFactory()
|
|
area1 = ParkAreaFactory(park=park1)
|
|
area2 = ParkAreaFactory(park=park2)
|
|
|
|
result = ParkArea.objects.by_park(park_id=park1.pk)
|
|
|
|
assert area1 in result
|
|
assert area2 not in result
|
|
|
|
def test__with_rides__filters_areas_with_rides(self):
|
|
"""Test with_rides filters areas that have rides."""
|
|
park = ParkFactory()
|
|
area_with_rides = ParkAreaFactory(park=park)
|
|
area_without_rides = ParkAreaFactory(park=park)
|
|
RideFactory(park=park, park_area=area_with_rides)
|
|
|
|
result = ParkArea.objects.get_queryset().with_rides()
|
|
|
|
assert area_with_rides in result
|
|
assert area_without_rides not in result
|
|
|
|
|
|
@pytest.mark.django_db
|
|
class TestParkReviewQuerySet(TestCase):
|
|
"""Tests for ParkReviewQuerySet."""
|
|
|
|
def test__for_park__filters_by_park_id(self):
|
|
"""Test for_park filters reviews by park."""
|
|
park1 = ParkFactory()
|
|
park2 = ParkFactory()
|
|
user = UserFactory()
|
|
review1 = ParkReviewFactory(park=park1, user=user)
|
|
user2 = UserFactory()
|
|
review2 = ParkReviewFactory(park=park2, user=user2)
|
|
|
|
result = ParkReview.objects.for_park(park_id=park1.pk)
|
|
|
|
assert review1 in result
|
|
assert review2 not in result
|
|
|
|
def test__by_user__filters_by_user_id(self):
|
|
"""Test by_user filters reviews by user."""
|
|
user1 = UserFactory()
|
|
user2 = UserFactory()
|
|
review1 = ParkReviewFactory(user=user1)
|
|
review2 = ParkReviewFactory(user=user2)
|
|
|
|
result = ParkReview.objects.get_queryset().by_user(user_id=user1.pk)
|
|
|
|
assert review1 in result
|
|
assert review2 not in result
|
|
|
|
def test__by_rating_range__filters_by_rating(self):
|
|
"""Test by_rating_range filters reviews by rating range."""
|
|
user1 = UserFactory()
|
|
user2 = UserFactory()
|
|
user3 = UserFactory()
|
|
high_review = ParkReviewFactory(rating=9, user=user1)
|
|
mid_review = ParkReviewFactory(rating=5, user=user2)
|
|
low_review = ParkReviewFactory(rating=2, user=user3)
|
|
|
|
result = ParkReview.objects.by_rating_range(min_rating=7, max_rating=10)
|
|
|
|
assert high_review in result
|
|
assert mid_review not in result
|
|
assert low_review not in result
|
|
|
|
def test__moderation_required__filters_unpublished_or_unmoderated(self):
|
|
"""Test moderation_required filters reviews needing moderation."""
|
|
user1 = UserFactory()
|
|
user2 = UserFactory()
|
|
published = ParkReviewFactory(is_published=True, user=user1)
|
|
unpublished = ParkReviewFactory(is_published=False, user=user2)
|
|
|
|
result = ParkReview.objects.moderation_required()
|
|
|
|
# unpublished should definitely be in result
|
|
assert unpublished in result
|
|
|
|
|
|
@pytest.mark.django_db
|
|
class TestCompanyQuerySet(TestCase):
|
|
"""Tests for CompanyQuerySet."""
|
|
|
|
def test__operators__filters_operator_companies(self):
|
|
"""Test operators filters for companies with OPERATOR role."""
|
|
operator = OperatorCompanyFactory()
|
|
manufacturer = ManufacturerCompanyFactory()
|
|
|
|
result = Company.objects.operators()
|
|
|
|
assert operator in result
|
|
assert manufacturer not in result
|
|
|
|
def test__manufacturers__filters_manufacturer_companies(self):
|
|
"""Test manufacturers filters for companies with MANUFACTURER role."""
|
|
operator = OperatorCompanyFactory()
|
|
manufacturer = ManufacturerCompanyFactory()
|
|
|
|
result = Company.objects.manufacturers()
|
|
|
|
assert manufacturer in result
|
|
assert operator not in result
|
|
|
|
def test__with_park_counts__annotates_park_counts(self):
|
|
"""Test with_park_counts adds park count annotations."""
|
|
operator = OperatorCompanyFactory()
|
|
ParkFactory(operator=operator)
|
|
ParkFactory(operator=operator)
|
|
ParkFactory(property_owner=operator)
|
|
|
|
result = Company.objects.get_queryset().with_park_counts().get(pk=operator.pk)
|
|
|
|
assert result.operated_parks_count == 2
|
|
assert result.owned_parks_count == 1
|
|
|
|
def test__major_operators__filters_by_minimum_parks(self):
|
|
"""Test major_operators filters by minimum park count."""
|
|
major_operator = OperatorCompanyFactory()
|
|
small_operator = OperatorCompanyFactory()
|
|
|
|
for _ in range(6):
|
|
ParkFactory(operator=major_operator)
|
|
for _ in range(2):
|
|
ParkFactory(operator=small_operator)
|
|
|
|
result = Company.objects.major_operators(min_parks=5)
|
|
|
|
assert major_operator in result
|
|
assert small_operator not in result
|
|
|
|
|
|
@pytest.mark.django_db
|
|
class TestCompanyManager(TestCase):
|
|
"""Tests for CompanyManager."""
|
|
|
|
def test__manufacturers_with_ride_count__annotates_ride_count(self):
|
|
"""Test manufacturers_with_ride_count adds ride count annotation."""
|
|
manufacturer = ManufacturerCompanyFactory()
|
|
RideFactory(manufacturer=manufacturer)
|
|
RideFactory(manufacturer=manufacturer)
|
|
RideFactory(manufacturer=manufacturer)
|
|
|
|
result = list(Company.objects.manufacturers_with_ride_count())
|
|
mfr = next((c for c in result if c.pk == manufacturer.pk), None)
|
|
|
|
assert mfr is not None
|
|
assert mfr.ride_count == 3
|
|
|
|
def test__operators_with_park_count__annotates_park_count(self):
|
|
"""Test operators_with_park_count adds park count annotation."""
|
|
operator = OperatorCompanyFactory()
|
|
ParkFactory(operator=operator)
|
|
ParkFactory(operator=operator)
|
|
|
|
result = list(Company.objects.operators_with_park_count())
|
|
op = next((c for c in result if c.pk == operator.pk), None)
|
|
|
|
assert op is not None
|
|
assert op.operated_parks_count == 2
|