diff --git a/jdav_web/contrib/tests.py b/jdav_web/contrib/tests.py index 99493e1..45adca4 100644 --- a/jdav_web/contrib/tests.py +++ b/jdav_web/contrib/tests.py @@ -1,13 +1,18 @@ -from django.test import TestCase +from datetime import datetime, timedelta +from decimal import Decimal +from django.test import TestCase, RequestFactory from django.contrib.auth import get_user_model from django.contrib import admin from django.db import models -from django.test import RequestFactory -from unittest.mock import Mock +from django.core.exceptions import ValidationError +from django.core.files.uploadedfile import SimpleUploadedFile +from django.utils.translation import gettext_lazy as _ +from unittest.mock import Mock, patch from rules.contrib.models import RulesModelMixin, RulesModelBase from contrib.models import CommonModel from contrib.rules import has_global_perm from contrib.admin import CommonAdminMixin +from utils import file_size_validator, RestrictedFileField, cvt_to_decimal, get_member, normalize_name, normalize_filename, coming_midnight, mondays_until_nth User = get_user_model() @@ -91,3 +96,80 @@ class CommonAdminMixinTestCase(TestCase): # Verify that the formfield_overrides were used self.assertIsNotNone(result) + + +class UtilsTestCase(TestCase): + def setUp(self): + self.user = User.objects.create_user( + username='testuser', + email='test@example.com', + password='testpass123' + ) + + def test_file_size_validator_exceeds_limit(self): + """Test file_size_validator when file exceeds size limit""" + validator = file_size_validator(1) # 1MB limit + + # Create a mock file that exceeds the limit (2MB) + mock_file = Mock() + mock_file.size = 2 * 1024 * 1024 # 2MB + + with self.assertRaises(ValidationError) as cm: + validator(mock_file) + + # Check for the translated error message + expected_message = str(_('Please keep filesize under {} MiB. Current filesize: {:10.2f} MiB.').format(1, 2.00)) + self.assertIn(expected_message, str(cm.exception)) + + def test_restricted_file_field_content_type_not_supported(self): + """Test RestrictedFileField when content type is not supported""" + field = RestrictedFileField(content_types=['image/jpeg']) + + # Create mock data with unsupported content type + mock_data = Mock() + mock_data.file = Mock() + mock_data.file.content_type = "text/plain" + + # Mock the super().clean() to return our mock data + with patch.object(models.FileField, 'clean', return_value=mock_data): + with self.assertRaises(ValidationError) as cm: + field.clean("dummy") + + # Check for the translated error message + expected_message = str(_('Filetype not supported.')) + self.assertIn(expected_message, str(cm.exception)) + + def test_restricted_file_field_size_exceeds_limit(self): + """Test RestrictedFileField when file size exceeds limit""" + field = RestrictedFileField(max_upload_size=1) # 1 byte limit + + # Create mock data with file that exceeds size limit + mock_data = Mock() + mock_data.file = Mock() + mock_data.file.content_type = "text/plain" + mock_data.file._size = 2 # 2 bytes, exceeds limit + + # Mock the super().clean() to return our mock data + with patch.object(models.FileField, 'clean', return_value=mock_data): + with self.assertRaises(ValidationError) as cm: + field.clean("dummy") + + # Check for the translated error message + expected_message = str(_('Please keep filesize under {}. Current filesize: {}').format(1, 2)) + self.assertIn(expected_message, str(cm.exception)) + + def test_mondays_until_nth(self): + """Test mondays_until_nth function""" + # Test with n=2 to get 3 Mondays (including the 0th) + result = mondays_until_nth(2) + + # Should return a list of 3 dates + self.assertEqual(len(result), 3) + + # All dates should be Mondays (weekday 0) + for date in result: + self.assertEqual(date.weekday(), 0) # Monday is 0 + + # Dates should be consecutive weeks + self.assertEqual(result[1] - result[0], timedelta(days=7)) + self.assertEqual(result[2] - result[1], timedelta(days=7))