mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-30 21:47:04 -05:00
feat: Implement MFA authentication, add ride statistics model, and update various services, APIs, and tests across the application.
This commit is contained in:
@@ -5,20 +5,18 @@ These tests verify the functionality of park, area, company, location,
|
||||
and review admin classes including query optimization and custom actions.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from django.contrib.admin.sites import AdminSite
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import RequestFactory, TestCase
|
||||
|
||||
from apps.parks.admin import (
|
||||
CompanyAdmin,
|
||||
CompanyHeadquartersAdmin,
|
||||
ParkAdmin,
|
||||
ParkAreaAdmin,
|
||||
ParkLocationAdmin,
|
||||
ParkReviewAdmin,
|
||||
)
|
||||
from apps.parks.models import Company, CompanyHeadquarters, Park, ParkArea, ParkLocation, ParkReview
|
||||
from apps.parks.models import Company, Park, ParkArea, ParkLocation, ParkReview
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ This module tests end-to-end park lifecycle workflows including:
|
||||
- Related ride status updates
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import TestCase
|
||||
from django.utils import timezone
|
||||
|
||||
User = get_user_model()
|
||||
@@ -18,7 +18,7 @@ User = get_user_model()
|
||||
|
||||
class ParkOpeningWorkflowTests(TestCase):
|
||||
"""Tests for park opening workflow."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.user = User.objects.create_user(
|
||||
@@ -33,16 +33,16 @@ class ParkOpeningWorkflowTests(TestCase):
|
||||
password='testpass123',
|
||||
role='MODERATOR'
|
||||
)
|
||||
|
||||
|
||||
def _create_park(self, status='OPERATING', **kwargs):
|
||||
"""Helper to create a park."""
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
from apps.parks.models import Company, Park
|
||||
|
||||
operator = Company.objects.create(
|
||||
name=f'Operator {status}',
|
||||
roles=['OPERATOR']
|
||||
)
|
||||
|
||||
|
||||
defaults = {
|
||||
'name': f'Test Park {status}',
|
||||
'slug': f'test-park-{status.lower()}-{timezone.now().timestamp()}',
|
||||
@@ -52,28 +52,28 @@ class ParkOpeningWorkflowTests(TestCase):
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return Park.objects.create(**defaults)
|
||||
|
||||
|
||||
def test_park_opens_from_under_construction(self):
|
||||
"""
|
||||
Test park opening from under construction state.
|
||||
|
||||
|
||||
Flow: UNDER_CONSTRUCTION → OPERATING
|
||||
"""
|
||||
park = self._create_park(status='UNDER_CONSTRUCTION')
|
||||
|
||||
|
||||
self.assertEqual(park.status, 'UNDER_CONSTRUCTION')
|
||||
|
||||
|
||||
# Park opens
|
||||
park.transition_to_operating(user=self.user)
|
||||
park.save()
|
||||
|
||||
|
||||
park.refresh_from_db()
|
||||
self.assertEqual(park.status, 'OPERATING')
|
||||
|
||||
|
||||
class ParkTemporaryClosureWorkflowTests(TestCase):
|
||||
"""Tests for park temporary closure workflow."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.user = User.objects.create_user(
|
||||
@@ -82,15 +82,15 @@ class ParkTemporaryClosureWorkflowTests(TestCase):
|
||||
password='testpass123',
|
||||
role='USER'
|
||||
)
|
||||
|
||||
|
||||
def _create_park(self, status='OPERATING', **kwargs):
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
from apps.parks.models import Company, Park
|
||||
|
||||
operator = Company.objects.create(
|
||||
name=f'Operator Temp {timezone.now().timestamp()}',
|
||||
roles=['OPERATOR']
|
||||
)
|
||||
|
||||
|
||||
defaults = {
|
||||
'name': f'Test Park Temp {timezone.now().timestamp()}',
|
||||
'slug': f'test-park-temp-{timezone.now().timestamp()}',
|
||||
@@ -100,35 +100,35 @@ class ParkTemporaryClosureWorkflowTests(TestCase):
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return Park.objects.create(**defaults)
|
||||
|
||||
|
||||
def test_park_temporary_closure_and_reopen(self):
|
||||
"""
|
||||
Test park temporary closure and reopening.
|
||||
|
||||
|
||||
Flow: OPERATING → CLOSED_TEMP → OPERATING
|
||||
"""
|
||||
park = self._create_park(status='OPERATING')
|
||||
|
||||
|
||||
self.assertEqual(park.status, 'OPERATING')
|
||||
|
||||
|
||||
# Close temporarily (e.g., off-season)
|
||||
park.transition_to_closed_temp(user=self.user)
|
||||
park.save()
|
||||
|
||||
|
||||
park.refresh_from_db()
|
||||
self.assertEqual(park.status, 'CLOSED_TEMP')
|
||||
|
||||
|
||||
# Reopen
|
||||
park.transition_to_operating(user=self.user)
|
||||
park.save()
|
||||
|
||||
|
||||
park.refresh_from_db()
|
||||
self.assertEqual(park.status, 'OPERATING')
|
||||
|
||||
|
||||
class ParkPermanentClosureWorkflowTests(TestCase):
|
||||
"""Tests for park permanent closure workflow."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.moderator = User.objects.create_user(
|
||||
@@ -137,15 +137,15 @@ class ParkPermanentClosureWorkflowTests(TestCase):
|
||||
password='testpass123',
|
||||
role='MODERATOR'
|
||||
)
|
||||
|
||||
|
||||
def _create_park(self, status='OPERATING', **kwargs):
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
from apps.parks.models import Company, Park
|
||||
|
||||
operator = Company.objects.create(
|
||||
name=f'Operator Perm {timezone.now().timestamp()}',
|
||||
roles=['OPERATOR']
|
||||
)
|
||||
|
||||
|
||||
defaults = {
|
||||
'name': f'Test Park Perm {timezone.now().timestamp()}',
|
||||
'slug': f'test-park-perm-{timezone.now().timestamp()}',
|
||||
@@ -155,48 +155,48 @@ class ParkPermanentClosureWorkflowTests(TestCase):
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return Park.objects.create(**defaults)
|
||||
|
||||
|
||||
def test_park_permanent_closure(self):
|
||||
"""
|
||||
Test park permanent closure from operating state.
|
||||
|
||||
|
||||
Flow: OPERATING → CLOSED_PERM
|
||||
"""
|
||||
park = self._create_park(status='OPERATING')
|
||||
|
||||
|
||||
# Close permanently
|
||||
park.transition_to_closed_perm(user=self.moderator)
|
||||
park.closing_date = timezone.now().date()
|
||||
park.save()
|
||||
|
||||
|
||||
park.refresh_from_db()
|
||||
self.assertEqual(park.status, 'CLOSED_PERM')
|
||||
self.assertIsNotNone(park.closing_date)
|
||||
|
||||
|
||||
def test_park_permanent_closure_from_temp(self):
|
||||
"""
|
||||
Test park permanent closure from temporary closure.
|
||||
|
||||
|
||||
Flow: OPERATING → CLOSED_TEMP → CLOSED_PERM
|
||||
"""
|
||||
park = self._create_park(status='OPERATING')
|
||||
|
||||
|
||||
# Temporary closure
|
||||
park.transition_to_closed_temp(user=self.moderator)
|
||||
park.save()
|
||||
|
||||
|
||||
# Becomes permanent
|
||||
park.transition_to_closed_perm(user=self.moderator)
|
||||
park.closing_date = timezone.now().date()
|
||||
park.save()
|
||||
|
||||
|
||||
park.refresh_from_db()
|
||||
self.assertEqual(park.status, 'CLOSED_PERM')
|
||||
|
||||
|
||||
class ParkDemolitionWorkflowTests(TestCase):
|
||||
"""Tests for park demolition workflow."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.moderator = User.objects.create_user(
|
||||
@@ -205,15 +205,15 @@ class ParkDemolitionWorkflowTests(TestCase):
|
||||
password='testpass123',
|
||||
role='MODERATOR'
|
||||
)
|
||||
|
||||
|
||||
def _create_park(self, status='CLOSED_PERM', **kwargs):
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
from apps.parks.models import Company, Park
|
||||
|
||||
operator = Company.objects.create(
|
||||
name=f'Operator Demo {timezone.now().timestamp()}',
|
||||
roles=['OPERATOR']
|
||||
)
|
||||
|
||||
|
||||
defaults = {
|
||||
'name': f'Test Park Demo {timezone.now().timestamp()}',
|
||||
'slug': f'test-park-demo-{timezone.now().timestamp()}',
|
||||
@@ -223,28 +223,28 @@ class ParkDemolitionWorkflowTests(TestCase):
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return Park.objects.create(**defaults)
|
||||
|
||||
|
||||
def test_park_demolition_workflow(self):
|
||||
"""
|
||||
Test complete park demolition workflow.
|
||||
|
||||
|
||||
Flow: OPERATING → CLOSED_PERM → DEMOLISHED
|
||||
"""
|
||||
park = self._create_park(status='CLOSED_PERM')
|
||||
|
||||
|
||||
# Demolish
|
||||
park.transition_to_demolished(user=self.moderator)
|
||||
park.save()
|
||||
|
||||
|
||||
park.refresh_from_db()
|
||||
self.assertEqual(park.status, 'DEMOLISHED')
|
||||
|
||||
|
||||
def test_demolished_is_final_state(self):
|
||||
"""Test that demolished parks cannot transition further."""
|
||||
from django_fsm import TransitionNotAllowed
|
||||
|
||||
|
||||
park = self._create_park(status='DEMOLISHED')
|
||||
|
||||
|
||||
# Cannot transition from demolished
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
park.transition_to_operating(user=self.moderator)
|
||||
@@ -252,7 +252,7 @@ class ParkDemolitionWorkflowTests(TestCase):
|
||||
|
||||
class ParkRelocationWorkflowTests(TestCase):
|
||||
"""Tests for park relocation workflow."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.moderator = User.objects.create_user(
|
||||
@@ -261,15 +261,15 @@ class ParkRelocationWorkflowTests(TestCase):
|
||||
password='testpass123',
|
||||
role='MODERATOR'
|
||||
)
|
||||
|
||||
|
||||
def _create_park(self, status='CLOSED_PERM', **kwargs):
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
from apps.parks.models import Company, Park
|
||||
|
||||
operator = Company.objects.create(
|
||||
name=f'Operator Reloc {timezone.now().timestamp()}',
|
||||
roles=['OPERATOR']
|
||||
)
|
||||
|
||||
|
||||
defaults = {
|
||||
'name': f'Test Park Reloc {timezone.now().timestamp()}',
|
||||
'slug': f'test-park-reloc-{timezone.now().timestamp()}',
|
||||
@@ -279,28 +279,28 @@ class ParkRelocationWorkflowTests(TestCase):
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return Park.objects.create(**defaults)
|
||||
|
||||
|
||||
def test_park_relocation_workflow(self):
|
||||
"""
|
||||
Test park relocation workflow.
|
||||
|
||||
|
||||
Flow: OPERATING → CLOSED_PERM → RELOCATED
|
||||
"""
|
||||
park = self._create_park(status='CLOSED_PERM')
|
||||
|
||||
|
||||
# Relocate
|
||||
park.transition_to_relocated(user=self.moderator)
|
||||
park.save()
|
||||
|
||||
|
||||
park.refresh_from_db()
|
||||
self.assertEqual(park.status, 'RELOCATED')
|
||||
|
||||
|
||||
def test_relocated_is_final_state(self):
|
||||
"""Test that relocated parks cannot transition further."""
|
||||
from django_fsm import TransitionNotAllowed
|
||||
|
||||
|
||||
park = self._create_park(status='RELOCATED')
|
||||
|
||||
|
||||
# Cannot transition from relocated
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
park.transition_to_operating(user=self.moderator)
|
||||
@@ -308,7 +308,7 @@ class ParkRelocationWorkflowTests(TestCase):
|
||||
|
||||
class ParkWrapperMethodTests(TestCase):
|
||||
"""Tests for park wrapper methods."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.user = User.objects.create_user(
|
||||
@@ -323,15 +323,15 @@ class ParkWrapperMethodTests(TestCase):
|
||||
password='testpass123',
|
||||
role='MODERATOR'
|
||||
)
|
||||
|
||||
|
||||
def _create_park(self, status='OPERATING', **kwargs):
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
from apps.parks.models import Company, Park
|
||||
|
||||
operator = Company.objects.create(
|
||||
name=f'Operator Wrapper {timezone.now().timestamp()}',
|
||||
roles=['OPERATOR']
|
||||
)
|
||||
|
||||
|
||||
defaults = {
|
||||
'name': f'Test Park Wrapper {timezone.now().timestamp()}',
|
||||
'slug': f'test-park-wrapper-{timezone.now().timestamp()}',
|
||||
@@ -341,40 +341,40 @@ class ParkWrapperMethodTests(TestCase):
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return Park.objects.create(**defaults)
|
||||
|
||||
|
||||
def test_close_temporarily_wrapper(self):
|
||||
"""Test close_temporarily wrapper method."""
|
||||
park = self._create_park(status='OPERATING')
|
||||
|
||||
|
||||
# Use wrapper method if it exists
|
||||
if hasattr(park, 'close_temporarily'):
|
||||
park.close_temporarily(user=self.user)
|
||||
else:
|
||||
park.transition_to_closed_temp(user=self.user)
|
||||
park.save()
|
||||
|
||||
|
||||
park.refresh_from_db()
|
||||
self.assertEqual(park.status, 'CLOSED_TEMP')
|
||||
|
||||
|
||||
def test_reopen_wrapper(self):
|
||||
"""Test reopen wrapper method."""
|
||||
park = self._create_park(status='CLOSED_TEMP')
|
||||
|
||||
|
||||
# Use wrapper method if it exists
|
||||
if hasattr(park, 'reopen'):
|
||||
park.reopen(user=self.user)
|
||||
else:
|
||||
park.transition_to_operating(user=self.user)
|
||||
park.save()
|
||||
|
||||
|
||||
park.refresh_from_db()
|
||||
self.assertEqual(park.status, 'OPERATING')
|
||||
|
||||
|
||||
def test_close_permanently_wrapper(self):
|
||||
"""Test close_permanently wrapper method."""
|
||||
park = self._create_park(status='OPERATING')
|
||||
closing_date = timezone.now().date()
|
||||
|
||||
|
||||
# Use wrapper method if it exists
|
||||
if hasattr(park, 'close_permanently'):
|
||||
park.close_permanently(closing_date=closing_date, user=self.moderator)
|
||||
@@ -382,24 +382,24 @@ class ParkWrapperMethodTests(TestCase):
|
||||
park.transition_to_closed_perm(user=self.moderator)
|
||||
park.closing_date = closing_date
|
||||
park.save()
|
||||
|
||||
|
||||
park.refresh_from_db()
|
||||
self.assertEqual(park.status, 'CLOSED_PERM')
|
||||
|
||||
|
||||
def test_demolish_wrapper(self):
|
||||
"""Test demolish wrapper method."""
|
||||
park = self._create_park(status='CLOSED_PERM')
|
||||
|
||||
|
||||
# Use wrapper method if it exists
|
||||
if hasattr(park, 'demolish'):
|
||||
park.demolish(user=self.moderator)
|
||||
else:
|
||||
park.transition_to_demolished(user=self.moderator)
|
||||
park.save()
|
||||
|
||||
|
||||
park.refresh_from_db()
|
||||
self.assertEqual(park.status, 'DEMOLISHED')
|
||||
|
||||
|
||||
def test_relocate_wrapper(self):
|
||||
"""Test relocate wrapper method."""
|
||||
park = self._create_park(status='CLOSED_PERM')
|
||||
@@ -434,7 +434,7 @@ class ParkStateLogTests(TestCase):
|
||||
)
|
||||
|
||||
def _create_park(self, status='OPERATING', **kwargs):
|
||||
from apps.parks.models import Park, Company
|
||||
from apps.parks.models import Company, Park
|
||||
|
||||
operator = Company.objects.create(
|
||||
name=f'Operator Log {timezone.now().timestamp()}',
|
||||
@@ -453,8 +453,8 @@ class ParkStateLogTests(TestCase):
|
||||
|
||||
def test_transition_creates_state_log(self):
|
||||
"""Test that park transitions create StateLog entries."""
|
||||
from django_fsm_log.models import StateLog
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django_fsm_log.models import StateLog
|
||||
|
||||
park = self._create_park(status='OPERATING')
|
||||
park_ct = ContentType.objects.get_for_model(park)
|
||||
@@ -475,8 +475,8 @@ class ParkStateLogTests(TestCase):
|
||||
|
||||
def test_multiple_transitions_logged(self):
|
||||
"""Test that multiple park transitions are all logged."""
|
||||
from django_fsm_log.models import StateLog
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django_fsm_log.models import StateLog
|
||||
|
||||
park = self._create_park(status='OPERATING')
|
||||
park_ct = ContentType.objects.get_for_model(park)
|
||||
@@ -503,8 +503,8 @@ class ParkStateLogTests(TestCase):
|
||||
|
||||
def test_full_lifecycle_logged(self):
|
||||
"""Test complete park lifecycle is logged."""
|
||||
from django_fsm_log.models import StateLog
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django_fsm_log.models import StateLog
|
||||
|
||||
park = self._create_park(status='OPERATING')
|
||||
park_ct = ContentType.objects.get_for_model(park)
|
||||
|
||||
@@ -7,11 +7,11 @@ These tests verify that:
|
||||
3. Computed fields are updated correctly
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
from django.db import connection
|
||||
from django.test import TestCase
|
||||
from django.test.utils import CaptureQueriesContext
|
||||
|
||||
from apps.parks.models import Park, ParkLocation, Company
|
||||
from apps.parks.models import Company, Park, ParkLocation
|
||||
|
||||
|
||||
class ParkQueryOptimizationTests(TestCase):
|
||||
@@ -225,10 +225,9 @@ class ComputedFieldMaintenanceTests(TestCase):
|
||||
)
|
||||
|
||||
# Initially no location in search_text
|
||||
original_search_text = park.search_text
|
||||
|
||||
# Add location
|
||||
location = ParkLocation.objects.create(
|
||||
ParkLocation.objects.create(
|
||||
park=park,
|
||||
city="Orlando",
|
||||
state="Florida",
|
||||
|
||||
Reference in New Issue
Block a user