from django.test import TestCase, Client from django.contrib.auth.models import User from django.core.files.uploadedfile import SimpleUploadedFile from django.urls import reverse from common.models import UserConfig, AppView from .models import GeocodingTask from .forms import GeocodingUploadForm import io class SchoolsAppViewTestCase(TestCase): """Test cases for the Schools app view setup""" def setUp(self): # Create a test user self.user = User.objects.create_user( username='testuser', email='test@example.com', password='testpass123' ) # Create user config self.user_config = UserConfig.objects.create(user=self.user) # Create Schools AppView self.schools_view = AppView.objects.create( code='schools', name_fr='Écoles', name_nl='Scholen', icon='bi-building', url_name='schools:index', is_default=False, order=30 ) def test_appview_created(self): """Test that Schools AppView can be created""" self.assertEqual(self.schools_view.code, 'schools') self.assertEqual(self.schools_view.name_fr, 'Écoles') self.assertEqual(self.schools_view.url_name, 'schools:index') def test_user_without_permission(self): """Test that user without permission cannot access schools view""" client = Client() client.login(username='testuser', password='testpass123') response = client.get(reverse('schools:index')) self.assertEqual(response.status_code, 403) # Permission denied def test_user_with_permission(self): """Test that user with permission can access schools view""" # Grant access to schools view self.user_config.accessible_views.add(self.schools_view) client = Client() client.login(username='testuser', password='testpass123') response = client.get(reverse('schools:index')) self.assertEqual(response.status_code, 200) class GeocodingTaskModelTestCase(TestCase): """Test cases for the GeocodingTask model""" def setUp(self): self.user = User.objects.create_user( username='testuser', email='test@example.com', password='testpass123' ) def test_geocoding_task_creation(self): """Test that GeocodingTask can be created""" task = GeocodingTask.objects.create( user=self.user, status='pending' ) self.assertEqual(task.user, self.user) self.assertEqual(task.status, 'pending') self.assertEqual(task.total_rows, 0) def test_geocoding_task_str(self): """Test string representation of GeocodingTask""" task = GeocodingTask.objects.create( user=self.user, status='completed' ) expected = f"Tâche {task.id} - {self.user.username} - completed" self.assertEqual(str(task), expected) class GeocodingUploadFormTestCase(TestCase): """Test cases for the GeocodingUploadForm""" def test_valid_excel_file(self): """Test form with valid Excel file""" # Create a simple Excel file in memory excel_content = b'PK\x03\x04' # Minimal xlsx signature file = SimpleUploadedFile( "test.xlsx", excel_content, content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) form = GeocodingUploadForm(files={'uploaded_file': file}) # Note: The form may be valid or invalid depending on actual file content # This test just ensures the form can handle file input self.assertIn('uploaded_file', form.fields) def test_invalid_file_extension(self): """Test form rejects non-Excel files""" file = SimpleUploadedFile( "test.txt", b"test content", content_type="text/plain" ) form = GeocodingUploadForm(files={'uploaded_file': file}) form.is_valid() self.assertIn('uploaded_file', form.errors) def test_file_too_large(self): """Test form rejects files larger than 10MB""" # Create a file larger than 10MB large_content = b'x' * (11 * 1024 * 1024) # 11MB file = SimpleUploadedFile( "large.xlsx", large_content, content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) form = GeocodingUploadForm(files={'uploaded_file': file}) form.is_valid() self.assertIn('uploaded_file', form.errors) class GeolocationViewTestCase(TestCase): """Test cases for the geolocation views""" def setUp(self): self.user = User.objects.create_user( username='testuser', email='test@example.com', password='testpass123' ) self.user_config = UserConfig.objects.create(user=self.user) from django.utils import translation translation.activate('fr') self.schools_view = AppView.objects.create( code='schools', name_fr='Écoles', name_nl='Scholen', icon='bi-building', url_name='schools:index', is_default=False, order=30 ) # Grant access self.user_config.accessible_views.add(self.schools_view) self.client = Client() self.client.login(username='testuser', password='testpass123') def test_geolocation_view_loads(self): """Test that geolocation view loads successfully""" response = self.client.get(reverse('schools:geolocation')) self.assertEqual(response.status_code, 200) self.assertContains(response, 'Géolocalisation') def test_geolocation_view_shows_user_tasks(self): """Test that user's tasks are displayed""" # Create a task for the user task = GeocodingTask.objects.create( user=self.user, status='completed', total_rows=10, successful_geocodes=8 ) response = self.client.get(reverse('schools:geolocation')) self.assertEqual(response.status_code, 200) self.assertContains(response, 'Completed')