from django.test import TestCase, Client from django.urls import reverse from django.contrib.auth import get_user_model from django.core.exceptions import ValidationError from django.contrib.contenttypes.models import ContentType from django.contrib.gis.geos import Point from django.http import HttpResponse from typing import cast, Optional, Tuple from .models import Park, ParkArea from companies.models import Company from location.models import Location User = get_user_model() def create_test_location(park: Park) -> Location: """Helper function to create a test location""" return Location.objects.create( content_type=ContentType.objects.get_for_model(Park), object_id=park.id, name='Test Park Location', location_type='park', street_address='123 Test St', city='Test City', state='TS', country='Test Country', postal_code='12345', point=Point(-118.2437, 34.0522) ) class ParkModelTests(TestCase): @classmethod def setUpTestData(cls) -> None: # Create test user cls.user = User.objects.create_user( username='testuser', email='test@example.com', password='testpass123' ) # Create test company cls.company = Company.objects.create( name='Test Company', website='http://example.com' ) # Create test park cls.park = Park.objects.create( name='Test Park', owner=cls.company, status='OPERATING', website='http://testpark.com' ) # Create test location cls.location = create_test_location(cls.park) def test_park_creation(self) -> None: """Test park instance creation and field values""" self.assertEqual(self.park.name, 'Test Park') self.assertEqual(self.park.owner, self.company) self.assertEqual(self.park.status, 'OPERATING') self.assertEqual(self.park.website, 'http://testpark.com') self.assertTrue(self.park.slug) def test_park_str_representation(self) -> None: """Test string representation of park""" self.assertEqual(str(self.park), 'Test Park') def test_park_location(self) -> None: """Test park location relationship""" self.assertTrue(self.park.location.exists()) if location := self.park.location.first(): self.assertEqual(location.street_address, '123 Test St') self.assertEqual(location.city, 'Test City') self.assertEqual(location.state, 'TS') self.assertEqual(location.country, 'Test Country') self.assertEqual(location.postal_code, '12345') def test_park_coordinates(self) -> None: """Test park coordinates property""" coords = self.park.coordinates self.assertIsNotNone(coords) if coords: self.assertAlmostEqual(coords[0], 34.0522, places=4) # latitude self.assertAlmostEqual(coords[1], -118.2437, places=4) # longitude def test_park_formatted_location(self) -> None: """Test park formatted_location property""" expected = '123 Test St, Test City, TS, 12345, Test Country' self.assertEqual(self.park.formatted_location, expected) class ParkAreaTests(TestCase): def setUp(self) -> None: # Create test company self.company = Company.objects.create( name='Test Company', website='http://example.com' ) # Create test park self.park = Park.objects.create( name='Test Park', owner=self.company, status='OPERATING' ) # Create test location self.location = create_test_location(self.park) # Create test area self.area = ParkArea.objects.create( park=self.park, name='Test Area', description='Test Description' ) def test_area_creation(self) -> None: """Test park area creation""" self.assertEqual(self.area.name, 'Test Area') self.assertEqual(self.area.park, self.park) self.assertTrue(self.area.slug) def test_area_str_representation(self) -> None: """Test string representation of park area""" expected = f'Test Area at {self.park.name}' self.assertEqual(str(self.area), expected) def test_area_get_by_slug(self) -> None: """Test get_by_slug class method""" area, is_historical = ParkArea.get_by_slug(self.area.slug) self.assertEqual(area, self.area) self.assertFalse(is_historical) class ParkViewTests(TestCase): def setUp(self) -> None: self.client = Client() self.user = User.objects.create_user( username='testuser', email='test@example.com', password='testpass123' ) self.company = Company.objects.create( name='Test Company', website='http://example.com' ) self.park = Park.objects.create( name='Test Park', owner=self.company, status='OPERATING' ) self.location = create_test_location(self.park) def test_park_list_view(self) -> None: """Test park list view""" response = cast(HttpResponse, self.client.get(reverse('parks:park_list'))) self.assertEqual(response.status_code, 200) content = response.content.decode('utf-8') self.assertIn(self.park.name, content) def test_park_detail_view(self) -> None: """Test park detail view""" response = cast(HttpResponse, self.client.get( reverse('parks:park_detail', kwargs={'slug': self.park.slug}) )) self.assertEqual(response.status_code, 200) content = response.content.decode('utf-8') self.assertIn(self.park.name, content) self.assertIn('123 Test St', content) def test_park_area_detail_view(self) -> None: """Test park area detail view""" area = ParkArea.objects.create( park=self.park, name='Test Area' ) response = cast(HttpResponse, self.client.get( reverse('parks:area_detail', kwargs={'park_slug': self.park.slug, 'area_slug': area.slug}) )) self.assertEqual(response.status_code, 200) content = response.content.decode('utf-8') self.assertIn(area.name, content)