You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kompass/jdav_web/contrib/tests.py

320 lines
12 KiB
Python

from django.test import TestCase, RequestFactory
from django.test.utils import override_settings
from django.contrib.auth import get_user_model
from django.contrib import admin
from django.contrib.admin.sites import AdminSite
from django.db import models
from unittest.mock import Mock
from contrib.admin import CommonAdminMixin
from contrib.models import CommonModel
from contrib.rules import has_global_perm
from rules.contrib.models import RulesModelMixin, RulesModelBase
# Test model for admin customization
class DummyModel(models.Model):
field1 = models.CharField(max_length=100)
field2 = models.IntegerField()
field3 = models.BooleanField()
field4 = models.DateField()
field5 = models.TextField()
class Meta:
app_label = 'contrib'
class DummyAdmin(CommonAdminMixin, admin.ModelAdmin):
model = DummyModel
fieldsets = (
('Group1', {'fields': ('field1', 'field2')}),
('Group2', {'fields': ('field3', 'field4', 'field5')}),
)
fields = ['field1', 'field2', 'field3', 'field4', 'field5']
def __init__(self):
self.opts = self.model._meta
self.admin_site = AdminSite()
User = get_user_model()
class CommonModelTestCase(TestCase):
def test_common_model_abstract_base(self):
"""Test that CommonModel provides the correct meta attributes"""
meta = CommonModel._meta
self.assertTrue(meta.abstract)
expected_permissions = (
'add_global', 'change_global', 'view_global', 'delete_global', 'list_global', 'view',
)
self.assertEqual(meta.default_permissions, expected_permissions)
def test_common_model_inheritance(self):
"""Test that CommonModel has rules mixin functionality"""
# Test that CommonModel has the expected functionality
# Since it's abstract, we can't instantiate it directly
# but we can check its metaclass and mixins
self.assertTrue(issubclass(CommonModel, RulesModelMixin))
self.assertEqual(CommonModel.__class__, RulesModelBase)
class GlobalPermissionRulesTestCase(TestCase):
def setUp(self):
self.user = User.objects.create_user(
username='testuser',
email='test@example.com',
password='testpass123'
)
def test_has_global_perm_predicate_creation(self):
"""Test that has_global_perm creates a predicate function"""
# has_global_perm is a decorator factory, not a direct predicate
predicate = has_global_perm('auth.add_user')
self.assertTrue(callable(predicate))
def test_has_global_perm_with_superuser(self):
"""Test that superusers have global permissions"""
self.user.is_superuser = True
self.user.save()
predicate = has_global_perm('auth.add_user')
result = predicate(self.user, None)
self.assertTrue(result)
def test_has_global_perm_with_regular_user(self):
"""Test that regular users don't automatically have global permissions"""
predicate = has_global_perm('auth.add_user')
result = predicate(self.user, None)
self.assertFalse(result)
class CommonAdminMixinTestCase(TestCase):
@classmethod
def setUpTestData(cls):
cls.user = User.objects.create_superuser('admin', 'admin@test.com', 'password')
def setUp(self):
self.request = RequestFactory().get('/')
self.request.user = self.__class__.user
self.admin = DummyAdmin()
self.admin.admin_site = AdminSite()
def test_formfield_for_dbfield_with_formfield_overrides(self):
"""Test formfield_for_dbfield when db_field class is in formfield_overrides"""
# Create a test admin instance that inherits from Django's ModelAdmin
class TestAdmin(CommonAdminMixin, admin.ModelAdmin):
formfield_overrides = {
models.ForeignKey: {'widget': Mock()}
}
# Create a mock model to use with the admin
class TestModel:
_meta = Mock()
_meta.app_label = 'test'
admin_instance = TestAdmin(TestModel, admin.site)
# Create a mock ForeignKey field to trigger the missing line 147
db_field = models.ForeignKey(User, on_delete=models.CASCADE)
# Create a test request
request = RequestFactory().get('/')
request.user = self.user
# Call the method to test formfield_overrides usage
result = admin_instance.formfield_for_dbfield(db_field, request, help_text='Test help text')
# Verify that the formfield_overrides were used
self.assertIsNotNone(result)
def test_default_behavior(self):
"""Test with no customization settings"""
fields = self.admin.get_fields(self.request)
self.assertEqual(fields, ['field1', 'field2', 'field3', 'field4', 'field5'])
fieldsets = self.admin.get_fieldsets(self.request)
self.assertEqual(len(fieldsets), 2)
self.assertEqual(fieldsets[0][1]['fields'], ['field1', 'field2'])
self.assertEqual(fieldsets[1][1]['fields'], ['field3', 'field4', 'field5'])
@override_settings(CUSTOM_MODEL_FIELDS={
'contrib_dummymodel': {
'fields': ['field1', 'field3', 'field5']
}
})
def test_included_fields_only(self):
"""Test with only included fields specified"""
fields = self.admin.get_fields(self.request)
self.assertEqual(fields, ['field1', 'field3', 'field5'])
fieldsets = self.admin.get_fieldsets(self.request)
self.assertEqual(len(fieldsets), 2)
self.assertEqual(fieldsets[0][1]['fields'], ['field1'])
self.assertEqual(fieldsets[1][1]['fields'], ['field3', 'field5'])
@override_settings(CUSTOM_MODEL_FIELDS={
'contrib_dummymodel': {
'exclude': ['field2', 'field4']
}
})
def test_excluded_fields_only(self):
"""Test with only excluded fields specified"""
fields = self.admin.get_fields(self.request)
self.assertEqual(fields, ['field1', 'field3', 'field5'])
fieldsets = self.admin.get_fieldsets(self.request)
self.assertEqual(len(fieldsets), 2)
self.assertEqual(fieldsets[0][1]['fields'], ['field1'])
self.assertEqual(fieldsets[1][1]['fields'], ['field3', 'field5'])
@override_settings(CUSTOM_MODEL_FIELDS={
'contrib_dummymodel': {
'fields': ['field1', 'field3', 'field5'],
'exclude': ['field3']
}
})
def test_included_and_excluded_fields(self):
"""Test with both included and excluded fields"""
fields = self.admin.get_fields(self.request)
# custom fields should take precedence over exclude
self.assertEqual(fields, ['field1', 'field3', 'field5'])
fieldsets = self.admin.get_fieldsets(self.request)
self.assertEqual(len(fieldsets), 2)
self.assertEqual(fieldsets[0][1]['fields'], ['field1'])
self.assertEqual(fieldsets[1][1]['fields'], ['field3', 'field5'])
@override_settings(CUSTOM_MODEL_FIELDS={
'contrib_dummymodel': {
'fields': ['field5', 'field3', 'field1']
}
})
def test_field_order_preservation(self):
"""Test that field order from settings is preserved"""
fields = self.admin.get_fields(self.request)
self.assertEqual(fields, ['field5', 'field3', 'field1'])
def test_nonexistent_fields(self):
"""Test behavior with nonexistent fields in settings"""
with override_settings(CUSTOM_MODEL_FIELDS={
'contrib_dummymodel': {
'fields': ['field1', 'nonexistent_field']
}
}):
fields = self.admin.get_fields(self.request)
self.assertEqual(fields, ['field1', 'nonexistent_field'])
def test_nonexistent_exclude(self):
"""Test behavior with nonexistent fields in settings"""
with override_settings(CUSTOM_MODEL_FIELDS={
'contrib_dummymodel': {
'exclude': ['field1', 'nonexistent', 'field2']
}
}):
fields = self.admin.get_fields(self.request)
self.assertEqual(fields, ['field3', 'field4', 'field5'])
exclude = self.admin.get_exclude(self.request)
self.assertEqual(set(exclude), {'nonexistent', 'field1', 'field2'})
@override_settings(CUSTOM_MODEL_FIELDS={})
def test_empty_settings(self):
"""Test behavior with empty settings"""
fields = self.admin.get_fields(self.request)
self.assertEqual(fields, ['field1', 'field2', 'field3', 'field4', 'field5'])
fieldsets = self.admin.get_fieldsets(self.request)
self.assertEqual(len(fieldsets), 2)
self.assertEqual(fieldsets[0][1]['fields'], ['field1', 'field2'])
self.assertEqual(fieldsets[1][1]['fields'], ['field3', 'field4', 'field5'])
@override_settings(CUSTOM_MODEL_FIELDS={
'contrib_dummymodel': {
'fields': []
}
})
def test_empty_included_fields(self):
"""Test behavior with empty included fields list"""
fields = self.admin.get_fields(self.request)
# empty custom fields is perceived as no restriction
self.assertEqual(fields, ['field1', 'field2', 'field3', 'field4', 'field5'])
@override_settings(CUSTOM_MODEL_FIELDS={
'contrib_dummymodel': {
'exclude': ['field1', 'field2', 'field3', 'field4', 'field5']
}
})
def test_exclude_all_fields(self):
"""Test behavior when all fields are excluded"""
fields = self.admin.get_fields(self.request)
self.assertEqual(fields, [])
fieldsets = self.admin.get_fieldsets(self.request)
# as all fields from group2 are excluded, only group1 remains
self.assertEqual(len(fieldsets), 0)
@override_settings(CUSTOM_MODEL_FIELDS={
'contrib_dummymodel': {
'exclude': ['field5']
}
})
def test_custom_fields_exclude_exclude(self):
"""Test that custom excluded fields are respected"""
class OrderedAdmin(DummyAdmin):
exclude = ['field2', 'field4']
admin_instance = OrderedAdmin()
exclude = admin_instance.get_exclude(self.request)
# app and custom excludes should be additive
self.assertEqual(set(exclude), {'field2', 'field4', 'field5'})
fields = admin_instance.get_fields(self.request)
self.assertEqual(fields, ['field1', 'field3'])
fieldsets = admin_instance.get_fieldsets(self.request)
# for fieldsets, the app exclude is irrelevant, thus only field5 is excluded
self.assertEqual(len(fieldsets), 2)
self.assertEqual(fieldsets[0][1]['fields'], ['field1', 'field2'])
self.assertEqual(fieldsets[1][1]['fields'], ['field3', 'field4'])
@override_settings(CUSTOM_MODEL_FIELDS={
'contrib_dummymodel': {
'exclude': ['field3', 'field4', 'field5']
}
})
def test_custom_fields_fields_exclude(self):
"""Test that custom excluded fields are respected"""
class OrderedAdmin(DummyAdmin):
fields = ['field1', 'field2', 'field4']
admin_instance = OrderedAdmin()
exclude = admin_instance.get_exclude(self.request)
self.assertEqual(set(exclude), {'field3', 'field4', 'field5'})
fields = admin_instance.get_fields(self.request)
self.assertEqual(fields, ['field1', 'field2'])
fieldsets = admin_instance.get_fieldsets(self.request)
# as all fields from group2 are excluded, only group1 remains
self.assertEqual(len(fieldsets), 1)
self.assertEqual(fieldsets[0][1]['fields'], ['field1', 'field2'])
@override_settings(CUSTOM_MODEL_FIELDS={
'contrib_dummymodel': {
'exclude': ['field2', 'field4']
}
})
def test_combined_admin_and_settings_exclude(self):
"""Test that both admin and settings excludes are applied while maintaining order"""
class CombinedAdmin(DummyAdmin):
fields = ['field5', 'field4', 'field3', 'field2', 'field1']
exclude = ['field1']
admin_instance = CombinedAdmin()
fields = admin_instance.get_fields(self.request)
self.assertEqual(fields, ['field5', 'field3'])
exclude = admin_instance.get_exclude(self.request)
self.assertEqual(set(exclude), {'field1', 'field2', 'field4'})