mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 16:11:08 -05:00
331 lines
12 KiB
Python
331 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 companies.models import Company
|
|
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 = Company
|
|
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.company = Company.objects.create(
|
|
name='Test Company',
|
|
website='http://example.com',
|
|
headquarters='Test HQ',
|
|
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.company.pk}/')
|
|
request.user = AnonymousUser()
|
|
view.setup(request, pk=self.company.pk)
|
|
view.kwargs = {'pk': self.company.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.company.pk}/',
|
|
data=json.dumps({}),
|
|
content_type='application/json'
|
|
)
|
|
request.user = self.user
|
|
view.setup(request, pk=self.company.pk)
|
|
view.kwargs = {'pk': self.company.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.company.pk}/',
|
|
data='invalid json',
|
|
content_type='application/json'
|
|
)
|
|
request.user = self.user
|
|
view.setup(request, pk=self.company.pk)
|
|
view.kwargs = {'pk': self.company.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.company.pk}/')
|
|
request.user = self.user
|
|
view.setup(request, pk=self.company.pk)
|
|
view.kwargs = {'pk': self.company.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.company.pk}/')
|
|
request.user = self.moderator
|
|
view.setup(request, pk=self.company.pk)
|
|
view.kwargs = {'pk': self.company.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.company.pk}
|
|
view.object = self.company
|
|
|
|
request = self.factory.post(
|
|
f'/test/{self.company.pk}/',
|
|
data={},
|
|
format='multipart'
|
|
)
|
|
request.user = AnonymousUser()
|
|
view.setup(request, pk=self.company.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.company.pk}
|
|
view.object = self.company
|
|
|
|
request = self.factory.post(
|
|
f'/test/{self.company.pk}/',
|
|
data={},
|
|
format='multipart'
|
|
)
|
|
request.user = self.user
|
|
view.setup(request, pk=self.company.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.company.pk}
|
|
view.object = self.company
|
|
|
|
# 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.company.pk}/',
|
|
data={'photo': photo, 'caption': 'Test Photo', 'date_taken': '2024-01-01'},
|
|
format='multipart'
|
|
)
|
|
request.user = self.user
|
|
view.setup(request, pk=self.company.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.company.pk}
|
|
view.object = self.company
|
|
|
|
# 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.company.pk}/',
|
|
data={'photo': photo, 'caption': 'Test Photo', 'date_taken': '2024-01-01'},
|
|
format='multipart'
|
|
)
|
|
request.user = self.moderator
|
|
view.setup(request, pk=self.company.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.company.pk}
|
|
view.object = self.company
|
|
|
|
# Test unauthenticated user
|
|
request = self.factory.get(f'/test/{self.company.pk}/')
|
|
request.user = AnonymousUser()
|
|
view.setup(request, pk=self.company.pk)
|
|
context = view.get_context_data()
|
|
self.assertNotIn('can_edit', context)
|
|
|
|
# Test regular user
|
|
request.user = self.user
|
|
view.setup(request, pk=self.company.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.company.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.company.pk}
|
|
view.object = self.company
|
|
request = self.factory.get(f'/test/{self.company.pk}/')
|
|
request.user = self.user
|
|
view.setup(request, pk=self.company.pk)
|
|
|
|
# Create some edit submissions
|
|
EditSubmission.objects.create(
|
|
user=self.user,
|
|
content_type=ContentType.objects.get_for_model(Company),
|
|
object_id=getattr(self.company, '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)
|