From 698c287b655bdf06cfb717eb64351ebf58d730bf Mon Sep 17 00:00:00 2001 From: Roipoussiere Date: Mon, 23 Oct 2023 19:48:31 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20[Bug=20fixes]=20fix=20language?= =?UTF-8?q?=20bug=20in=20several=20detail=20pages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/changelog.rst | 1 + geotrek/diving/tests/test_views.py | 11 ++++++++++ geotrek/infrastructure/tests/test_views.py | 11 ++++++++++ geotrek/infrastructure/views.py | 8 +++++++ geotrek/outdoor/tests/test_views.py | 24 +++++++++++++++++++++ geotrek/outdoor/views.py | 15 +++++++++++++ geotrek/sensitivity/tests/test_views.py | 13 +++++++++++ geotrek/sensitivity/views.py | 8 +++++++ geotrek/signage/tests/test_views.py | 11 ++++++++++ geotrek/signage/views.py | 8 +++++++ geotrek/tourism/tests/test_views.py | 25 ++++++++++++++++++++++ geotrek/tourism/views.py | 15 +++++++++++++ geotrek/trekking/tests/test_views.py | 22 +++++++++++++++++++ geotrek/trekking/views.py | 7 ++++++ 14 files changed, 179 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index c7f0eebb10..e4d72d4715 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -10,6 +10,7 @@ CHANGELOG **Bug fixes** +- Fix language bug in several detail pages (#3577) - Fix Aggregator fails when updating Tour steps order (#3793) - Fix services list display error (refs ##3795) diff --git a/geotrek/diving/tests/test_views.py b/geotrek/diving/tests/test_views.py index 883eed30e1..dc207d9209 100644 --- a/geotrek/diving/tests/test_views.py +++ b/geotrek/diving/tests/test_views.py @@ -130,6 +130,17 @@ def test_pois_on_treks_not_public(self): response = self.client.get(reverse('diving:dive_poi_geojson', kwargs={'lang': translation.get_language(), 'pk': dive.pk})) self.assertEqual(response.status_code, 404) + def test_lang_in_detail_page(self): + dive = self.modelfactory.create(name_fr='une plongée', name_en='a dive') + + response = self.client.get(dive.get_detail_url() + '?lang=fr') + self.assertContains(response, 'une plongée') + self.assertNotContains(response, 'a dive') + + response = self.client.get(dive.get_detail_url() + '?lang=en') + self.assertContains(response, 'a dive') + self.assertNotContains(response, 'une plongée') + class DiveViewsLiveTests(CommonLiveTest): model = Dive diff --git a/geotrek/infrastructure/tests/test_views.py b/geotrek/infrastructure/tests/test_views.py index b1ffa2371f..5b4e3e34f1 100755 --- a/geotrek/infrastructure/tests/test_views.py +++ b/geotrek/infrastructure/tests/test_views.py @@ -80,6 +80,17 @@ def test_description_in_detail_page(self): response = self.client.get(infra.get_detail_url()) self.assertContains(response, "Beautiful !") + def test_lang_in_detail_page(self): + infra = InfrastructureFactory.create(name_fr='une infra', name_en='an infra') + + response = self.client.get(infra.get_detail_url() + '?lang=fr') + self.assertContains(response, 'une infra') + self.assertNotContains(response, 'an infra') + + response = self.client.get(infra.get_detail_url() + '?lang=en') + self.assertContains(response, 'an infra') + self.assertNotContains(response, 'une infra') + def test_check_structure_or_none_related_are_visible(self): infratype = InfrastructureTypeFactory.create(type=INFRASTRUCTURE_TYPES.BUILDING, structure=None) response = self.client.get(self.model.get_add_url()) diff --git a/geotrek/infrastructure/views.py b/geotrek/infrastructure/views.py index 75f2a065a2..3447948ae9 100755 --- a/geotrek/infrastructure/views.py +++ b/geotrek/infrastructure/views.py @@ -1,4 +1,5 @@ from django.conf import settings +from django.utils import translation from django.contrib.gis.db.models.functions import Transform from mapentity.views import (MapEntityList, MapEntityFormat, MapEntityDetail, MapEntityDocument, MapEntityCreate, MapEntityUpdate, MapEntityDelete) @@ -37,6 +38,13 @@ class InfrastructureFormatList(MapEntityFormat, InfrastructureList): class InfrastructureDetail(MapEntityDetail): queryset = Infrastructure.objects.existing() + def dispatch(self, *args, **kwargs): + lang = self.request.GET.get('lang') + if lang: + translation.activate(lang) + self.request.LANGUAGE_CODE = lang + return super().dispatch(*args, **kwargs) + def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) context['can_edit'] = self.get_object().same_structure(self.request.user) diff --git a/geotrek/outdoor/tests/test_views.py b/geotrek/outdoor/tests/test_views.py index f478cd3974..6acdf54f54 100644 --- a/geotrek/outdoor/tests/test_views.py +++ b/geotrek/outdoor/tests/test_views.py @@ -74,6 +74,18 @@ def test_init_form_with_parent_site(self): selected = f"" self.assertContains(response, selected) + def test_lang_in_detail_page(self): + site = SiteFactory.create(name_fr='un site', name_en='a site') + self.client.force_login(SuperUserFactory()) + + response = self.client.get(site.get_detail_url() + '?lang=fr') + self.assertContains(response, 'un site') + self.assertNotContains(response, 'a site') + + response = self.client.get(site.get_detail_url() + '?lang=en') + self.assertContains(response, 'a site') + self.assertNotContains(response, 'un site') + class CourseCustomViewTests(TestCase): @mock.patch('mapentity.helpers.requests.get') @@ -132,6 +144,18 @@ def test_serialize_ref_points(self): data = "{'type': 'MultiPoint', 'coordinates': [[12.0, 12.0]]}" self.assertEqual(str(response.json()[0]['points_reference']), data) + def test_lang_in_detail_page(self): + course = CourseFactory.create(name_fr='un parcours', name_en='a course', published=True) + self.client.force_login(SuperUserFactory()) + + response = self.client.get(course.get_detail_url() + '?lang=fr') + self.assertContains(response, 'un parcours') + self.assertNotContains(response, 'a course') + + response = self.client.get(course.get_detail_url() + '?lang=en') + self.assertContains(response, 'a course') + self.assertNotContains(response, 'un parcours') + class SiteDeleteTest(TestCase): @classmethod diff --git a/geotrek/outdoor/views.py b/geotrek/outdoor/views.py index 00e2e30a1b..e026dc9248 100644 --- a/geotrek/outdoor/views.py +++ b/geotrek/outdoor/views.py @@ -1,4 +1,5 @@ from django.conf import settings +from django.utils import translation from django.contrib.gis.db.models.functions import Transform from django.db.models import Q, Prefetch from geotrek.common.models import HDViewPoint @@ -33,6 +34,13 @@ class SiteDetail(CompletenessMixin, MapEntityDetail): queryset=HDViewPoint.objects.select_related('content_type', 'license')) ) + def dispatch(self, *args, **kwargs): + lang = self.request.GET.get('lang') + if lang: + translation.activate(lang) + self.request.LANGUAGE_CODE = lang + return super().dispatch(*args, **kwargs) + def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) context['can_edit'] = self.get_object().same_structure(self.request.user) @@ -156,6 +164,13 @@ class CourseList(CustomColumnsMixin, MapEntityList): class CourseDetail(CompletenessMixin, MapEntityDetail): queryset = Course.objects.prefetch_related('type').all() + def dispatch(self, *args, **kwargs): + lang = self.request.GET.get('lang') + if lang: + translation.activate(lang) + self.request.LANGUAGE_CODE = lang + return super().dispatch(*args, **kwargs) + def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) context['can_edit'] = self.get_object().same_structure(self.request.user) diff --git a/geotrek/sensitivity/tests/test_views.py b/geotrek/sensitivity/tests/test_views.py index f0ebb92a9c..83da92c9f2 100644 --- a/geotrek/sensitivity/tests/test_views.py +++ b/geotrek/sensitivity/tests/test_views.py @@ -4,6 +4,7 @@ from django.test import TestCase from django.test.utils import override_settings from django.urls import reverse +from mapentity.tests.factories import SuperUserFactory from geotrek.authent.tests.factories import StructureFactory, UserProfileFactory from geotrek.authent.tests.base import AuthentFixturesTest @@ -160,6 +161,18 @@ def test_detail_sensitivearea_regulatory(self): response = self.client.get(url, params) self.assertIsNone(response.json()['species_id']) + def test_lang_in_detail_page(self): + sensitivearea = SensitiveAreaFactory.create(description_fr='une zone sensible', description_en='a sentive area') + self.client.force_login(SuperUserFactory()) + + response = self.client.get(sensitivearea.get_detail_url() + '?lang=fr') + self.assertContains(response, 'une zone sensible') + self.assertNotContains(response, 'a sentive area') + + response = self.client.get(sensitivearea.get_detail_url() + '?lang=en') + self.assertContains(response, 'a sentive area') + self.assertNotContains(response, 'une zone sensible') + @override_settings(SENSITIVITY_OPENAIR_SPORT_PRACTICES=['Practice1', ]) def test_list_sensitivearea(self): url = reverse('apiv2:sensitivearea-list') diff --git a/geotrek/sensitivity/views.py b/geotrek/sensitivity/views.py index 767d072bec..b5beeb4f88 100644 --- a/geotrek/sensitivity/views.py +++ b/geotrek/sensitivity/views.py @@ -7,6 +7,7 @@ from django.db.models import F, Case, When from django.http import Http404, HttpResponse from django.shortcuts import get_object_or_404 +from django.utils import translation from django.utils.translation import ugettext_lazy as _ from django.views.generic import ListView from django.views.generic.detail import BaseDetailView @@ -53,6 +54,13 @@ class SensitiveAreaFormatList(MapEntityFormat, SensitiveAreaList): class SensitiveAreaDetail(MapEntityDetail): queryset = SensitiveArea.objects.existing() + def dispatch(self, *args, **kwargs): + lang = self.request.GET.get('lang') + if lang: + translation.activate(lang) + self.request.LANGUAGE_CODE = lang + return super().dispatch(*args, **kwargs) + def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) context['can_edit'] = self.object.same_structure(self.request.user) diff --git a/geotrek/signage/tests/test_views.py b/geotrek/signage/tests/test_views.py index 6548859e03..3ca0164a78 100755 --- a/geotrek/signage/tests/test_views.py +++ b/geotrek/signage/tests/test_views.py @@ -407,6 +407,17 @@ def test_content_in_detail_page(self): self.assertContains(response, "Beautiful !") self.assertContains(response, "(WGS 84 / Pseudo-Mercator)") + def test_lang_in_detail_page(self): + signage = SignageFactory.create(name_fr='une signalétique', name_en='a signage') + + response = self.client.get(signage.get_detail_url() + '?lang=fr') + self.assertContains(response, 'une signalétique') + self.assertNotContains(response, 'a signage') + + response = self.client.get(signage.get_detail_url() + '?lang=en') + self.assertContains(response, 'a signage') + self.assertNotContains(response, 'une signalétique') + def test_check_structure_or_none_related_are_visible(self): signagetype = SignageTypeFactory.create(structure=None) response = self.client.get(self.model.get_add_url()) diff --git a/geotrek/signage/views.py b/geotrek/signage/views.py index 18726fad96..020d817639 100755 --- a/geotrek/signage/views.py +++ b/geotrek/signage/views.py @@ -3,6 +3,7 @@ from django.conf import settings from django.contrib.gis.db.models.functions import Transform from django.http import HttpResponse +from django.utils import translation from django.utils.functional import classproperty from mapentity.views import (MapEntityList, MapEntityFormat, MapEntityDetail, MapEntityDocument, MapEntityCreate, MapEntityUpdate, MapEntityDelete) @@ -50,6 +51,13 @@ class SignageFormatList(MapEntityFormat, SignageList): class SignageDetail(MapEntityDetail): queryset = Signage.objects.existing() + def dispatch(self, *args, **kwargs): + lang = self.request.GET.get('lang') + if lang: + translation.activate(lang) + self.request.LANGUAGE_CODE = lang + return super().dispatch(*args, **kwargs) + def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) context['can_edit'] = self.get_object().same_structure(self.request.user) diff --git a/geotrek/tourism/tests/test_views.py b/geotrek/tourism/tests/test_views.py index 1aa9c4811a..a2a68a9ee2 100644 --- a/geotrek/tourism/tests/test_views.py +++ b/geotrek/tourism/tests/test_views.py @@ -14,6 +14,7 @@ from django.urls import reverse from embed_video.backends import detect_backend from paperclip.models import random_suffix_regexp +from mapentity.tests.factories import SuperUserFactory from geotrek.authent.tests.base import AuthentFixturesTest from geotrek.authent.tests.factories import (StructureFactory, UserFactory, @@ -360,6 +361,18 @@ def test_category(self): "type2_label": self.content.type2_label, "pictogram": os.path.join(settings.MEDIA_URL, self.category.pictogram.name)}) + def test_lang_in_detail_page(self): + touristic_content = TouristicContentFactory.create(name_fr='un contenu touristique', name_en='a touristic content') + self.client.force_login(SuperUserFactory()) + + response = self.client.get(touristic_content.get_detail_url() + '?lang=fr') + self.assertContains(response, 'un contenu touristique') + self.assertNotContains(response, 'a touristic content') + + response = self.client.get(touristic_content.get_detail_url() + '?lang=en') + self.assertContains(response, 'a touristic content') + self.assertNotContains(response, 'un contenu touristique') + class TouristicEventAPITest(BasicJSONAPITest, TrekkingManagerTest): factory = TouristicEventFactory @@ -398,6 +411,18 @@ def test_category(self): "type1_label": "Type", "pictogram": "/static/tourism/touristicevent.svg"}) + def test_lang_in_detail_page(self): + touristic_event = TouristicContentFactory.create(name_fr='un évenement touristique', name_en='a touristic event') + self.client.force_login(SuperUserFactory()) + + response = self.client.get(touristic_event.get_detail_url() + '?lang=fr') + self.assertContains(response, 'un évenement touristique') + self.assertNotContains(response, 'a touristic event') + + response = self.client.get(touristic_event.get_detail_url() + '?lang=en') + self.assertContains(response, 'a touristic event') + self.assertNotContains(response, 'un évenement touristique') + class TouristicEventViewsSameStructureTests(AuthentFixturesTest): @classmethod diff --git a/geotrek/tourism/views.py b/geotrek/tourism/views.py index 9119e031df..cedb98e024 100644 --- a/geotrek/tourism/views.py +++ b/geotrek/tourism/views.py @@ -6,6 +6,7 @@ from django.db.models import Q, Sum from django.http import Http404 from django.shortcuts import get_object_or_404 +from django.utils import translation from django.utils.translation import gettext as _ from django.views.generic import DetailView from django_filters.rest_framework import DjangoFilterBackend @@ -65,6 +66,13 @@ class TouristicContentFormatList(MapEntityFormat, TouristicContentList): class TouristicContentDetail(CompletenessMixin, MapEntityDetail): queryset = TouristicContent.objects.existing() + def dispatch(self, *args, **kwargs): + lang = self.request.GET.get('lang') + if lang: + translation.activate(lang) + self.request.LANGUAGE_CODE = lang + return super().dispatch(*args, **kwargs) + def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) context['can_edit'] = self.get_object().same_structure(self.request.user) @@ -217,6 +225,13 @@ def get_queryset(self): class TouristicEventDetail(CompletenessMixin, MapEntityDetail): queryset = TouristicEvent.objects.existing().select_related('place', 'cancellation_reason').prefetch_related('participants') + def dispatch(self, *args, **kwargs): + lang = self.request.GET.get('lang') + if lang: + translation.activate(lang) + self.request.LANGUAGE_CODE = lang + return super().dispatch(*args, **kwargs) + def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) context['can_edit'] = self.get_object().same_structure(self.request.user) diff --git a/geotrek/trekking/tests/test_views.py b/geotrek/trekking/tests/test_views.py index f29bfe0e74..179a2b9aac 100755 --- a/geotrek/trekking/tests/test_views.py +++ b/geotrek/trekking/tests/test_views.py @@ -223,6 +223,17 @@ def test_pois_on_treks_not_public_anonymous(self): reverse('trekking:trek_poi_geojson', kwargs={'lang': translation.get_language(), 'pk': trek.pk})) self.assertEqual(response.status_code, 404) + def test_lang_in_detail_page(self): + poi = POIFactory.create(name_fr='un POI', name_en='a POI') + + response = self.client.get(poi.get_detail_url() + '?lang=fr') + self.assertContains(response, 'un POI') + self.assertNotContains(response, 'a POI') + + response = self.client.get(poi.get_detail_url() + '?lang=en') + self.assertContains(response, 'a POI') + self.assertNotContains(response, 'un POI') + class TrekViewsTest(GeotrekAPITestCase, CommonTest): model = Trek @@ -484,6 +495,17 @@ def test_detail_lother_language(self): form = self.get_form(response) self.assertEqual(form.data['parking_location'], bad_data['parking_location']) + def test_lang_in_detail_page(self): + trek = TrekFactory.create(name_fr='un itinéraire', name_en='a trek') + + response = self.client.get(trek.get_detail_url() + '?lang=fr') + self.assertContains(response, 'un itinéraire') + self.assertNotContains(response, 'a trek') + + response = self.client.get(trek.get_detail_url() + '?lang=en') + self.assertContains(response, 'a trek') + self.assertNotContains(response, 'un itinéraire') + def test_list_in_csv(self): if self.model is None: return # Abstract test should not run diff --git a/geotrek/trekking/views.py b/geotrek/trekking/views.py index 2fb2221ad5..f84b7bd057 100755 --- a/geotrek/trekking/views.py +++ b/geotrek/trekking/views.py @@ -337,6 +337,13 @@ class POIDetail(CompletenessMixin, MapEntityDetail): queryset=HDViewPoint.objects.select_related('content_type', 'license')) ) + def dispatch(self, *args, **kwargs): + lang = self.request.GET.get('lang') + if lang: + translation.activate(lang) + self.request.LANGUAGE_CODE = lang + return super().dispatch(*args, **kwargs) + def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) context['can_edit'] = self.get_object().same_structure(self.request.user)