chore: fix pghistory migration deps and improve htmx utilities

- Update pghistory dependency from 0007 to 0006 in account migrations
- Add docstrings and remove unused imports in htmx_forms.py
- Add DJANGO_SETTINGS_MODULE bash commands to Claude settings
- Add state transition definitions for ride statuses
This commit is contained in:
pacnpal
2025-12-21 17:33:24 -05:00
parent b9063ff4f8
commit 7ba0004c93
74 changed files with 11134 additions and 198 deletions

View File

@@ -347,3 +347,181 @@ class ModerationMixinsTests(TestCase):
self.assertIn("history", context)
self.assertIn("edit_submissions", context)
self.assertEqual(len(context["edit_submissions"]), 1)
# ============================================================================
# FSM Transition Logging Tests
# ============================================================================
class TransitionLoggingTestCase(TestCase):
"""Test cases for FSM transition logging with django-fsm-log."""
def setUp(self):
"""Set up test fixtures."""
self.user = User.objects.create_user(
username='testuser',
email='test@example.com',
password='testpass123',
role='USER'
)
self.moderator = User.objects.create_user(
username='moderator',
email='moderator@example.com',
password='testpass123',
role='MODERATOR'
)
self.operator = Operator.objects.create(
name='Test Operator',
description='Test Description'
)
self.content_type = ContentType.objects.get_for_model(Operator)
def test_transition_creates_log(self):
"""Test that transitions create StateLog entries."""
from django_fsm_log.models import StateLog
# Create a submission
submission = EditSubmission.objects.create(
user=self.user,
content_type=self.content_type,
object_id=self.operator.id,
submission_type='EDIT',
changes={'name': 'Updated Name'},
status='PENDING'
)
# Perform transition
submission.transition_to_approved(user=self.moderator)
submission.save()
# Check log was created
submission_ct = ContentType.objects.get_for_model(submission)
log = StateLog.objects.filter(
content_type=submission_ct,
object_id=submission.id
).first()
self.assertIsNotNone(log, "StateLog entry should be created")
self.assertEqual(log.state, 'APPROVED')
self.assertEqual(log.by, self.moderator)
self.assertIn('approved', log.transition.lower())
def test_multiple_transitions_logged(self):
"""Test that multiple transitions are all logged."""
from django_fsm_log.models import StateLog
submission = EditSubmission.objects.create(
user=self.user,
content_type=self.content_type,
object_id=self.operator.id,
submission_type='EDIT',
changes={'name': 'Updated Name'},
status='PENDING'
)
submission_ct = ContentType.objects.get_for_model(submission)
# First transition
submission.transition_to_escalated(user=self.moderator)
submission.save()
# Second transition
submission.transition_to_approved(user=self.moderator)
submission.save()
# Check multiple logs created
logs = StateLog.objects.filter(
content_type=submission_ct,
object_id=submission.id
).order_by('timestamp')
self.assertEqual(logs.count(), 2, "Should have 2 log entries")
self.assertEqual(logs[0].state, 'ESCALATED')
self.assertEqual(logs[1].state, 'APPROVED')
def test_history_endpoint_returns_logs(self):
"""Test history API endpoint returns transition logs."""
from rest_framework.test import APIClient
from django_fsm_log.models import StateLog
api_client = APIClient()
api_client.force_authenticate(user=self.moderator)
submission = EditSubmission.objects.create(
user=self.user,
content_type=self.content_type,
object_id=self.operator.id,
submission_type='EDIT',
changes={'name': 'Updated Name'},
status='PENDING'
)
# Perform transition to create log
submission.transition_to_approved(user=self.moderator)
submission.save()
# Note: This assumes EditSubmission has a history endpoint
# Adjust URL pattern based on actual implementation
response = api_client.get(f'/api/moderation/reports/all_history/')
self.assertEqual(response.status_code, 200)
# Response should contain history data
# Actual assertions depend on response format
def test_system_transitions_without_user(self):
"""Test that system transitions work without a user."""
from django_fsm_log.models import StateLog
submission = EditSubmission.objects.create(
user=self.user,
content_type=self.content_type,
object_id=self.operator.id,
submission_type='EDIT',
changes={'name': 'Updated Name'},
status='PENDING'
)
# Perform transition without user
submission.transition_to_rejected(user=None)
submission.save()
# Check log was created even without user
submission_ct = ContentType.objects.get_for_model(submission)
log = StateLog.objects.filter(
content_type=submission_ct,
object_id=submission.id
).first()
self.assertIsNotNone(log)
self.assertEqual(log.state, 'REJECTED')
self.assertIsNone(log.by, "System transitions should have no user")
def test_transition_log_includes_description(self):
"""Test that transition logs can include descriptions."""
from django_fsm_log.models import StateLog
submission = EditSubmission.objects.create(
user=self.user,
content_type=self.content_type,
object_id=self.operator.id,
submission_type='EDIT',
changes={'name': 'Updated Name'},
status='PENDING'
)
# Perform transition
submission.transition_to_approved(user=self.moderator)
submission.save()
# Check log
submission_ct = ContentType.objects.get_for_model(submission)
log = StateLog.objects.filter(
content_type=submission_ct,
object_id=submission.id
).first()
self.assertIsNotNone(log)
# Description field exists and can be used for audit trails
self.assertTrue(hasattr(log, 'description'))