diff --git a/envergo/analytics/utils.py b/envergo/analytics/utils.py index a7d20c1b9..7a7f0076b 100644 --- a/envergo/analytics/utils.py +++ b/envergo/analytics/utils.py @@ -108,3 +108,15 @@ def update_url_with_matomo_params(url, request): def get_matomo_tags(request): return {k: v for k, v in request.session.items() if k.startswith("mtm_")} + + +def get_user_type(user): + """Return the type of user as a string depending on its attributes.""" + if not user or not user.is_authenticated: + return "anonymous" + if user.is_superuser or user.is_staff: + return "administrator" + elif user.is_instructor: + return "instructor" + else: + return "guest" diff --git a/envergo/moulinette/tests/test_views_haie.py b/envergo/moulinette/tests/test_views_haie.py index fd106aa1d..ab2cc161d 100644 --- a/envergo/moulinette/tests/test_views_haie.py +++ b/envergo/moulinette/tests/test_views_haie.py @@ -61,6 +61,9 @@ def test_triage(client): assert res.status_code == 200 content = res.content.decode() assert "

Doctrine du département

" in content + assert Event.objects.get( + category="simulateur", event="localisation", metadata__user_type="anonymous" + ) # GIVEN an invalid department code params = "department=00" @@ -92,6 +95,9 @@ def test_triage_result(client): content = res.content.decode() assert "Votre projet n'est pas encore pris en compte par le simulateur" in content assert "

kikoo

" in content + assert Event.objects.get( + category="simulateur", event="soumission_autre", metadata__user_type="anonymous" + ) params = "department=44&element=bosquet&travaux=entretien" full_url = f"{url}?{params}" @@ -209,7 +215,7 @@ def test_debug_result(client): ENVERGO_HAIE_DOMAIN="testserver", ENVERGO_AMENAGEMENT_DOMAIN="otherserver" ) @patch("envergo.hedges.services.get_replantation_coefficient") -def test_result_p_view_with_R_gt_0(mock_R, client): +def test_result_d_view_with_R_gt_0(mock_R, client): DCConfigHaieFactory() hedges = HedgeDataFactory() data = { @@ -230,6 +236,9 @@ def test_result_p_view_with_R_gt_0(mock_R, client): res = client.get(f"{url}?{query}") assert "Déposer une demande sans plantation" not in res.content.decode() + assert Event.objects.get( + category="simulateur", event="soumission_d", metadata__user_type="anonymous" + ) @pytest.mark.urls("config.urls_haie") @@ -237,7 +246,7 @@ def test_result_p_view_with_R_gt_0(mock_R, client): ENVERGO_HAIE_DOMAIN="testserver", ENVERGO_AMENAGEMENT_DOMAIN="otherserver" ) @patch("envergo.hedges.services.get_replantation_coefficient") -def test_result_p_view_with_R_eq_0(mock_R, client): +def test_result_d_view_with_R_eq_0(mock_R, client): DCConfigHaieFactory() hedges = HedgeDataFactory() data = { @@ -265,7 +274,7 @@ def test_result_p_view_with_R_eq_0(mock_R, client): @override_settings( ENVERGO_HAIE_DOMAIN="testserver", ENVERGO_AMENAGEMENT_DOMAIN="otherserver" ) -def test_result_p_view_non_soumis_with_r_gt_0(client): +def test_result_d_view_non_soumis_with_r_gt_0(client): DCConfigHaieFactory() hedge_lt5m = HedgeFactory( latLngs=[ @@ -293,6 +302,36 @@ def test_result_p_view_non_soumis_with_r_gt_0(client): assert "Déposer une demande sans plantation" not in res.content.decode() +@pytest.mark.urls("config.urls_haie") +@override_settings( + ENVERGO_HAIE_DOMAIN="testserver", ENVERGO_AMENAGEMENT_DOMAIN="otherserver" +) +@patch("envergo.hedges.services.get_replantation_coefficient") +def test_result_p_view(mock_R, client): + DCConfigHaieFactory() + hedges = HedgeDataFactory() + data = { + "element": "haie", + "travaux": "destruction", + "motif": "amelioration_culture", + "reimplantation": "remplacement", + "localisation_pac": "oui", + "department": "44", + "haies": hedges.id, + "lineaire_total": 100, + "transfert_parcelles": "non", + "meilleur_emplacement": "non", + } + url = reverse("moulinette_result_plantation") + query = urlencode(data) + mock_R.return_value = 0.0 + client.get(f"{url}?{query}") + + assert Event.objects.get( + category="simulateur", event="soumission_p", metadata__user_type="anonymous" + ) + + @pytest.mark.urls("config.urls_haie") @override_settings( ENVERGO_HAIE_DOMAIN="testserver", ENVERGO_AMENAGEMENT_DOMAIN="otherserver" @@ -311,7 +350,9 @@ def test_moulinette_post_form_error(client): assert res.status_code == 200 assert HOME_TITLE in res.content.decode() assert FORM_ERROR in res.content.decode() - error_event = Event.objects.filter(category="erreur", event="formulaire-simu").get() + error_event = Event.objects.get( + category="erreur", event="formulaire-simu", metadata__user_type="anonymous" + ) assert "errors" in error_event.metadata assert error_event.metadata["errors"] == { "haies": [ diff --git a/envergo/moulinette/views.py b/envergo/moulinette/views.py index e58e7d93d..47f10f590 100644 --- a/envergo/moulinette/views.py +++ b/envergo/moulinette/views.py @@ -14,6 +14,7 @@ from envergo.analytics.forms import FeedbackFormUseful, FeedbackFormUseless from envergo.analytics.utils import ( get_matomo_tags, + get_user_type, is_request_from_a_bot, log_event, update_url_with_matomo_params, @@ -269,7 +270,12 @@ def log_moulinette_event(self, moulinette, context, **kwargs): if self.request.site.domain == settings.ENVERGO_AMENAGEMENT_DOMAIN: action = self.event_action_amenagement else: - action = self.event_action_haie + # if the triage is not valid, we log a "soumission_autre" action + action = ( + self.event_action_haie + if moulinette.is_triage_valid() + else "soumission_autre" + ) mtm_keys = get_matomo_tags(self.request) export.update(mtm_keys) @@ -279,6 +285,7 @@ def log_moulinette_event(self, moulinette, context, **kwargs): action, self.request, **export, + user_type=get_user_type(self.request.user), ) @@ -334,6 +341,7 @@ def form_invalid(self, form): self.request, data=form.data, errors=form_errors, + user_type=get_user_type(self.request.user), ) return self.render_to_response(context) @@ -531,22 +539,6 @@ def get(self, request, *args, **kwargs): return res - def log_moulinette_event(self, moulinette, context): - if moulinette.is_triage_valid(): - super().log_moulinette_event(moulinette, context) - else: - # TODO Why is matomo param cleanup only happens here? - # Matomo parameters are stored in session, but some might remain in the url. - # We need to prevent duplicate values - params = get_matomo_tags(self.request) - params.update(self.request.GET.dict()) - log_event( - "simulateur", - "soumission_autre", - self.request, - **params, - ) - class MoulinetteAmenagementResult( MoulinetteResultMixin, MoulinetteMixin, BaseMoulinetteResult @@ -662,13 +654,19 @@ def get(self, request, *args, **kwargs): if not self.moulinette.department: return HttpResponseRedirect(f"{reverse("home")}#simulateur") + event_params = { + "department": self.moulinette.department.department, + "user_type": get_user_type(request.user), + } + is_alternative = bool(request.GET.get("alternative", False)) + if is_alternative: + event_params["alternative"] = "true" + log_event( "simulateur", "localisation", self.request, - **{ - "department": self.moulinette.department.department, - }, + **event_params, **get_matomo_tags(self.request), ) return self.render_to_response(self.get_context_data()) diff --git a/envergo/pages/views.py b/envergo/pages/views.py index c9ebc7a5f..28d954df8 100644 --- a/envergo/pages/views.py +++ b/envergo/pages/views.py @@ -16,7 +16,7 @@ from django.views.generic import FormView, ListView, TemplateView from config.settings.base import GEOMETRICIAN_WEBINAR_FORM_URL -from envergo.analytics.utils import log_event +from envergo.analytics.utils import get_user_type, log_event from envergo.geodata.models import Department from envergo.moulinette.models import ConfigAmenagement from envergo.moulinette.views import MoulinetteMixin @@ -79,9 +79,8 @@ def post(self, request, *args, **kwargs): "simulateur", "localisation", self.request, - **{ - "department": department.department, - }, + department=department.department, + user_type=get_user_type(request.user), ) return self.render_to_response(context) diff --git a/envergo/petitions/tests/test_views.py b/envergo/petitions/tests/test_views.py index c4f1abb3d..b3a131101 100644 --- a/envergo/petitions/tests/test_views.py +++ b/envergo/petitions/tests/test_views.py @@ -199,6 +199,9 @@ def test_petition_project_detail(mock_post, client, site): response = client.get(petition_project_url) assert response.status_code == 200 assert "moulinette" in response.context + assert Event.objects.get( + category="simulateur", event="consultation", metadata__user_type="anonymous" + ) # default PetitionProjectFactory has hedges near Aniane but is declared in department 44 assert response.context["has_hedges_outside_department"] assert "Le projet est hors du département sélectionné" in response.content.decode() diff --git a/envergo/petitions/views.py b/envergo/petitions/views.py index 4807f834a..7698f09e4 100644 --- a/envergo/petitions/views.py +++ b/envergo/petitions/views.py @@ -41,6 +41,7 @@ from envergo.analytics.utils import ( get_matomo_tags, + get_user_type, log_event, update_url_with_matomo_params, ) @@ -251,6 +252,7 @@ def form_valid(self, form): "creation", self.request, **petition_project.get_log_event_data(), + user_type=get_user_type(self.request.user), **get_matomo_tags(self.request), ) @@ -581,6 +583,7 @@ def get(self, request, *args, **kwargs): "consultation", self.request, **self.object.get_log_event_data(), + user_type=get_user_type(self.request.user), **get_matomo_tags(self.request), ) @@ -848,6 +851,7 @@ def log_event_action(self, request): self.event_action, self.request, **self.get_log_event_data(), + user_type=get_user_type(request.user), **get_matomo_tags(self.request), )