mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-30 15:07:03 -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,7 +5,6 @@ These tests verify the functionality of ride, model, stats, company,
|
||||
review, and ranking 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
|
||||
@@ -14,7 +13,6 @@ from apps.rides.admin import (
|
||||
CompanyAdmin,
|
||||
RankingSnapshotAdmin,
|
||||
RideAdmin,
|
||||
RideLocationAdmin,
|
||||
RideModelAdmin,
|
||||
RidePairComparisonAdmin,
|
||||
RideRankingAdmin,
|
||||
@@ -22,7 +20,6 @@ from apps.rides.admin import (
|
||||
RollerCoasterStatsAdmin,
|
||||
)
|
||||
from apps.rides.models.company import Company
|
||||
from apps.rides.models.location import RideLocation
|
||||
from apps.rides.models.rankings import RankingSnapshot, RidePairComparison, RideRanking
|
||||
from apps.rides.models.reviews import RideReview
|
||||
from apps.rides.models.rides import Ride, RideModel, RollerCoasterStats
|
||||
|
||||
@@ -10,17 +10,18 @@ This module tests end-to-end ride lifecycle workflows including:
|
||||
- Ride relocation workflow
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.utils import timezone
|
||||
from datetime import timedelta
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import TestCase
|
||||
from django.utils import timezone
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class RideOpeningWorkflowTests(TestCase):
|
||||
"""Tests for ride opening workflow."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.user = User.objects.create_user(
|
||||
@@ -29,18 +30,18 @@ class RideOpeningWorkflowTests(TestCase):
|
||||
password='testpass123',
|
||||
role='USER'
|
||||
)
|
||||
|
||||
|
||||
def _create_ride(self, status='OPERATING', **kwargs):
|
||||
"""Helper to create a ride with park."""
|
||||
from apps.parks.models import Company, Park
|
||||
from apps.rides.models import Ride
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
|
||||
# Create manufacturer
|
||||
manufacturer = Company.objects.create(
|
||||
name=f'Manufacturer {timezone.now().timestamp()}',
|
||||
roles=['MANUFACTURER']
|
||||
)
|
||||
|
||||
|
||||
# Create park with operator
|
||||
operator = Company.objects.create(
|
||||
name=f'Operator {timezone.now().timestamp()}',
|
||||
@@ -53,7 +54,7 @@ class RideOpeningWorkflowTests(TestCase):
|
||||
status='OPERATING',
|
||||
timezone='America/New_York'
|
||||
)
|
||||
|
||||
|
||||
defaults = {
|
||||
'name': f'Test Ride {timezone.now().timestamp()}',
|
||||
'slug': f'test-ride-{timezone.now().timestamp()}',
|
||||
@@ -63,28 +64,28 @@ class RideOpeningWorkflowTests(TestCase):
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return Ride.objects.create(**defaults)
|
||||
|
||||
|
||||
def test_ride_opens_from_under_construction(self):
|
||||
"""
|
||||
Test ride opening from under construction state.
|
||||
|
||||
|
||||
Flow: UNDER_CONSTRUCTION → OPERATING
|
||||
"""
|
||||
ride = self._create_ride(status='UNDER_CONSTRUCTION')
|
||||
|
||||
|
||||
self.assertEqual(ride.status, 'UNDER_CONSTRUCTION')
|
||||
|
||||
|
||||
# Ride opens
|
||||
ride.transition_to_operating(user=self.user)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'OPERATING')
|
||||
|
||||
|
||||
class RideMaintenanceWorkflowTests(TestCase):
|
||||
"""Tests for ride maintenance (temporary closure) workflow."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.user = User.objects.create_user(
|
||||
@@ -93,11 +94,11 @@ class RideMaintenanceWorkflowTests(TestCase):
|
||||
password='testpass123',
|
||||
role='USER'
|
||||
)
|
||||
|
||||
|
||||
def _create_ride(self, status='OPERATING', **kwargs):
|
||||
from apps.parks.models import Company, Park
|
||||
from apps.rides.models import Ride
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
|
||||
manufacturer = Company.objects.create(
|
||||
name=f'Mfr Maint {timezone.now().timestamp()}',
|
||||
roles=['MANUFACTURER']
|
||||
@@ -113,7 +114,7 @@ class RideMaintenanceWorkflowTests(TestCase):
|
||||
status='OPERATING',
|
||||
timezone='America/New_York'
|
||||
)
|
||||
|
||||
|
||||
defaults = {
|
||||
'name': f'Ride Maint {timezone.now().timestamp()}',
|
||||
'slug': f'ride-maint-{timezone.now().timestamp()}',
|
||||
@@ -123,33 +124,33 @@ class RideMaintenanceWorkflowTests(TestCase):
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return Ride.objects.create(**defaults)
|
||||
|
||||
|
||||
def test_ride_maintenance_and_reopen(self):
|
||||
"""
|
||||
Test ride maintenance and reopening.
|
||||
|
||||
|
||||
Flow: OPERATING → CLOSED_TEMP → OPERATING
|
||||
"""
|
||||
ride = self._create_ride(status='OPERATING')
|
||||
|
||||
|
||||
# Close for maintenance
|
||||
ride.transition_to_closed_temp(user=self.user)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'CLOSED_TEMP')
|
||||
|
||||
|
||||
# Reopen after maintenance
|
||||
ride.transition_to_operating(user=self.user)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'OPERATING')
|
||||
|
||||
|
||||
class RideSBNOWorkflowTests(TestCase):
|
||||
"""Tests for ride SBNO (Standing But Not Operating) workflow."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.moderator = User.objects.create_user(
|
||||
@@ -158,11 +159,11 @@ class RideSBNOWorkflowTests(TestCase):
|
||||
password='testpass123',
|
||||
role='MODERATOR'
|
||||
)
|
||||
|
||||
|
||||
def _create_ride(self, status='OPERATING', **kwargs):
|
||||
from apps.parks.models import Company, Park
|
||||
from apps.rides.models import Ride
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
|
||||
manufacturer = Company.objects.create(
|
||||
name=f'Mfr SBNO {timezone.now().timestamp()}',
|
||||
roles=['MANUFACTURER']
|
||||
@@ -178,7 +179,7 @@ class RideSBNOWorkflowTests(TestCase):
|
||||
status='OPERATING',
|
||||
timezone='America/New_York'
|
||||
)
|
||||
|
||||
|
||||
defaults = {
|
||||
'name': f'Ride SBNO {timezone.now().timestamp()}',
|
||||
'slug': f'ride-sbno-{timezone.now().timestamp()}',
|
||||
@@ -188,71 +189,71 @@ class RideSBNOWorkflowTests(TestCase):
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return Ride.objects.create(**defaults)
|
||||
|
||||
|
||||
def test_ride_sbno_from_operating(self):
|
||||
"""
|
||||
Test ride becomes SBNO from operating.
|
||||
|
||||
|
||||
Flow: OPERATING → SBNO
|
||||
"""
|
||||
ride = self._create_ride(status='OPERATING')
|
||||
|
||||
|
||||
# Mark as SBNO
|
||||
ride.transition_to_sbno(user=self.moderator)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'SBNO')
|
||||
|
||||
|
||||
def test_ride_sbno_from_closed_temp(self):
|
||||
"""
|
||||
Test ride becomes SBNO from temporary closure.
|
||||
|
||||
|
||||
Flow: OPERATING → CLOSED_TEMP → SBNO
|
||||
"""
|
||||
ride = self._create_ride(status='CLOSED_TEMP')
|
||||
|
||||
|
||||
# Extended to SBNO
|
||||
ride.transition_to_sbno(user=self.moderator)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'SBNO')
|
||||
|
||||
|
||||
def test_ride_revival_from_sbno(self):
|
||||
"""
|
||||
Test ride revival from SBNO state.
|
||||
|
||||
|
||||
Flow: SBNO → OPERATING
|
||||
"""
|
||||
ride = self._create_ride(status='SBNO')
|
||||
|
||||
|
||||
# Revive the ride
|
||||
ride.transition_to_operating(user=self.moderator)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'OPERATING')
|
||||
|
||||
|
||||
def test_sbno_to_closed_perm(self):
|
||||
"""
|
||||
Test ride permanently closes from SBNO.
|
||||
|
||||
|
||||
Flow: SBNO → CLOSED_PERM
|
||||
"""
|
||||
ride = self._create_ride(status='SBNO')
|
||||
|
||||
|
||||
# Confirm permanent closure
|
||||
ride.transition_to_closed_perm(user=self.moderator)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'CLOSED_PERM')
|
||||
|
||||
|
||||
class RideScheduledClosureWorkflowTests(TestCase):
|
||||
"""Tests for ride scheduled closure (CLOSING state) workflow."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.moderator = User.objects.create_user(
|
||||
@@ -261,11 +262,11 @@ class RideScheduledClosureWorkflowTests(TestCase):
|
||||
password='testpass123',
|
||||
role='MODERATOR'
|
||||
)
|
||||
|
||||
|
||||
def _create_ride(self, status='OPERATING', **kwargs):
|
||||
from apps.parks.models import Company, Park
|
||||
from apps.rides.models import Ride
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
|
||||
manufacturer = Company.objects.create(
|
||||
name=f'Mfr Closing {timezone.now().timestamp()}',
|
||||
roles=['MANUFACTURER']
|
||||
@@ -281,7 +282,7 @@ class RideScheduledClosureWorkflowTests(TestCase):
|
||||
status='OPERATING',
|
||||
timezone='America/New_York'
|
||||
)
|
||||
|
||||
|
||||
defaults = {
|
||||
'name': f'Ride Closing {timezone.now().timestamp()}',
|
||||
'slug': f'ride-closing-{timezone.now().timestamp()}',
|
||||
@@ -291,67 +292,67 @@ class RideScheduledClosureWorkflowTests(TestCase):
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return Ride.objects.create(**defaults)
|
||||
|
||||
|
||||
def test_ride_mark_closing_with_date(self):
|
||||
"""
|
||||
Test ride marked as closing with scheduled date.
|
||||
|
||||
|
||||
Flow: OPERATING → CLOSING (with closing_date and post_closing_status)
|
||||
"""
|
||||
ride = self._create_ride(status='OPERATING')
|
||||
closing_date = (timezone.now() + timedelta(days=30)).date()
|
||||
|
||||
|
||||
# Mark as closing
|
||||
ride.transition_to_closing(user=self.moderator)
|
||||
ride.closing_date = closing_date
|
||||
ride.post_closing_status = 'DEMOLISHED'
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'CLOSING')
|
||||
self.assertEqual(ride.closing_date, closing_date)
|
||||
self.assertEqual(ride.post_closing_status, 'DEMOLISHED')
|
||||
|
||||
|
||||
def test_closing_to_closed_perm(self):
|
||||
"""
|
||||
Test ride transitions from CLOSING to CLOSED_PERM when date reached.
|
||||
|
||||
|
||||
Flow: CLOSING → CLOSED_PERM
|
||||
"""
|
||||
ride = self._create_ride(status='CLOSING')
|
||||
ride.closing_date = timezone.now().date()
|
||||
ride.post_closing_status = 'CLOSED_PERM'
|
||||
ride.save()
|
||||
|
||||
|
||||
# Transition when closing date reached
|
||||
ride.transition_to_closed_perm(user=self.moderator)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'CLOSED_PERM')
|
||||
|
||||
|
||||
def test_closing_to_sbno(self):
|
||||
"""
|
||||
Test ride transitions from CLOSING to SBNO.
|
||||
|
||||
|
||||
Flow: CLOSING → SBNO
|
||||
"""
|
||||
ride = self._create_ride(status='CLOSING')
|
||||
ride.closing_date = timezone.now().date()
|
||||
ride.post_closing_status = 'SBNO'
|
||||
ride.save()
|
||||
|
||||
|
||||
# Transition to SBNO
|
||||
ride.transition_to_sbno(user=self.moderator)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'SBNO')
|
||||
|
||||
|
||||
class RideDemolitionWorkflowTests(TestCase):
|
||||
"""Tests for ride demolition workflow."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.moderator = User.objects.create_user(
|
||||
@@ -360,11 +361,11 @@ class RideDemolitionWorkflowTests(TestCase):
|
||||
password='testpass123',
|
||||
role='MODERATOR'
|
||||
)
|
||||
|
||||
|
||||
def _create_ride(self, status='CLOSED_PERM', **kwargs):
|
||||
from apps.parks.models import Company, Park
|
||||
from apps.rides.models import Ride
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
|
||||
manufacturer = Company.objects.create(
|
||||
name=f'Mfr Demo {timezone.now().timestamp()}',
|
||||
roles=['MANUFACTURER']
|
||||
@@ -380,7 +381,7 @@ class RideDemolitionWorkflowTests(TestCase):
|
||||
status='OPERATING',
|
||||
timezone='America/New_York'
|
||||
)
|
||||
|
||||
|
||||
defaults = {
|
||||
'name': f'Ride Demo {timezone.now().timestamp()}',
|
||||
'slug': f'ride-demo-{timezone.now().timestamp()}',
|
||||
@@ -390,28 +391,28 @@ class RideDemolitionWorkflowTests(TestCase):
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return Ride.objects.create(**defaults)
|
||||
|
||||
|
||||
def test_ride_demolition(self):
|
||||
"""
|
||||
Test ride demolition from permanently closed.
|
||||
|
||||
|
||||
Flow: CLOSED_PERM → DEMOLISHED
|
||||
"""
|
||||
ride = self._create_ride(status='CLOSED_PERM')
|
||||
|
||||
|
||||
# Demolish
|
||||
ride.transition_to_demolished(user=self.moderator)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'DEMOLISHED')
|
||||
|
||||
|
||||
def test_demolished_is_final_state(self):
|
||||
"""Test that demolished rides cannot transition further."""
|
||||
from django_fsm import TransitionNotAllowed
|
||||
|
||||
|
||||
ride = self._create_ride(status='DEMOLISHED')
|
||||
|
||||
|
||||
# Cannot transition from demolished
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
ride.transition_to_operating(user=self.moderator)
|
||||
@@ -419,7 +420,7 @@ class RideDemolitionWorkflowTests(TestCase):
|
||||
|
||||
class RideRelocationWorkflowTests(TestCase):
|
||||
"""Tests for ride relocation workflow."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.moderator = User.objects.create_user(
|
||||
@@ -428,11 +429,11 @@ class RideRelocationWorkflowTests(TestCase):
|
||||
password='testpass123',
|
||||
role='MODERATOR'
|
||||
)
|
||||
|
||||
|
||||
def _create_ride(self, status='CLOSED_PERM', **kwargs):
|
||||
from apps.parks.models import Company, Park
|
||||
from apps.rides.models import Ride
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
|
||||
manufacturer = Company.objects.create(
|
||||
name=f'Mfr Reloc {timezone.now().timestamp()}',
|
||||
roles=['MANUFACTURER']
|
||||
@@ -448,7 +449,7 @@ class RideRelocationWorkflowTests(TestCase):
|
||||
status='OPERATING',
|
||||
timezone='America/New_York'
|
||||
)
|
||||
|
||||
|
||||
defaults = {
|
||||
'name': f'Ride Reloc {timezone.now().timestamp()}',
|
||||
'slug': f'ride-reloc-{timezone.now().timestamp()}',
|
||||
@@ -458,28 +459,28 @@ class RideRelocationWorkflowTests(TestCase):
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return Ride.objects.create(**defaults)
|
||||
|
||||
|
||||
def test_ride_relocation(self):
|
||||
"""
|
||||
Test ride relocation from permanently closed.
|
||||
|
||||
|
||||
Flow: CLOSED_PERM → RELOCATED
|
||||
"""
|
||||
ride = self._create_ride(status='CLOSED_PERM')
|
||||
|
||||
|
||||
# Relocate
|
||||
ride.transition_to_relocated(user=self.moderator)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'RELOCATED')
|
||||
|
||||
|
||||
def test_relocated_is_final_state(self):
|
||||
"""Test that relocated rides cannot transition further."""
|
||||
from django_fsm import TransitionNotAllowed
|
||||
|
||||
|
||||
ride = self._create_ride(status='RELOCATED')
|
||||
|
||||
|
||||
# Cannot transition from relocated
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
ride.transition_to_operating(user=self.moderator)
|
||||
@@ -487,7 +488,7 @@ class RideRelocationWorkflowTests(TestCase):
|
||||
|
||||
class RideWrapperMethodTests(TestCase):
|
||||
"""Tests for ride wrapper methods."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.user = User.objects.create_user(
|
||||
@@ -502,11 +503,11 @@ class RideWrapperMethodTests(TestCase):
|
||||
password='testpass123',
|
||||
role='MODERATOR'
|
||||
)
|
||||
|
||||
|
||||
def _create_ride(self, status='OPERATING', **kwargs):
|
||||
from apps.parks.models import Company, Park
|
||||
from apps.rides.models import Ride
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
|
||||
manufacturer = Company.objects.create(
|
||||
name=f'Mfr Wrapper {timezone.now().timestamp()}',
|
||||
roles=['MANUFACTURER']
|
||||
@@ -522,7 +523,7 @@ class RideWrapperMethodTests(TestCase):
|
||||
status='OPERATING',
|
||||
timezone='America/New_York'
|
||||
)
|
||||
|
||||
|
||||
defaults = {
|
||||
'name': f'Ride Wrapper {timezone.now().timestamp()}',
|
||||
'slug': f'ride-wrapper-{timezone.now().timestamp()}',
|
||||
@@ -532,38 +533,38 @@ class RideWrapperMethodTests(TestCase):
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return Ride.objects.create(**defaults)
|
||||
|
||||
|
||||
def test_close_temporarily_wrapper(self):
|
||||
"""Test close_temporarily wrapper method."""
|
||||
ride = self._create_ride(status='OPERATING')
|
||||
|
||||
|
||||
if hasattr(ride, 'close_temporarily'):
|
||||
ride.close_temporarily(user=self.user)
|
||||
else:
|
||||
ride.transition_to_closed_temp(user=self.user)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'CLOSED_TEMP')
|
||||
|
||||
|
||||
def test_mark_sbno_wrapper(self):
|
||||
"""Test mark_sbno wrapper method."""
|
||||
ride = self._create_ride(status='OPERATING')
|
||||
|
||||
|
||||
if hasattr(ride, 'mark_sbno'):
|
||||
ride.mark_sbno(user=self.moderator)
|
||||
else:
|
||||
ride.transition_to_sbno(user=self.moderator)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'SBNO')
|
||||
|
||||
|
||||
def test_mark_closing_wrapper(self):
|
||||
"""Test mark_closing wrapper method."""
|
||||
ride = self._create_ride(status='OPERATING')
|
||||
closing_date = (timezone.now() + timedelta(days=30)).date()
|
||||
|
||||
|
||||
if hasattr(ride, 'mark_closing'):
|
||||
ride.mark_closing(
|
||||
closing_date=closing_date,
|
||||
@@ -575,66 +576,66 @@ class RideWrapperMethodTests(TestCase):
|
||||
ride.closing_date = closing_date
|
||||
ride.post_closing_status = 'DEMOLISHED'
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'CLOSING')
|
||||
|
||||
|
||||
def test_open_wrapper(self):
|
||||
"""Test open wrapper method."""
|
||||
ride = self._create_ride(status='CLOSED_TEMP')
|
||||
|
||||
|
||||
if hasattr(ride, 'open'):
|
||||
ride.open(user=self.user)
|
||||
else:
|
||||
ride.transition_to_operating(user=self.user)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'OPERATING')
|
||||
|
||||
|
||||
def test_close_permanently_wrapper(self):
|
||||
"""Test close_permanently wrapper method."""
|
||||
ride = self._create_ride(status='SBNO')
|
||||
|
||||
|
||||
if hasattr(ride, 'close_permanently'):
|
||||
ride.close_permanently(user=self.moderator)
|
||||
else:
|
||||
ride.transition_to_closed_perm(user=self.moderator)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'CLOSED_PERM')
|
||||
|
||||
|
||||
def test_demolish_wrapper(self):
|
||||
"""Test demolish wrapper method."""
|
||||
ride = self._create_ride(status='CLOSED_PERM')
|
||||
|
||||
|
||||
if hasattr(ride, 'demolish'):
|
||||
ride.demolish(user=self.moderator)
|
||||
else:
|
||||
ride.transition_to_demolished(user=self.moderator)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'DEMOLISHED')
|
||||
|
||||
|
||||
def test_relocate_wrapper(self):
|
||||
"""Test relocate wrapper method."""
|
||||
ride = self._create_ride(status='CLOSED_PERM')
|
||||
|
||||
|
||||
if hasattr(ride, 'relocate'):
|
||||
ride.relocate(user=self.moderator)
|
||||
else:
|
||||
ride.transition_to_relocated(user=self.moderator)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'RELOCATED')
|
||||
|
||||
|
||||
class RidePostClosingStatusAutomationTests(TestCase):
|
||||
"""Tests for post_closing_status automation logic."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.moderator = User.objects.create_user(
|
||||
@@ -643,11 +644,11 @@ class RidePostClosingStatusAutomationTests(TestCase):
|
||||
password='testpass123',
|
||||
role='MODERATOR'
|
||||
)
|
||||
|
||||
|
||||
def _create_ride(self, status='CLOSING', **kwargs):
|
||||
from apps.parks.models import Company, Park
|
||||
from apps.rides.models import Ride
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
|
||||
manufacturer = Company.objects.create(
|
||||
name=f'Mfr Auto {timezone.now().timestamp()}',
|
||||
roles=['MANUFACTURER']
|
||||
@@ -663,7 +664,7 @@ class RidePostClosingStatusAutomationTests(TestCase):
|
||||
status='OPERATING',
|
||||
timezone='America/New_York'
|
||||
)
|
||||
|
||||
|
||||
defaults = {
|
||||
'name': f'Ride Auto {timezone.now().timestamp()}',
|
||||
'slug': f'ride-auto-{timezone.now().timestamp()}',
|
||||
@@ -673,40 +674,40 @@ class RidePostClosingStatusAutomationTests(TestCase):
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return Ride.objects.create(**defaults)
|
||||
|
||||
|
||||
def test_apply_post_closing_status_demolished(self):
|
||||
"""Test apply_post_closing_status transitions to DEMOLISHED."""
|
||||
ride = self._create_ride(status='CLOSING')
|
||||
ride.closing_date = timezone.now().date()
|
||||
ride.post_closing_status = 'DEMOLISHED'
|
||||
ride.save()
|
||||
|
||||
|
||||
# Apply post-closing status if method exists
|
||||
if hasattr(ride, 'apply_post_closing_status'):
|
||||
ride.apply_post_closing_status(user=self.moderator)
|
||||
else:
|
||||
ride.transition_to_demolished(user=self.moderator)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'DEMOLISHED')
|
||||
|
||||
|
||||
def test_apply_post_closing_status_relocated(self):
|
||||
"""Test apply_post_closing_status transitions to RELOCATED."""
|
||||
ride = self._create_ride(status='CLOSING')
|
||||
ride.closing_date = timezone.now().date()
|
||||
ride.post_closing_status = 'RELOCATED'
|
||||
ride.save()
|
||||
|
||||
|
||||
if hasattr(ride, 'apply_post_closing_status'):
|
||||
ride.apply_post_closing_status(user=self.moderator)
|
||||
else:
|
||||
ride.transition_to_relocated(user=self.moderator)
|
||||
ride.save()
|
||||
|
||||
|
||||
ride.refresh_from_db()
|
||||
self.assertEqual(ride.status, 'RELOCATED')
|
||||
|
||||
|
||||
def test_apply_post_closing_status_sbno(self):
|
||||
"""Test apply_post_closing_status transitions to SBNO."""
|
||||
ride = self._create_ride(status='CLOSING')
|
||||
@@ -743,8 +744,8 @@ class RideStateLogTests(TestCase):
|
||||
)
|
||||
|
||||
def _create_ride(self, status='OPERATING', **kwargs):
|
||||
from apps.parks.models import Company, Park
|
||||
from apps.rides.models import Ride
|
||||
from apps.parks.models import Park, Company
|
||||
|
||||
manufacturer = Company.objects.create(
|
||||
name=f'Mfr Log {timezone.now().timestamp()}',
|
||||
@@ -774,8 +775,8 @@ class RideStateLogTests(TestCase):
|
||||
|
||||
def test_transition_creates_state_log(self):
|
||||
"""Test that ride 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
|
||||
|
||||
ride = self._create_ride(status='OPERATING')
|
||||
ride_ct = ContentType.objects.get_for_model(ride)
|
||||
@@ -796,8 +797,8 @@ class RideStateLogTests(TestCase):
|
||||
|
||||
def test_multiple_transitions_logged(self):
|
||||
"""Test that multiple ride 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
|
||||
|
||||
ride = self._create_ride(status='OPERATING')
|
||||
ride_ct = ContentType.objects.get_for_model(ride)
|
||||
@@ -822,8 +823,8 @@ class RideStateLogTests(TestCase):
|
||||
|
||||
def test_sbno_revival_workflow_logged(self):
|
||||
"""Test that SBNO revival workflow is logged."""
|
||||
from django_fsm_log.models import StateLog
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django_fsm_log.models import StateLog
|
||||
|
||||
ride = self._create_ride(status='SBNO')
|
||||
ride_ct = ContentType.objects.get_for_model(ride)
|
||||
@@ -844,8 +845,8 @@ class RideStateLogTests(TestCase):
|
||||
|
||||
def test_full_lifecycle_logged(self):
|
||||
"""Test complete ride lifecycle is logged."""
|
||||
from django_fsm_log.models import StateLog
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django_fsm_log.models import StateLog
|
||||
|
||||
ride = self._create_ride(status='OPERATING')
|
||||
ride_ct = ContentType.objects.get_for_model(ride)
|
||||
@@ -875,8 +876,8 @@ class RideStateLogTests(TestCase):
|
||||
|
||||
def test_scheduled_closing_workflow_logged(self):
|
||||
"""Test that scheduled closing workflow creates logs."""
|
||||
from django_fsm_log.models import StateLog
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django_fsm_log.models import StateLog
|
||||
|
||||
ride = self._create_ride(status='OPERATING')
|
||||
ride_ct = ContentType.objects.get_for_model(ride)
|
||||
|
||||
Reference in New Issue
Block a user