Add @extend_schema decorators to moderation ViewSet actions

- Add drf_spectacular imports (extend_schema, OpenApiResponse, inline_serializer)
- Annotate claim action with response schemas for 200/404/409/400
- Annotate unclaim action with response schemas for 200/403/400
- Annotate approve action with request=None and response schemas
- Annotate reject action with reason request body schema
- Annotate escalate action with reason request body schema
- All actions tagged with 'Moderation' for API docs grouping
This commit is contained in:
pacnpal
2026-01-13 19:34:41 -05:00
parent d631f3183c
commit 4140a0d8e7
18 changed files with 526 additions and 692 deletions

View File

@@ -13,11 +13,10 @@ from django.test import RequestFactory, TestCase
from apps.moderation.admin import (
EditSubmissionAdmin,
HistoryEventAdmin,
PhotoSubmissionAdmin,
StateLogAdmin,
moderation_site,
)
from apps.moderation.models import EditSubmission, PhotoSubmission
from apps.moderation.models import EditSubmission
User = get_user_model()
@@ -101,32 +100,7 @@ class TestEditSubmissionAdmin(TestCase):
assert "bulk_escalate" in actions
class TestPhotoSubmissionAdmin(TestCase):
"""Tests for PhotoSubmissionAdmin class."""
def setUp(self):
self.factory = RequestFactory()
self.site = AdminSite()
self.admin = PhotoSubmissionAdmin(model=PhotoSubmission, admin_site=self.site)
def test_list_display_includes_preview(self):
"""Verify photo preview is in list_display."""
assert "photo_preview" in self.admin.list_display
def test_list_select_related(self):
"""Verify select_related is configured."""
assert "user" in self.admin.list_select_related
assert "content_type" in self.admin.list_select_related
assert "handled_by" in self.admin.list_select_related
def test_moderation_actions_registered(self):
"""Verify moderation actions are registered."""
request = self.factory.get("/admin/")
request.user = User(is_superuser=True)
actions = self.admin.get_actions(request)
assert "bulk_approve" in actions
assert "bulk_reject" in actions
# PhotoSubmissionAdmin tests removed - model consolidated into EditSubmission
class TestStateLogAdmin(TestCase):
@@ -200,9 +174,7 @@ class TestRegisteredModels(TestCase):
"""Verify EditSubmission is registered with moderation site."""
assert EditSubmission in moderation_site._registry
def test_photo_submission_registered(self):
"""Verify PhotoSubmission is registered with moderation site."""
assert PhotoSubmission in moderation_site._registry
# PhotoSubmission registration test removed - model consolidated into EditSubmission
def test_state_log_registered(self):
"""Verify StateLog is registered with moderation site."""

View File

@@ -3,7 +3,7 @@ Comprehensive tests for the moderation app.
This module contains tests for:
- EditSubmission state machine transitions
- PhotoSubmission state machine transitions
- EditSubmission with submission_type="PHOTO" (photo submissions)
- ModerationReport state machine transitions
- ModerationQueue state machine transitions
- BulkOperation state machine transitions
@@ -39,7 +39,6 @@ from ..models import (
ModerationAction,
ModerationQueue,
ModerationReport,
PhotoSubmission,
)
User = get_user_model()
@@ -1132,14 +1131,17 @@ class ModerationActionTests(TestCase):
# ============================================================================
# PhotoSubmission FSM Transition Tests
# EditSubmission PHOTO Type FSM Transition Tests
# ============================================================================
class PhotoSubmissionTransitionTests(TestCase):
"""Comprehensive tests for PhotoSubmission FSM transitions.
class PhotoEditSubmissionTransitionTests(TestCase):
"""Comprehensive tests for EditSubmission with submission_type='PHOTO' FSM transitions.
Note: All approve/reject/escalate transitions require CLAIMED state first.
These tests validate that photo submissions (using the unified EditSubmission model)
have correct FSM behavior.
"""
def setUp(self):
@@ -1169,13 +1171,15 @@ class PhotoSubmissionTransitionTests(TestCase):
)
def _create_submission(self, status="PENDING"):
"""Helper to create a PhotoSubmission with proper CloudflareImage."""
submission = PhotoSubmission.objects.create(
"""Helper to create an EditSubmission with submission_type='PHOTO' and proper CloudflareImage."""
submission = EditSubmission.objects.create(
user=self.user,
content_type=self.content_type,
object_id=self.operator.id,
submission_type="PHOTO", # Unified model
photo=self.mock_image,
caption="Test Photo",
changes={}, # Photos use empty changes
status="PENDING", # Always create as PENDING first
)

View File

@@ -83,13 +83,17 @@ class SubmissionApprovalWorkflowTests(TestCase):
def test_photo_submission_approval_workflow(self):
"""
Test complete photo submission approval workflow.
Test complete photo submission approval workflow using EditSubmission.
Flow: User submits photo → Moderator reviews → Moderator approves → Photo created
Note: Photos now use EditSubmission with submission_type="PHOTO" (unified model).
"""
from datetime import timedelta
from django_cloudflareimages_toolkit.models import CloudflareImage
from apps.moderation.models import PhotoSubmission
from apps.moderation.models import EditSubmission
from apps.parks.models import Company, Park
# Create target park
@@ -105,18 +109,21 @@ class SubmissionApprovalWorkflowTests(TestCase):
expires_at=timezone.now() + timedelta(days=365),
)
# User submits a photo
# User submits a photo using unified EditSubmission model
content_type = ContentType.objects.get_for_model(park)
submission = PhotoSubmission.objects.create(
submission = EditSubmission.objects.create(
user=self.regular_user,
content_type=content_type,
object_id=park.id,
submission_type="PHOTO", # Unified model with PHOTO type
status="PENDING",
photo=mock_image,
caption="Beautiful park entrance",
changes={}, # Photos use empty changes dict
)
self.assertEqual(submission.status, "PENDING")
self.assertEqual(submission.submission_type, "PHOTO")
# Moderator claims the submission first (required FSM step)
submission.claim(user=self.moderator)