loko/streetup/common/tests.py

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)