132 lines
5.6 KiB
Python
132 lines
5.6 KiB
Python
from django.test import TestCase, Client
|
|
from django.urls import reverse
|
|
from django.contrib.auth import get_user_model
|
|
from common.models import UserConfig, Thematic
|
|
from projects.models import Project, ProjectTag
|
|
import json
|
|
|
|
User = get_user_model()
|
|
|
|
class ProjectFiltersPreferencesTest(TestCase):
|
|
def setUp(self):
|
|
# Create users
|
|
self.user = User.objects.create_user(username="testuser", password="password123")
|
|
self.user_config = UserConfig.objects.create(user=self.user, is_intern=True)
|
|
|
|
# Create thematics
|
|
self.thematic_a = Thematic.objects.create(code="them_a", name_fr="Thématique A", name_nl="Thema A")
|
|
self.thematic_b = Thematic.objects.create(code="them_b", name_fr="Thématique B", name_nl="Thema B")
|
|
|
|
# Create projects
|
|
self.project_a = Project.objects.create(
|
|
name="Project A",
|
|
created_by=self.user,
|
|
status="in_preparation",
|
|
start_date="2026-06-01",
|
|
end_date="2026-06-30"
|
|
)
|
|
self.project_a.thematics.add(self.thematic_a)
|
|
|
|
self.project_b = Project.objects.create(
|
|
name="Project B",
|
|
created_by=self.user,
|
|
status="in_progress",
|
|
start_date="2026-07-01",
|
|
end_date="2026-07-31"
|
|
)
|
|
self.project_b.thematics.add(self.thematic_b)
|
|
|
|
# Client setup
|
|
self.client = Client()
|
|
self.client.login(username="testuser", password="password123")
|
|
|
|
def test_projects_index_view(self):
|
|
# Ensure view loads and context contains necessary choices
|
|
response = self.client.get(reverse('projects:projects_index'))
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertIn('thematic_choices', response.context)
|
|
self.assertIn('selected_thematics', response.context)
|
|
self.assertIn('saved_sort', response.context)
|
|
|
|
# Check that thematic choices are populated
|
|
thematics = list(response.context['thematic_choices'])
|
|
self.assertEqual(len(thematics), 2)
|
|
|
|
def test_projects_geojson_thematic_filter(self):
|
|
# Without filter, return all (within permissions limit)
|
|
response = self.client.get(reverse('projects:projects_geojson'))
|
|
self.assertEqual(response.status_code, 200)
|
|
data = json.loads(response.content)
|
|
self.assertEqual(len(data['features']), 2)
|
|
|
|
# Filter by thematic_a
|
|
response = self.client.get(reverse('projects:projects_geojson'), {'thematic': ['them_a']})
|
|
self.assertEqual(response.status_code, 200)
|
|
data = json.loads(response.content)
|
|
self.assertEqual(len(data['features']), 1)
|
|
self.assertEqual(data['features'][0]['id'], self.project_a.id)
|
|
|
|
# Filter by thematic_b
|
|
response = self.client.get(reverse('projects:projects_geojson'), {'thematic': ['them_b']})
|
|
self.assertEqual(response.status_code, 200)
|
|
data = json.loads(response.content)
|
|
self.assertEqual(len(data['features']), 1)
|
|
self.assertEqual(data['features'][0]['id'], self.project_b.id)
|
|
|
|
def test_projects_geojson_date_filter(self):
|
|
# Date filter should successfully map start_date / end_date
|
|
response = self.client.get(reverse('projects:projects_geojson'), {'begin_date': '2026-06-15'})
|
|
self.assertEqual(response.status_code, 200)
|
|
data = json.loads(response.content)
|
|
# Should return Project B since its start_date is 2026-07-01 >= 2026-06-15 (Project A start_date is 2026-06-01 < 2026-06-15)
|
|
self.assertEqual(len(data['features']), 1)
|
|
self.assertEqual(data['features'][0]['id'], self.project_b.id)
|
|
|
|
response = self.client.get(reverse('projects:projects_geojson'), {'end_date': '2026-07-15'})
|
|
self.assertEqual(response.status_code, 200)
|
|
data = json.loads(response.content)
|
|
# Should return Project A since its end_date is 2026-06-30 <= 2026-07-15 (Project B end_date is 2026-07-31 > 2026-07-15)
|
|
self.assertEqual(len(data['features']), 1)
|
|
self.assertEqual(data['features'][0]['id'], self.project_a.id)
|
|
|
|
def test_save_preferences_endpoint(self):
|
|
filters_data = {
|
|
'status': ['in_preparation'],
|
|
'thematic': ['them_a'],
|
|
'begin_date': '2026-06-01'
|
|
}
|
|
sort_data = {
|
|
'sortName': 'title',
|
|
'sortOrder': 'desc'
|
|
}
|
|
|
|
# Save preferences POST request
|
|
response = self.client.post(
|
|
reverse('common:save_project_list_preferences'),
|
|
data=json.dumps({'filters': filters_data, 'sort': sort_data}),
|
|
content_type='application/json',
|
|
HTTP_X_REQUESTED_WITH='XMLHttpRequest'
|
|
)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
# Verify db persistence
|
|
self.user_config.refresh_from_db()
|
|
self.assertEqual(self.user_config.project_list_filters, filters_data)
|
|
self.assertEqual(self.user_config.project_list_sort, sort_data)
|
|
|
|
def test_saved_preferences_redirect(self):
|
|
# Populate saved preferences first
|
|
filters_data = {'status': ['in_preparation'], 'thematic': ['them_a']}
|
|
self.user_config.project_list_filters = filters_data
|
|
self.user_config.save()
|
|
|
|
# Visit index page without GET params
|
|
response = self.client.get(reverse('projects:projects_index'))
|
|
|
|
# Should redirect to index page with query parameters
|
|
self.assertEqual(response.status_code, 302)
|
|
self.assertIn("status=in_preparation", response.url)
|
|
self.assertIn("thematic=them_a", response.url)
|
|
|
|
|
|
|