Files
thrillwiki_django_no_react/moderation/tests.py
pacnpal b5bae44cb8 Add Road Trip Planner template with interactive map and trip management features
- Implemented a new HTML template for the Road Trip Planner.
- Integrated Leaflet.js for interactive mapping and routing.
- Added functionality for searching and selecting parks to include in a trip.
- Enabled drag-and-drop reordering of selected parks.
- Included trip optimization and route calculation features.
- Created a summary display for trip statistics.
- Added functionality to save trips and manage saved trips.
- Enhanced UI with responsive design and dark mode support.
2025-08-15 20:53:00 -04:00

330 lines
12 KiB
Python

from django.test import TestCase, Client
from django.urls import reverse
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.utils import timezone
from django.utils.datastructures import MultiValueDict
from django.http import QueryDict
from .models import EditSubmission, PhotoSubmission
from .mixins import EditSubmissionMixin, PhotoSubmissionMixin, ModeratorRequiredMixin, AdminRequiredMixin, InlineEditMixin, HistoryMixin
from parks.models import Company as Operator
from django.views.generic import DetailView
from django.test import RequestFactory
import json
from typing import Optional
User = get_user_model()
class TestView(EditSubmissionMixin, PhotoSubmissionMixin, InlineEditMixin, HistoryMixin, DetailView):
model = Operator
template_name = 'test.html'
pk_url_kwarg = 'pk'
slug_url_kwarg = 'slug'
def get_context_data(self, **kwargs):
if not hasattr(self, 'object'):
self.object = self.get_object()
return super().get_context_data(**kwargs)
def setup(self, request: HttpRequest, *args, **kwargs):
super().setup(request, *args, **kwargs)
self.request = request
class ModerationMixinsTests(TestCase):
def setUp(self):
self.client = Client()
self.factory = RequestFactory()
# Create users with different roles
self.user = User.objects.create_user(
username='testuser',
email='test@example.com',
password='testpass123'
)
self.moderator = User.objects.create_user(
username='moderator',
email='moderator@example.com',
password='modpass123',
role='MODERATOR'
)
self.admin = User.objects.create_user(
username='admin',
email='admin@example.com',
password='adminpass123',
role='ADMIN'
)
# Create test company
self.operator = Operator.objects.create(
name='Test Operator',
website='http://example.com',
description='Test Description'
)
def test_edit_submission_mixin_unauthenticated(self):
"""Test edit submission when not logged in"""
view = TestView()
request = self.factory.post(f'/test/{self.operator.pk}/')
request.user = AnonymousUser()
view.setup(request, pk=self.operator.pk)
view.kwargs = {'pk': self.operator.pk}
response = view.handle_edit_submission(request, {})
self.assertIsInstance(response, JsonResponse)
self.assertEqual(response.status_code, 403)
def test_edit_submission_mixin_no_changes(self):
"""Test edit submission with no changes"""
view = TestView()
request = self.factory.post(
f'/test/{self.operator.pk}/',
data=json.dumps({}),
content_type='application/json'
)
request.user = self.user
view.setup(request, pk=self.operator.pk)
view.kwargs = {'pk': self.operator.pk}
response = view.post(request)
self.assertIsInstance(response, JsonResponse)
self.assertEqual(response.status_code, 400)
def test_edit_submission_mixin_invalid_json(self):
"""Test edit submission with invalid JSON"""
view = TestView()
request = self.factory.post(
f'/test/{self.operator.pk}/',
data='invalid json',
content_type='application/json'
)
request.user = self.user
view.setup(request, pk=self.operator.pk)
view.kwargs = {'pk': self.operator.pk}
response = view.post(request)
self.assertIsInstance(response, JsonResponse)
self.assertEqual(response.status_code, 400)
def test_edit_submission_mixin_regular_user(self):
"""Test edit submission as regular user"""
view = TestView()
request = self.factory.post(f'/test/{self.operator.pk}/')
request.user = self.user
view.setup(request, pk=self.operator.pk)
view.kwargs = {'pk': self.operator.pk}
changes = {'name': 'New Name'}
response = view.handle_edit_submission(request, changes, 'Test reason', 'Test source')
self.assertIsInstance(response, JsonResponse)
self.assertEqual(response.status_code, 200)
data = json.loads(response.content.decode())
self.assertFalse(data['auto_approved'])
def test_edit_submission_mixin_moderator(self):
"""Test edit submission as moderator"""
view = TestView()
request = self.factory.post(f'/test/{self.operator.pk}/')
request.user = self.moderator
view.setup(request, pk=self.operator.pk)
view.kwargs = {'pk': self.operator.pk}
changes = {'name': 'New Name'}
response = view.handle_edit_submission(request, changes, 'Test reason', 'Test source')
self.assertIsInstance(response, JsonResponse)
self.assertEqual(response.status_code, 200)
data = json.loads(response.content.decode())
self.assertTrue(data['auto_approved'])
def test_photo_submission_mixin_unauthenticated(self):
"""Test photo submission when not logged in"""
view = TestView()
view.kwargs = {'pk': self.operator.pk}
view.object = self.operator
request = self.factory.post(
f'/test/{self.operator.pk}/',
data={},
format='multipart'
)
request.user = AnonymousUser()
view.setup(request, pk=self.operator.pk)
response = view.handle_photo_submission(request)
self.assertIsInstance(response, JsonResponse)
self.assertEqual(response.status_code, 403)
def test_photo_submission_mixin_no_photo(self):
"""Test photo submission with no photo"""
view = TestView()
view.kwargs = {'pk': self.operator.pk}
view.object = self.operator
request = self.factory.post(
f'/test/{self.operator.pk}/',
data={},
format='multipart'
)
request.user = self.user
view.setup(request, pk=self.operator.pk)
response = view.handle_photo_submission(request)
self.assertIsInstance(response, JsonResponse)
self.assertEqual(response.status_code, 400)
def test_photo_submission_mixin_regular_user(self):
"""Test photo submission as regular user"""
view = TestView()
view.kwargs = {'pk': self.operator.pk}
view.object = self.operator
# Create a test photo file
photo = SimpleUploadedFile(
'test.gif',
b'GIF87a\x01\x00\x01\x00\x80\x01\x00\x00\x00\x00ccc,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;',
content_type='image/gif'
)
request = self.factory.post(
f'/test/{self.operator.pk}/',
data={'photo': photo, 'caption': 'Test Photo', 'date_taken': '2024-01-01'},
format='multipart'
)
request.user = self.user
view.setup(request, pk=self.operator.pk)
response = view.handle_photo_submission(request)
self.assertIsInstance(response, JsonResponse)
self.assertEqual(response.status_code, 200)
data = json.loads(response.content.decode())
self.assertFalse(data['auto_approved'])
def test_photo_submission_mixin_moderator(self):
"""Test photo submission as moderator"""
view = TestView()
view.kwargs = {'pk': self.operator.pk}
view.object = self.operator
# Create a test photo file
photo = SimpleUploadedFile(
'test.gif',
b'GIF87a\x01\x00\x01\x00\x80\x01\x00\x00\x00\x00ccc,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;',
content_type='image/gif'
)
request = self.factory.post(
f'/test/{self.operator.pk}/',
data={'photo': photo, 'caption': 'Test Photo', 'date_taken': '2024-01-01'},
format='multipart'
)
request.user = self.moderator
view.setup(request, pk=self.operator.pk)
response = view.handle_photo_submission(request)
self.assertIsInstance(response, JsonResponse)
self.assertEqual(response.status_code, 200)
data = json.loads(response.content.decode())
self.assertTrue(data['auto_approved'])
def test_moderator_required_mixin(self):
"""Test moderator required mixin"""
class TestModeratorView(ModeratorRequiredMixin):
pass
view = TestModeratorView()
# Test unauthenticated user
request = self.factory.get('/test/')
request.user = AnonymousUser()
view.request = request
self.assertFalse(view.test_func())
# Test regular user
request.user = self.user
view.request = request
self.assertFalse(view.test_func())
# Test moderator
request.user = self.moderator
view.request = request
self.assertTrue(view.test_func())
# Test admin
request.user = self.admin
view.request = request
self.assertTrue(view.test_func())
def test_admin_required_mixin(self):
"""Test admin required mixin"""
class TestAdminView(AdminRequiredMixin):
pass
view = TestAdminView()
# Test unauthenticated user
request = self.factory.get('/test/')
request.user = AnonymousUser()
view.request = request
self.assertFalse(view.test_func())
# Test regular user
request.user = self.user
view.request = request
self.assertFalse(view.test_func())
# Test moderator
request.user = self.moderator
view.request = request
self.assertFalse(view.test_func())
# Test admin
request.user = self.admin
view.request = request
self.assertTrue(view.test_func())
def test_inline_edit_mixin(self):
"""Test inline edit mixin"""
view = TestView()
view.kwargs = {'pk': self.operator.pk}
view.object = self.operator
# Test unauthenticated user
request = self.factory.get(f'/test/{self.operator.pk}/')
request.user = AnonymousUser()
view.setup(request, pk=self.operator.pk)
context = view.get_context_data()
self.assertNotIn('can_edit', context)
# Test regular user
request.user = self.user
view.setup(request, pk=self.operator.pk)
context = view.get_context_data()
self.assertTrue(context['can_edit'])
self.assertFalse(context['can_auto_approve'])
# Test moderator
request.user = self.moderator
view.setup(request, pk=self.operator.pk)
context = view.get_context_data()
self.assertTrue(context['can_edit'])
self.assertTrue(context['can_auto_approve'])
def test_history_mixin(self):
"""Test history mixin"""
view = TestView()
view.kwargs = {'pk': self.operator.pk}
view.object = self.operator
request = self.factory.get(f'/test/{self.operator.pk}/')
request.user = self.user
view.setup(request, pk=self.operator.pk)
# Create some edit submissions
EditSubmission.objects.create(
user=self.user,
content_type=ContentType.objects.get_for_model(Operator),
object_id=getattr(self.operator, 'id', None),
submission_type='EDIT',
changes={'name': 'New Name'},
status='APPROVED'
)
context = view.get_context_data()
self.assertIn('history', context)
self.assertIn('edit_submissions', context)
self.assertEqual(len(context['edit_submissions']), 1)