from django.test import TestCase from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from django.utils import timezone from history_tracking.models import VersionBranch, ChangeSet from parks.models import Park class VersionBranchTests(TestCase): def setUp(self): self.main_branch = VersionBranch.objects.create( name='main', metadata={'type': 'default_branch'} ) self.feature_branch = VersionBranch.objects.create( name='feature/new-layout', metadata={'type': 'feature'} ) def test_branch_creation(self): """Test that branch creation works with valid data""" branch = VersionBranch.objects.create( name='test-branch', metadata={'type': 'test'} ) self.assertEqual(branch.name, 'test-branch') self.assertEqual(branch.metadata['type'], 'test') self.assertTrue(branch.is_active) self.assertIsNotNone(branch.created_at) def test_invalid_branch_name(self): """Test that branch names are properly validated""" with self.assertRaises(ValidationError): VersionBranch.objects.create(name='', metadata={}) # Test overly long name with self.assertRaises(ValidationError): VersionBranch.objects.create( name='a' * 256, metadata={} ) def test_branch_deactivation(self): """Test that branches can be deactivated""" self.feature_branch.is_active = False self.feature_branch.save() branch = VersionBranch.objects.get(name='feature/new-layout') self.assertFalse(branch.is_active) def test_branch_metadata(self): """Test that branch metadata can be updated""" metadata = { 'type': 'feature', 'description': 'New layout implementation', 'owner': 'test-user' } self.feature_branch.metadata = metadata self.feature_branch.save() branch = VersionBranch.objects.get(name='feature/new-layout') self.assertEqual(branch.metadata, metadata) class ChangeSetTests(TestCase): def setUp(self): self.main_branch = VersionBranch.objects.create( name='main', metadata={'type': 'default_branch'} ) self.park = Park.objects.create( name='Test Park', slug='test-park', status='OPERATING' ) self.content_type = ContentType.objects.get_for_model(Park) def test_changeset_creation(self): """Test that changeset creation works with valid data""" changeset = ChangeSet.objects.create( branch=self.main_branch, content_type=self.content_type, object_id=self.park.id, data={'name': 'Updated Park Name'}, status='pending', description='Update park name' ) self.assertEqual(changeset.branch, self.main_branch) self.assertEqual(changeset.content_type, self.content_type) self.assertEqual(changeset.object_id, self.park.id) self.assertEqual(changeset.status, 'pending') def test_changeset_status_flow(self): """Test that changeset status transitions work correctly""" changeset = ChangeSet.objects.create( branch=self.main_branch, content_type=self.content_type, object_id=self.park.id, data={'name': 'Updated Park Name'}, status='pending' ) # Test status transition: pending -> applied changeset.status = 'applied' changeset.applied_at = timezone.now() changeset.save() updated_changeset = ChangeSet.objects.get(pk=changeset.pk) self.assertEqual(updated_changeset.status, 'applied') self.assertIsNotNone(updated_changeset.applied_at) def test_invalid_changeset_status(self): """Test that invalid changeset statuses are rejected""" with self.assertRaises(ValidationError): ChangeSet.objects.create( branch=self.main_branch, content_type=self.content_type, object_id=self.park.id, data={'name': 'Updated Park Name'}, status='invalid_status' ) def test_changeset_validation(self): """Test that changesets require valid branch and content object""" # Test missing branch with self.assertRaises(ValidationError): ChangeSet.objects.create( content_type=self.content_type, object_id=self.park.id, data={'name': 'Updated Park Name'}, status='pending' ) # Test invalid content object with self.assertRaises(ValidationError): ChangeSet.objects.create( branch=self.main_branch, content_type=self.content_type, object_id=99999, # Non-existent object data={'name': 'Updated Park Name'}, status='pending' ) def test_changeset_relationship_cascade(self): """Test that changesets are deleted when branch is deleted""" changeset = ChangeSet.objects.create( branch=self.main_branch, content_type=self.content_type, object_id=self.park.id, data={'name': 'Updated Park Name'}, status='pending' ) # Delete the branch self.main_branch.delete() # Verify changeset was deleted with self.assertRaises(ChangeSet.DoesNotExist): ChangeSet.objects.get(pk=changeset.pk) def test_changeset_data_validation(self): """Test that changeset data must be valid JSON""" changeset = ChangeSet.objects.create( branch=self.main_branch, content_type=self.content_type, object_id=self.park.id, data={'valid': 'json_data'}, status='pending' ) # Test invalid JSON data with self.assertRaises(ValidationError): changeset.data = "invalid_json" changeset.save()