mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-30 08:07:01 -05:00
feat: Implement MFA authentication, add ride statistics model, and update various services, APIs, and tests across the application.
This commit is contained in:
@@ -11,34 +11,36 @@ This module contains tests for:
|
||||
- Mixin functionality tests
|
||||
"""
|
||||
|
||||
from django.test import TestCase, Client
|
||||
import json
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.http import JsonResponse, HttpRequest
|
||||
from django.http import HttpRequest, JsonResponse
|
||||
from django.test import Client, RequestFactory, TestCase
|
||||
from django.utils import timezone
|
||||
from django_fsm import TransitionNotAllowed
|
||||
from .models import (
|
||||
EditSubmission,
|
||||
PhotoSubmission,
|
||||
ModerationReport,
|
||||
ModerationQueue,
|
||||
BulkOperation,
|
||||
ModerationAction,
|
||||
)
|
||||
from .mixins import (
|
||||
EditSubmissionMixin,
|
||||
PhotoSubmissionMixin,
|
||||
ModeratorRequiredMixin,
|
||||
AdminRequiredMixin,
|
||||
InlineEditMixin,
|
||||
HistoryMixin,
|
||||
)
|
||||
from apps.parks.models import Company as Operator
|
||||
from django.views.generic import DetailView
|
||||
from django.test import RequestFactory
|
||||
import json
|
||||
from django_fsm import TransitionNotAllowed
|
||||
|
||||
from apps.parks.models import Company as Operator
|
||||
|
||||
from .mixins import (
|
||||
AdminRequiredMixin,
|
||||
EditSubmissionMixin,
|
||||
HistoryMixin,
|
||||
InlineEditMixin,
|
||||
ModeratorRequiredMixin,
|
||||
PhotoSubmissionMixin,
|
||||
)
|
||||
from .models import (
|
||||
BulkOperation,
|
||||
EditSubmission,
|
||||
ModerationAction,
|
||||
ModerationQueue,
|
||||
ModerationReport,
|
||||
PhotoSubmission,
|
||||
)
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
@@ -421,12 +423,12 @@ class EditSubmissionTransitionTests(TestCase):
|
||||
"""Test transition from PENDING to APPROVED."""
|
||||
submission = self._create_submission()
|
||||
self.assertEqual(submission.status, 'PENDING')
|
||||
|
||||
|
||||
submission.transition_to_approved(user=self.moderator)
|
||||
submission.handled_by = self.moderator
|
||||
submission.handled_at = timezone.now()
|
||||
submission.save()
|
||||
|
||||
|
||||
submission.refresh_from_db()
|
||||
self.assertEqual(submission.status, 'APPROVED')
|
||||
self.assertEqual(submission.handled_by, self.moderator)
|
||||
@@ -436,13 +438,13 @@ class EditSubmissionTransitionTests(TestCase):
|
||||
"""Test transition from PENDING to REJECTED."""
|
||||
submission = self._create_submission()
|
||||
self.assertEqual(submission.status, 'PENDING')
|
||||
|
||||
|
||||
submission.transition_to_rejected(user=self.moderator)
|
||||
submission.handled_by = self.moderator
|
||||
submission.handled_at = timezone.now()
|
||||
submission.notes = 'Rejected: Insufficient evidence'
|
||||
submission.save()
|
||||
|
||||
|
||||
submission.refresh_from_db()
|
||||
self.assertEqual(submission.status, 'REJECTED')
|
||||
self.assertEqual(submission.handled_by, self.moderator)
|
||||
@@ -452,25 +454,25 @@ class EditSubmissionTransitionTests(TestCase):
|
||||
"""Test transition from PENDING to ESCALATED."""
|
||||
submission = self._create_submission()
|
||||
self.assertEqual(submission.status, 'PENDING')
|
||||
|
||||
|
||||
submission.transition_to_escalated(user=self.moderator)
|
||||
submission.handled_by = self.moderator
|
||||
submission.handled_at = timezone.now()
|
||||
submission.notes = 'Escalated: Needs admin review'
|
||||
submission.save()
|
||||
|
||||
|
||||
submission.refresh_from_db()
|
||||
self.assertEqual(submission.status, 'ESCALATED')
|
||||
|
||||
def test_escalated_to_approved_transition(self):
|
||||
"""Test transition from ESCALATED to APPROVED."""
|
||||
submission = self._create_submission(status='ESCALATED')
|
||||
|
||||
|
||||
submission.transition_to_approved(user=self.admin)
|
||||
submission.handled_by = self.admin
|
||||
submission.handled_at = timezone.now()
|
||||
submission.save()
|
||||
|
||||
|
||||
submission.refresh_from_db()
|
||||
self.assertEqual(submission.status, 'APPROVED')
|
||||
self.assertEqual(submission.handled_by, self.admin)
|
||||
@@ -478,20 +480,20 @@ class EditSubmissionTransitionTests(TestCase):
|
||||
def test_escalated_to_rejected_transition(self):
|
||||
"""Test transition from ESCALATED to REJECTED."""
|
||||
submission = self._create_submission(status='ESCALATED')
|
||||
|
||||
|
||||
submission.transition_to_rejected(user=self.admin)
|
||||
submission.handled_by = self.admin
|
||||
submission.handled_at = timezone.now()
|
||||
submission.notes = 'Rejected by admin'
|
||||
submission.save()
|
||||
|
||||
|
||||
submission.refresh_from_db()
|
||||
self.assertEqual(submission.status, 'REJECTED')
|
||||
|
||||
def test_invalid_transition_from_approved(self):
|
||||
"""Test that transitions from APPROVED state fail."""
|
||||
submission = self._create_submission(status='APPROVED')
|
||||
|
||||
|
||||
# Attempting to transition from APPROVED should raise TransitionNotAllowed
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
submission.transition_to_rejected(user=self.moderator)
|
||||
@@ -499,7 +501,7 @@ class EditSubmissionTransitionTests(TestCase):
|
||||
def test_invalid_transition_from_rejected(self):
|
||||
"""Test that transitions from REJECTED state fail."""
|
||||
submission = self._create_submission(status='REJECTED')
|
||||
|
||||
|
||||
# Attempting to transition from REJECTED should raise TransitionNotAllowed
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
submission.transition_to_approved(user=self.moderator)
|
||||
@@ -507,9 +509,9 @@ class EditSubmissionTransitionTests(TestCase):
|
||||
def test_approve_wrapper_method(self):
|
||||
"""Test the approve() wrapper method."""
|
||||
submission = self._create_submission()
|
||||
|
||||
result = submission.approve(self.moderator)
|
||||
|
||||
|
||||
submission.approve(self.moderator)
|
||||
|
||||
submission.refresh_from_db()
|
||||
self.assertEqual(submission.status, 'APPROVED')
|
||||
self.assertEqual(submission.handled_by, self.moderator)
|
||||
@@ -518,9 +520,9 @@ class EditSubmissionTransitionTests(TestCase):
|
||||
def test_reject_wrapper_method(self):
|
||||
"""Test the reject() wrapper method."""
|
||||
submission = self._create_submission()
|
||||
|
||||
|
||||
submission.reject(self.moderator, reason='Not enough evidence')
|
||||
|
||||
|
||||
submission.refresh_from_db()
|
||||
self.assertEqual(submission.status, 'REJECTED')
|
||||
self.assertIn('Not enough evidence', submission.notes)
|
||||
@@ -528,9 +530,9 @@ class EditSubmissionTransitionTests(TestCase):
|
||||
def test_escalate_wrapper_method(self):
|
||||
"""Test the escalate() wrapper method."""
|
||||
submission = self._create_submission()
|
||||
|
||||
|
||||
submission.escalate(self.moderator, reason='Needs admin approval')
|
||||
|
||||
|
||||
submission.refresh_from_db()
|
||||
self.assertEqual(submission.status, 'ESCALATED')
|
||||
self.assertIn('Needs admin approval', submission.notes)
|
||||
@@ -582,11 +584,11 @@ class ModerationReportTransitionTests(TestCase):
|
||||
"""Test transition from PENDING to UNDER_REVIEW."""
|
||||
report = self._create_report()
|
||||
self.assertEqual(report.status, 'PENDING')
|
||||
|
||||
|
||||
report.transition_to_under_review(user=self.moderator)
|
||||
report.assigned_moderator = self.moderator
|
||||
report.save()
|
||||
|
||||
|
||||
report.refresh_from_db()
|
||||
self.assertEqual(report.status, 'UNDER_REVIEW')
|
||||
self.assertEqual(report.assigned_moderator, self.moderator)
|
||||
@@ -596,13 +598,13 @@ class ModerationReportTransitionTests(TestCase):
|
||||
report = self._create_report(status='UNDER_REVIEW')
|
||||
report.assigned_moderator = self.moderator
|
||||
report.save()
|
||||
|
||||
|
||||
report.transition_to_resolved(user=self.moderator)
|
||||
report.resolution_action = 'Content updated'
|
||||
report.resolution_notes = 'Fixed the incorrect information'
|
||||
report.resolved_at = timezone.now()
|
||||
report.save()
|
||||
|
||||
|
||||
report.refresh_from_db()
|
||||
self.assertEqual(report.status, 'RESOLVED')
|
||||
self.assertIsNotNone(report.resolved_at)
|
||||
@@ -612,26 +614,26 @@ class ModerationReportTransitionTests(TestCase):
|
||||
report = self._create_report(status='UNDER_REVIEW')
|
||||
report.assigned_moderator = self.moderator
|
||||
report.save()
|
||||
|
||||
|
||||
report.transition_to_dismissed(user=self.moderator)
|
||||
report.resolution_notes = 'Report is not valid'
|
||||
report.resolved_at = timezone.now()
|
||||
report.save()
|
||||
|
||||
|
||||
report.refresh_from_db()
|
||||
self.assertEqual(report.status, 'DISMISSED')
|
||||
|
||||
def test_invalid_transition_from_resolved(self):
|
||||
"""Test that transitions from RESOLVED state fail."""
|
||||
report = self._create_report(status='RESOLVED')
|
||||
|
||||
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
report.transition_to_dismissed(user=self.moderator)
|
||||
|
||||
def test_invalid_transition_from_dismissed(self):
|
||||
"""Test that transitions from DISMISSED state fail."""
|
||||
report = self._create_report(status='DISMISSED')
|
||||
|
||||
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
report.transition_to_resolved(user=self.moderator)
|
||||
|
||||
@@ -668,12 +670,12 @@ class ModerationQueueTransitionTests(TestCase):
|
||||
"""Test transition from PENDING to IN_PROGRESS."""
|
||||
item = self._create_queue_item()
|
||||
self.assertEqual(item.status, 'PENDING')
|
||||
|
||||
|
||||
item.transition_to_in_progress(user=self.moderator)
|
||||
item.assigned_to = self.moderator
|
||||
item.assigned_at = timezone.now()
|
||||
item.save()
|
||||
|
||||
|
||||
item.refresh_from_db()
|
||||
self.assertEqual(item.status, 'IN_PROGRESS')
|
||||
self.assertEqual(item.assigned_to, self.moderator)
|
||||
@@ -683,10 +685,10 @@ class ModerationQueueTransitionTests(TestCase):
|
||||
item = self._create_queue_item(status='IN_PROGRESS')
|
||||
item.assigned_to = self.moderator
|
||||
item.save()
|
||||
|
||||
|
||||
item.transition_to_completed(user=self.moderator)
|
||||
item.save()
|
||||
|
||||
|
||||
item.refresh_from_db()
|
||||
self.assertEqual(item.status, 'COMPLETED')
|
||||
|
||||
@@ -695,27 +697,27 @@ class ModerationQueueTransitionTests(TestCase):
|
||||
item = self._create_queue_item(status='IN_PROGRESS')
|
||||
item.assigned_to = self.moderator
|
||||
item.save()
|
||||
|
||||
|
||||
item.transition_to_cancelled(user=self.moderator)
|
||||
item.save()
|
||||
|
||||
|
||||
item.refresh_from_db()
|
||||
self.assertEqual(item.status, 'CANCELLED')
|
||||
|
||||
def test_pending_to_cancelled_transition(self):
|
||||
"""Test transition from PENDING to CANCELLED."""
|
||||
item = self._create_queue_item()
|
||||
|
||||
|
||||
item.transition_to_cancelled(user=self.moderator)
|
||||
item.save()
|
||||
|
||||
|
||||
item.refresh_from_db()
|
||||
self.assertEqual(item.status, 'CANCELLED')
|
||||
|
||||
def test_invalid_transition_from_completed(self):
|
||||
"""Test that transitions from COMPLETED state fail."""
|
||||
item = self._create_queue_item(status='COMPLETED')
|
||||
|
||||
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
item.transition_to_in_progress(user=self.moderator)
|
||||
|
||||
@@ -753,11 +755,11 @@ class BulkOperationTransitionTests(TestCase):
|
||||
"""Test transition from PENDING to RUNNING."""
|
||||
operation = self._create_bulk_operation()
|
||||
self.assertEqual(operation.status, 'PENDING')
|
||||
|
||||
|
||||
operation.transition_to_running(user=self.admin)
|
||||
operation.started_at = timezone.now()
|
||||
operation.save()
|
||||
|
||||
|
||||
operation.refresh_from_db()
|
||||
self.assertEqual(operation.status, 'RUNNING')
|
||||
self.assertIsNotNone(operation.started_at)
|
||||
@@ -767,12 +769,12 @@ class BulkOperationTransitionTests(TestCase):
|
||||
operation = self._create_bulk_operation(status='RUNNING')
|
||||
operation.started_at = timezone.now()
|
||||
operation.save()
|
||||
|
||||
|
||||
operation.transition_to_completed(user=self.admin)
|
||||
operation.completed_at = timezone.now()
|
||||
operation.processed_items = 100
|
||||
operation.save()
|
||||
|
||||
|
||||
operation.refresh_from_db()
|
||||
self.assertEqual(operation.status, 'COMPLETED')
|
||||
self.assertIsNotNone(operation.completed_at)
|
||||
@@ -783,13 +785,13 @@ class BulkOperationTransitionTests(TestCase):
|
||||
operation = self._create_bulk_operation(status='RUNNING')
|
||||
operation.started_at = timezone.now()
|
||||
operation.save()
|
||||
|
||||
|
||||
operation.transition_to_failed(user=self.admin)
|
||||
operation.completed_at = timezone.now()
|
||||
operation.results = {'error': 'Database connection failed'}
|
||||
operation.failed_items = 50
|
||||
operation.save()
|
||||
|
||||
|
||||
operation.refresh_from_db()
|
||||
self.assertEqual(operation.status, 'FAILED')
|
||||
self.assertEqual(operation.failed_items, 50)
|
||||
@@ -797,10 +799,10 @@ class BulkOperationTransitionTests(TestCase):
|
||||
def test_pending_to_cancelled_transition(self):
|
||||
"""Test transition from PENDING to CANCELLED."""
|
||||
operation = self._create_bulk_operation()
|
||||
|
||||
|
||||
operation.transition_to_cancelled(user=self.admin)
|
||||
operation.save()
|
||||
|
||||
|
||||
operation.refresh_from_db()
|
||||
self.assertEqual(operation.status, 'CANCELLED')
|
||||
|
||||
@@ -809,24 +811,24 @@ class BulkOperationTransitionTests(TestCase):
|
||||
operation = self._create_bulk_operation(status='RUNNING')
|
||||
operation.can_cancel = True
|
||||
operation.save()
|
||||
|
||||
|
||||
operation.transition_to_cancelled(user=self.admin)
|
||||
operation.save()
|
||||
|
||||
|
||||
operation.refresh_from_db()
|
||||
self.assertEqual(operation.status, 'CANCELLED')
|
||||
|
||||
def test_invalid_transition_from_completed(self):
|
||||
"""Test that transitions from COMPLETED state fail."""
|
||||
operation = self._create_bulk_operation(status='COMPLETED')
|
||||
|
||||
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
operation.transition_to_running(user=self.admin)
|
||||
|
||||
def test_invalid_transition_from_failed(self):
|
||||
"""Test that transitions from FAILED state fail."""
|
||||
operation = self._create_bulk_operation(status='FAILED')
|
||||
|
||||
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
operation.transition_to_completed(user=self.admin)
|
||||
|
||||
@@ -835,12 +837,12 @@ class BulkOperationTransitionTests(TestCase):
|
||||
operation = self._create_bulk_operation()
|
||||
operation.total_items = 100
|
||||
operation.processed_items = 50
|
||||
|
||||
|
||||
self.assertEqual(operation.progress_percentage, 50.0)
|
||||
|
||||
|
||||
operation.processed_items = 0
|
||||
self.assertEqual(operation.progress_percentage, 0.0)
|
||||
|
||||
|
||||
operation.total_items = 0
|
||||
self.assertEqual(operation.progress_percentage, 0.0)
|
||||
|
||||
@@ -876,7 +878,7 @@ class TransitionLoggingTestCase(TestCase):
|
||||
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,
|
||||
@@ -887,18 +889,18 @@ class TransitionLoggingTestCase(TestCase):
|
||||
status='PENDING',
|
||||
reason='Test reason'
|
||||
)
|
||||
|
||||
|
||||
# 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)
|
||||
@@ -907,7 +909,7 @@ class TransitionLoggingTestCase(TestCase):
|
||||
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,
|
||||
@@ -917,23 +919,23 @@ class TransitionLoggingTestCase(TestCase):
|
||||
status='PENDING',
|
||||
reason='Test reason'
|
||||
)
|
||||
|
||||
|
||||
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')
|
||||
@@ -941,10 +943,10 @@ class TransitionLoggingTestCase(TestCase):
|
||||
def test_history_endpoint_returns_logs(self):
|
||||
"""Test history API endpoint returns transition logs."""
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
|
||||
api_client = APIClient()
|
||||
api_client.force_authenticate(user=self.moderator)
|
||||
|
||||
|
||||
submission = EditSubmission.objects.create(
|
||||
user=self.user,
|
||||
content_type=self.content_type,
|
||||
@@ -954,21 +956,21 @@ class TransitionLoggingTestCase(TestCase):
|
||||
status='PENDING',
|
||||
reason='Test reason'
|
||||
)
|
||||
|
||||
|
||||
# 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('/api/moderation/reports/all_history/')
|
||||
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
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,
|
||||
@@ -978,18 +980,18 @@ class TransitionLoggingTestCase(TestCase):
|
||||
status='PENDING',
|
||||
reason='Test reason'
|
||||
)
|
||||
|
||||
|
||||
# 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")
|
||||
@@ -997,7 +999,7 @@ class TransitionLoggingTestCase(TestCase):
|
||||
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,
|
||||
@@ -1007,27 +1009,27 @@ class TransitionLoggingTestCase(TestCase):
|
||||
status='PENDING',
|
||||
reason='Test reason'
|
||||
)
|
||||
|
||||
|
||||
# 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'))
|
||||
|
||||
def test_log_ordering_by_timestamp(self):
|
||||
"""Test that logs are properly ordered by timestamp."""
|
||||
|
||||
from django_fsm_log.models import StateLog
|
||||
import time
|
||||
|
||||
|
||||
submission = EditSubmission.objects.create(
|
||||
user=self.user,
|
||||
content_type=self.content_type,
|
||||
@@ -1037,22 +1039,22 @@ class TransitionLoggingTestCase(TestCase):
|
||||
status='PENDING',
|
||||
reason='Test reason'
|
||||
)
|
||||
|
||||
|
||||
submission_ct = ContentType.objects.get_for_model(submission)
|
||||
|
||||
|
||||
# Create multiple transitions
|
||||
submission.transition_to_escalated(user=self.moderator)
|
||||
submission.save()
|
||||
|
||||
|
||||
submission.transition_to_approved(user=self.moderator)
|
||||
submission.save()
|
||||
|
||||
|
||||
# Get logs ordered by timestamp
|
||||
logs = list(StateLog.objects.filter(
|
||||
content_type=submission_ct,
|
||||
object_id=submission.id
|
||||
).order_by('timestamp'))
|
||||
|
||||
|
||||
# Verify ordering
|
||||
self.assertEqual(len(logs), 2)
|
||||
self.assertTrue(logs[0].timestamp <= logs[1].timestamp)
|
||||
@@ -1091,7 +1093,7 @@ class ModerationActionTests(TestCase):
|
||||
moderator=self.moderator,
|
||||
target_user=self.target_user
|
||||
)
|
||||
|
||||
|
||||
self.assertIsNotNone(action.expires_at)
|
||||
# expires_at should be approximately 24 hours from now
|
||||
time_diff = action.expires_at - timezone.now()
|
||||
@@ -1106,7 +1108,7 @@ class ModerationActionTests(TestCase):
|
||||
moderator=self.moderator,
|
||||
target_user=self.target_user
|
||||
)
|
||||
|
||||
|
||||
self.assertIsNone(action.expires_at)
|
||||
|
||||
def test_action_is_active_by_default(self):
|
||||
@@ -1168,7 +1170,7 @@ class PhotoSubmissionTransitionTests(TestCase):
|
||||
def _create_submission(self, status='PENDING'):
|
||||
"""Helper to create a PhotoSubmission."""
|
||||
# Create using direct database creation to bypass FK validation
|
||||
from unittest.mock import patch, Mock
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
with patch.object(PhotoSubmission, 'photo', Mock()):
|
||||
submission = PhotoSubmission(
|
||||
|
||||
Reference in New Issue
Block a user