""" Tests for RideService. Following Django styleguide pattern: test______ """ import pytest from unittest.mock import Mock, patch, MagicMock from django.test import TestCase from django.core.exceptions import ValidationError from apps.rides.services import RideService from apps.rides.models import Ride from tests.factories import ( ParkFactory, RideFactory, RideModelFactory, ParkAreaFactory, UserFactory, ManufacturerCompanyFactory, DesignerCompanyFactory, ) @pytest.mark.django_db class TestRideServiceCreateRide(TestCase): """Tests for RideService.create_ride.""" def test__create_ride__valid_data__creates_ride(self): """Test create_ride creates ride with valid data.""" park = ParkFactory() user = UserFactory() ride = RideService.create_ride( name="Test Ride", park_id=park.pk, description="A test ride", status="OPERATING", category="TR", created_by=user, ) assert ride.name == "Test Ride" assert ride.park == park assert ride.description == "A test ride" assert ride.status == "OPERATING" assert ride.category == "TR" def test__create_ride__with_manufacturer__sets_manufacturer(self): """Test create_ride sets manufacturer when provided.""" park = ParkFactory() manufacturer = ManufacturerCompanyFactory() ride = RideService.create_ride( name="Test Ride", park_id=park.pk, category="RC", manufacturer_id=manufacturer.pk, ) assert ride.manufacturer == manufacturer def test__create_ride__with_designer__sets_designer(self): """Test create_ride sets designer when provided.""" park = ParkFactory() designer = DesignerCompanyFactory() ride = RideService.create_ride( name="Test Ride", park_id=park.pk, category="RC", designer_id=designer.pk, ) assert ride.designer == designer def test__create_ride__with_ride_model__sets_ride_model(self): """Test create_ride sets ride model when provided.""" park = ParkFactory() ride_model = RideModelFactory() ride = RideService.create_ride( name="Test Ride", park_id=park.pk, category="RC", ride_model_id=ride_model.pk, ) assert ride.ride_model == ride_model def test__create_ride__with_park_area__sets_park_area(self): """Test create_ride sets park area when provided.""" park = ParkFactory() area = ParkAreaFactory(park=park) ride = RideService.create_ride( name="Test Ride", park_id=park.pk, category="TR", park_area_id=area.pk, ) assert ride.park_area == area def test__create_ride__invalid_park__raises_exception(self): """Test create_ride raises exception for invalid park.""" with pytest.raises(Exception): RideService.create_ride( name="Test Ride", park_id=99999, # Non-existent category="TR", ) @pytest.mark.django_db class TestRideServiceUpdateRide(TestCase): """Tests for RideService.update_ride.""" def test__update_ride__valid_updates__updates_ride(self): """Test update_ride updates ride with valid data.""" ride = RideFactory(name="Original Name", description="Original desc") updated_ride = RideService.update_ride( ride_id=ride.pk, updates={"name": "Updated Name", "description": "Updated desc"}, ) assert updated_ride.name == "Updated Name" assert updated_ride.description == "Updated desc" def test__update_ride__partial_updates__updates_only_specified_fields(self): """Test update_ride only updates specified fields.""" ride = RideFactory(name="Original", status="OPERATING") updated_ride = RideService.update_ride( ride_id=ride.pk, updates={"name": "New Name"}, ) assert updated_ride.name == "New Name" assert updated_ride.status == "OPERATING" # Unchanged def test__update_ride__nonexistent_ride__raises_exception(self): """Test update_ride raises exception for non-existent ride.""" with pytest.raises(Ride.DoesNotExist): RideService.update_ride( ride_id=99999, updates={"name": "New Name"}, ) @pytest.mark.django_db class TestRideServiceCloseRideTemporarily(TestCase): """Tests for RideService.close_ride_temporarily.""" def test__close_ride_temporarily__operating_ride__changes_status(self): """Test close_ride_temporarily changes status to CLOSED_TEMP.""" ride = RideFactory(status="OPERATING") user = UserFactory() result = RideService.close_ride_temporarily(ride_id=ride.pk, user=user) assert result.status == "CLOSED_TEMP" def test__close_ride_temporarily__nonexistent_ride__raises_exception(self): """Test close_ride_temporarily raises exception for non-existent ride.""" with pytest.raises(Ride.DoesNotExist): RideService.close_ride_temporarily(ride_id=99999) @pytest.mark.django_db class TestRideServiceMarkRideSBNO(TestCase): """Tests for RideService.mark_ride_sbno.""" def test__mark_ride_sbno__operating_ride__changes_status(self): """Test mark_ride_sbno changes status to SBNO.""" ride = RideFactory(status="OPERATING") user = UserFactory() result = RideService.mark_ride_sbno(ride_id=ride.pk, user=user) assert result.status == "SBNO" @pytest.mark.django_db class TestRideServiceScheduleRideClosing(TestCase): """Tests for RideService.schedule_ride_closing.""" def test__schedule_ride_closing__valid_data__schedules_closing(self): """Test schedule_ride_closing schedules ride closing.""" from datetime import date, timedelta ride = RideFactory(status="OPERATING") user = UserFactory() closing_date = date.today() + timedelta(days=30) result = RideService.schedule_ride_closing( ride_id=ride.pk, closing_date=closing_date, post_closing_status="DEMOLISHED", user=user, ) assert result.status == "CLOSING" assert result.closing_date == closing_date assert result.post_closing_status == "DEMOLISHED" @pytest.mark.django_db class TestRideServiceCloseRidePermanently(TestCase): """Tests for RideService.close_ride_permanently.""" def test__close_ride_permanently__operating_ride__changes_status(self): """Test close_ride_permanently changes status to CLOSED_PERM.""" ride = RideFactory(status="OPERATING") user = UserFactory() result = RideService.close_ride_permanently(ride_id=ride.pk, user=user) assert result.status == "CLOSED_PERM" @pytest.mark.django_db class TestRideServiceDemolishRide(TestCase): """Tests for RideService.demolish_ride.""" def test__demolish_ride__closed_ride__changes_status(self): """Test demolish_ride changes status to DEMOLISHED.""" ride = RideFactory(status="CLOSED_PERM") user = UserFactory() result = RideService.demolish_ride(ride_id=ride.pk, user=user) assert result.status == "DEMOLISHED" @pytest.mark.django_db class TestRideServiceRelocateRide(TestCase): """Tests for RideService.relocate_ride.""" def test__relocate_ride__valid_data__relocates_ride(self): """Test relocate_ride moves ride to new park.""" old_park = ParkFactory() new_park = ParkFactory() ride = RideFactory(park=old_park, status="OPERATING") user = UserFactory() result = RideService.relocate_ride( ride_id=ride.pk, new_park_id=new_park.pk, user=user, ) assert result.park == new_park assert result.status == "RELOCATED" @pytest.mark.django_db class TestRideServiceReopenRide(TestCase): """Tests for RideService.reopen_ride.""" def test__reopen_ride__closed_temp_ride__changes_status(self): """Test reopen_ride changes status to OPERATING.""" ride = RideFactory(status="CLOSED_TEMP") user = UserFactory() result = RideService.reopen_ride(ride_id=ride.pk, user=user) assert result.status == "OPERATING" @pytest.mark.django_db class TestRideServiceHandleNewEntitySuggestions(TestCase): """Tests for RideService.handle_new_entity_suggestions.""" @patch("apps.rides.services.ModerationService.create_edit_submission_with_queue") def test__handle_new_entity_suggestions__new_manufacturer__creates_submission( self, mock_create_submission ): """Test handle_new_entity_suggestions creates submission for new manufacturer.""" mock_submission = Mock() mock_submission.id = 1 mock_create_submission.return_value = mock_submission user = UserFactory() form_data = { "manufacturer_search": "New Manufacturer", "manufacturer": None, "designer_search": "", "designer": None, "ride_model_search": "", "ride_model": None, } result = RideService.handle_new_entity_suggestions( form_data=form_data, submitter=user, ) assert result["total_submissions"] == 1 assert 1 in result["manufacturers"] mock_create_submission.assert_called_once() @patch("apps.rides.services.ModerationService.create_edit_submission_with_queue") def test__handle_new_entity_suggestions__new_designer__creates_submission( self, mock_create_submission ): """Test handle_new_entity_suggestions creates submission for new designer.""" mock_submission = Mock() mock_submission.id = 2 mock_create_submission.return_value = mock_submission user = UserFactory() form_data = { "manufacturer_search": "", "manufacturer": None, "designer_search": "New Designer", "designer": None, "ride_model_search": "", "ride_model": None, } result = RideService.handle_new_entity_suggestions( form_data=form_data, submitter=user, ) assert result["total_submissions"] == 1 assert 2 in result["designers"] @patch("apps.rides.services.ModerationService.create_edit_submission_with_queue") def test__handle_new_entity_suggestions__new_ride_model__creates_submission( self, mock_create_submission ): """Test handle_new_entity_suggestions creates submission for new ride model.""" mock_submission = Mock() mock_submission.id = 3 mock_create_submission.return_value = mock_submission user = UserFactory() manufacturer = ManufacturerCompanyFactory() form_data = { "manufacturer_search": "", "manufacturer": manufacturer, "designer_search": "", "designer": None, "ride_model_search": "New Model", "ride_model": None, } result = RideService.handle_new_entity_suggestions( form_data=form_data, submitter=user, ) assert result["total_submissions"] == 1 assert 3 in result["ride_models"] def test__handle_new_entity_suggestions__no_new_entities__returns_empty(self): """Test handle_new_entity_suggestions with no new entities returns empty result.""" user = UserFactory() manufacturer = ManufacturerCompanyFactory() form_data = { "manufacturer_search": "Existing Mfr", "manufacturer": manufacturer, # Already selected "designer_search": "", "designer": None, "ride_model_search": "", "ride_model": None, } result = RideService.handle_new_entity_suggestions( form_data=form_data, submitter=user, ) assert result["total_submissions"] == 0 assert len(result["manufacturers"]) == 0 assert len(result["designers"]) == 0 assert len(result["ride_models"]) == 0