322 lines
14 KiB
Python
322 lines
14 KiB
Python
from django.contrib.auth.models import User
|
|
from django.contrib.messages import get_messages
|
|
from django.test import TestCase
|
|
from django.urls import reverse
|
|
from django.conf import settings
|
|
from django.utils.translation import gettext as _
|
|
|
|
import json
|
|
|
|
from common.models import UserConfig
|
|
|
|
|
|
class SwitchAccountViewTests(TestCase):
|
|
def setUp(self):
|
|
self.user_1 = User.objects.create_user(username="alpha", password="password123")
|
|
self.user_2 = User.objects.create_user(username="beta", password="password123")
|
|
self.user_3 = User.objects.create_user(username="gamma", password="password123")
|
|
self.user_4 = User.objects.create_user(username="delta", password="password123")
|
|
|
|
self.config_1 = UserConfig.objects.create(user=self.user_1)
|
|
self.config_2 = UserConfig.objects.create(user=self.user_2)
|
|
self.config_3 = UserConfig.objects.create(user=self.user_3)
|
|
self.config_4 = UserConfig.objects.create(user=self.user_4)
|
|
|
|
# Link the first two users together
|
|
self.config_1.linked_configs.add(self.config_2)
|
|
|
|
def test_switch_to_linked_account(self):
|
|
self.client.force_login(self.user_1)
|
|
|
|
response = self.client.post(
|
|
reverse("common:switch_account"),
|
|
{"target_user_id": self.user_2.pk, "origin_next": "/interventions/"},
|
|
)
|
|
|
|
self.assertRedirects(response, "/interventions/", target_status_code=302)
|
|
self.assertEqual(int(self.client.session["_auth_user_id"]), self.user_2.pk)
|
|
|
|
def test_switch_to_unlinked_account_is_prevented(self):
|
|
self.client.force_login(self.user_1)
|
|
|
|
response = self.client.post(
|
|
reverse("common:switch_account"),
|
|
{"target_user_id": self.user_3.pk},
|
|
)
|
|
|
|
messages = list(get_messages(response.wsgi_request))
|
|
self.assertTrue(any(_("Vous ne pouvez pas accéder à ce compte.") in message.message for message in messages))
|
|
self.assertRedirects(response, reverse("home:index"))
|
|
self.assertEqual(int(self.client.session["_auth_user_id"]), self.user_1.pk)
|
|
|
|
def test_chained_switch_uses_origin_permissions(self):
|
|
self.config_1.linked_configs.add(self.config_3)
|
|
self.config_4.linked_configs.add(self.config_2)
|
|
|
|
self.client.force_login(self.user_1)
|
|
|
|
response = self.client.post(
|
|
reverse("common:switch_account"),
|
|
{"target_user_id": self.user_2.pk},
|
|
)
|
|
|
|
self.assertRedirects(response, reverse("home:index"))
|
|
self.assertEqual(int(self.client.session["_auth_user_id"]), self.user_2.pk)
|
|
|
|
response = self.client.post(
|
|
reverse("common:switch_account"),
|
|
{"target_user_id": self.user_3.pk},
|
|
)
|
|
|
|
self.assertRedirects(response, reverse("home:index"))
|
|
self.assertEqual(int(self.client.session["_auth_user_id"]), self.user_3.pk)
|
|
|
|
response = self.client.post(
|
|
reverse("common:switch_account"),
|
|
{"target_user_id": self.user_4.pk},
|
|
)
|
|
|
|
messages = list(get_messages(response.wsgi_request))
|
|
self.assertTrue(any(_("Vous ne pouvez pas accéder à ce compte.") in message.message for message in messages))
|
|
self.assertRedirects(response, reverse("home:index"))
|
|
self.assertEqual(int(self.client.session["_auth_user_id"]), self.user_3.pk)
|
|
|
|
|
|
class LanguageSwitchingTests(TestCase):
|
|
"""Tests for language switching functionality in mobile/user settings."""
|
|
|
|
def setUp(self):
|
|
self.user = User.objects.create_user(username="testuser", password="password123")
|
|
UserConfig.objects.create(user=self.user)
|
|
|
|
def test_account_info_page_loads(self):
|
|
"""Test that the account info page loads successfully."""
|
|
self.client.force_login(self.user)
|
|
response = self.client.get(reverse("common:account_info"))
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
def test_account_info_contains_language_selector(self):
|
|
"""Test that the account info page contains language selection elements."""
|
|
self.client.force_login(self.user)
|
|
response = self.client.get(reverse("common:account_info"))
|
|
|
|
# Check for language modal and buttons
|
|
self.assertContains(response, "languageModal")
|
|
self.assertContains(response, "Français")
|
|
self.assertContains(response, "Nederlands")
|
|
self.assertContains(response, "English")
|
|
|
|
def test_set_language_to_french(self):
|
|
"""Test switching to French language."""
|
|
self.client.force_login(self.user)
|
|
|
|
response = self.client.post(
|
|
reverse("set_language"),
|
|
{"language": "fr", "next": reverse("common:account_info")},
|
|
follow=True
|
|
)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
# Check that the language cookie is set
|
|
self.assertIn(settings.LANGUAGE_COOKIE_NAME, self.client.cookies)
|
|
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, "fr")
|
|
self.user.config.refresh_from_db()
|
|
self.assertEqual(self.user.config.preferred_language, "fr")
|
|
|
|
def test_set_language_to_dutch(self):
|
|
"""Test switching to Dutch language."""
|
|
self.client.force_login(self.user)
|
|
|
|
response = self.client.post(
|
|
reverse("set_language"),
|
|
{"language": "nl", "next": reverse("common:account_info")},
|
|
follow=True
|
|
)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertIn(settings.LANGUAGE_COOKIE_NAME, self.client.cookies)
|
|
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, "nl")
|
|
self.user.config.refresh_from_db()
|
|
self.assertEqual(self.user.config.preferred_language, "nl")
|
|
|
|
def test_set_language_to_english(self):
|
|
"""Test switching to English language."""
|
|
self.client.force_login(self.user)
|
|
|
|
response = self.client.post(
|
|
reverse("set_language"),
|
|
{"language": "en", "next": reverse("common:account_info")},
|
|
follow=True
|
|
)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertIn(settings.LANGUAGE_COOKIE_NAME, self.client.cookies)
|
|
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, "en")
|
|
self.user.config.refresh_from_db()
|
|
self.assertEqual(self.user.config.preferred_language, "en")
|
|
|
|
def test_invalid_language_code(self):
|
|
"""Test that invalid language codes are handled gracefully."""
|
|
self.client.force_login(self.user)
|
|
|
|
response = self.client.post(
|
|
reverse("set_language"),
|
|
{"language": "invalid", "next": reverse("common:account_info")},
|
|
follow=True
|
|
)
|
|
|
|
# Django's set_language view should handle invalid languages gracefully
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
|
|
class HelpPanelTests(TestCase):
|
|
def setUp(self):
|
|
from common.models import Role
|
|
self.user = User.objects.create_user(username="helpuser", password="password123")
|
|
self.user_config = UserConfig.objects.create(user=self.user)
|
|
|
|
# Superuser
|
|
self.superuser = User.objects.create_superuser(username="helpsuper", password="password123")
|
|
self.superuser_config = UserConfig.objects.create(user=self.superuser)
|
|
|
|
def test_can_approve_any_intervention_property(self):
|
|
from common.models import Role
|
|
# By default, regular user cannot approve
|
|
self.assertFalse(self.user_config.can_approve_any_intervention)
|
|
|
|
# Superuser can approve
|
|
self.assertTrue(self.superuser_config.can_approve_any_intervention)
|
|
|
|
# Admin role can approve
|
|
admin_role = Role.objects.get_or_create(name='admin')[0]
|
|
self.user_config.roles.add(admin_role)
|
|
self.assertTrue(self.user_config.can_approve_any_intervention)
|
|
|
|
# Remove admin role
|
|
self.user_config.roles.remove(admin_role)
|
|
self.assertFalse(self.user_config.can_approve_any_intervention)
|
|
|
|
def test_get_help_document_prise_en_main(self):
|
|
self.client.force_login(self.user)
|
|
response = self.client.get(reverse("common:get_help_document", args=["prise_en_main"]))
|
|
self.assertEqual(response.status_code, 200)
|
|
data = response.json()
|
|
self.assertIn("html", data)
|
|
# Check that it rendered markdown headers into HTML
|
|
self.assertIn("<h1", data["html"])
|
|
|
|
def test_get_help_document_gerer_projets_access_denied(self):
|
|
# Regular user should get 403 on gerer_projets
|
|
self.client.force_login(self.user)
|
|
response = self.client.get(reverse("common:get_help_document", args=["gerer_projets"]))
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
def test_get_help_document_gerer_projets_access_granted_to_superuser(self):
|
|
# Superuser should get 200 on gerer_projets
|
|
self.client.force_login(self.superuser)
|
|
response = self.client.get(reverse("common:get_help_document", args=["gerer_projets"]))
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
def test_get_help_document_gerer_projets_access_granted_by_role(self):
|
|
from common.models import Role
|
|
# User with manager role should get 200
|
|
manager_role = Role.objects.get_or_create(name='manager')[0]
|
|
self.user_config.roles.add(manager_role)
|
|
self.client.force_login(self.user)
|
|
response = self.client.get(reverse("common:get_help_document", args=["gerer_projets"]))
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
def test_get_help_document_not_found(self):
|
|
self.client.force_login(self.user)
|
|
response = self.client.get(reverse("common:get_help_document", args=["invalid_doc_name"]))
|
|
self.assertEqual(response.status_code, 404)
|
|
|
|
def test_get_help_document_statuts_intervention(self):
|
|
self.client.force_login(self.user)
|
|
response = self.client.get(reverse("common:get_help_document", args=["statuts_intervention"]))
|
|
self.assertEqual(response.status_code, 200)
|
|
data = response.json()
|
|
self.assertIn("html", data)
|
|
# Check title
|
|
self.assertIn("Statuts des interventions", data["html"])
|
|
|
|
def test_get_help_document_creer_controle_access_denied(self):
|
|
self.client.force_login(self.user)
|
|
response = self.client.get(reverse("common:get_help_document", args=["creer_controle"]))
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
def test_get_help_document_creer_controle_access_granted_by_role(self):
|
|
from common.models import Role
|
|
manager_role = Role.objects.get_or_create(name='manager')[0]
|
|
self.user_config.roles.add(manager_role)
|
|
self.client.force_login(self.user)
|
|
response = self.client.get(reverse("common:get_help_document", args=["creer_controle"]))
|
|
self.assertEqual(response.status_code, 200)
|
|
data = response.json()
|
|
self.assertIn("html", data)
|
|
self.assertIn("Ajouter un contrôle", data["html"])
|
|
|
|
|
|
class AssetsIndexPreferencesTests(TestCase):
|
|
def setUp(self):
|
|
from common.models import Thematic
|
|
self.superuser = User.objects.create_superuser(username="superprefuser", password="password123")
|
|
Thematic.objects.create(code="sign", name_fr="Signalisation")
|
|
Thematic.objects.create(code="roads", name_fr="Voirie")
|
|
|
|
def test_save_and_restore_assets_index_preferences_for_superuser(self):
|
|
self.client.force_login(self.superuser)
|
|
save_url = reverse("common:save_assets_index_preferences")
|
|
payload = {
|
|
"thematics": ["sign", "roads"],
|
|
"categories": [1, 2],
|
|
"models": [],
|
|
"conditional_filters": {},
|
|
"visible_columns": ["code", "status"],
|
|
"type_filter": "assets",
|
|
"status_filters": ["installed"],
|
|
"validation_status_filters": ["validated"],
|
|
"include_no_geom": False,
|
|
}
|
|
response = self.client.post(save_url, json.dumps(payload), content_type="application/json")
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertTrue(response.json().get("success"))
|
|
|
|
# Verify unified_assets_index restores saved thematics and sets has_url_thematics to False
|
|
index_url = reverse("assets:index")
|
|
response = self.client.get(index_url)
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertFalse(response.context["has_url_thematics"])
|
|
self.assertEqual(response.context["selected_thematics"], ["sign", "roads"])
|
|
|
|
|
|
|
|
class UserConfigCopyTests(TestCase):
|
|
def setUp(self):
|
|
from common.models import Thematic, UserThematics
|
|
self.user_source = User.objects.create_user(username="source_user", password="password123")
|
|
self.user_target = User.objects.create_user(username="target_user", password="password123")
|
|
self.config_source = UserConfig.objects.create(user=self.user_source)
|
|
self.config_target = UserConfig.objects.create(user=self.user_target)
|
|
self.thematic, _ = Thematic.objects.get_or_create(code="parking", defaults={"name_fr": "Stationnement"})
|
|
|
|
UserThematics.objects.create(
|
|
user_config=self.config_source,
|
|
thematic=self.thematic,
|
|
can_view_assets=True,
|
|
can_inspect=True,
|
|
)
|
|
|
|
def test_copy_config_copies_can_inspect(self):
|
|
from common.admin import UserConfigAdmin
|
|
from common.models import UserThematics
|
|
admin_obj = UserConfigAdmin(UserConfig, None)
|
|
admin_obj._copy_config(self.config_source, self.config_target)
|
|
|
|
target_ut = UserThematics.objects.get(user_config=self.config_target, thematic=self.thematic)
|
|
self.assertTrue(target_ut.can_inspect)
|
|
|
|
|
|
|
|
|
|
|