Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into feature/empower-haie-…
Browse files Browse the repository at this point in the history
…admin
  • Loading branch information
pyDez committed Nov 18, 2024
2 parents 47656be + a0eb413 commit f045daf
Show file tree
Hide file tree
Showing 61 changed files with 1,341 additions and 646 deletions.
2 changes: 2 additions & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"envergo.admin.config.EnvergoAdminConfig",
"envergo.urlmappings",
"envergo.hedges",
"envergo.petitions",
]
# https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
Expand Down Expand Up @@ -194,6 +195,7 @@
"envergo.utils.context_processors.settings_context",
"envergo.utils.context_processors.multi_sites_context",
"envergo.analytics.context_processors.analytics",
"envergo.analytics.context_processors.visitor_id",
"envergo.evaluations.context_processors.request_eval_context",
],
},
Expand Down
4 changes: 2 additions & 2 deletions config/tests/test_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ def site() -> Site:
"contact_us",
"accessibility",
"stats",
"privacy",
"terms_of_service",
"legal_mentions",
"moulinette_home",
"moulinette_result",
Expand All @@ -34,6 +32,8 @@ def site() -> Site:

AMENAGEMENT_URLS = [
# "/avis",
"privacy",
"terms_of_service",
"zone_map",
"2150_debug",
"faq",
Expand Down
1 change: 1 addition & 0 deletions config/urls_haie.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
path("", include("envergo.pages.urls_haie")),
path(_("moulinette/"), include("envergo.moulinette.urls_haie")),
path("haies/", include("envergo.hedges.urls")),
path("projet/", include("envergo.petitions.urls_haie")),
] + common_urlpatterns
9 changes: 9 additions & 0 deletions envergo/analytics/context_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,12 @@ def analytics(request):
return {
"matomo_dimensions": matomo_dimensions,
}


def visitor_id(request):
"""Add the visitor id to the templates.
Mostly useful for legal mentions and privacy static pages.
"""
visitor_id = request.COOKIES.get(VISITOR_COOKIE_NAME, "")
return {"visitor_id": visitor_id}
9 changes: 9 additions & 0 deletions envergo/analytics/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ class DisableVisitorCookie(RedirectView):

pattern_name = "legal_mentions"

def get_redirect_url(self, *args, **kwargs):
"""Redirect to the previous page.
If somehow the referer is missing, we fallback to the default redirect url.
"""
referer = self.request.META.get("HTTP_REFERER")
redirect_url = super().get_redirect_url(*args, **kwargs)
return referer or redirect_url

def post(self, request, *args, **kwargs):
response = super().post(request, *args, **kwargs)
set_visitor_id_cookie(response, "")
Expand Down
3 changes: 0 additions & 3 deletions envergo/contrib/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ def __init__(self, get_response):

def __call__(self, request):
request.urlconf = "config.urls_amenagement"
print("request.get_host()", request.get_host())
print("settings.ENV_NAME", settings.ENV_NAME)
print("settings.DATABASES", settings.DATABASES)
site = Site.objects.get_current(request)
request.site = site
request.base_template = "amenagement/base.html"
Expand Down
5 changes: 3 additions & 2 deletions envergo/evaluations/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -576,8 +576,9 @@ def get_bcc_recipients(self):
"action_requise",
)
):
perimeters = self.moulinette.sage.perimeters.all()
for perimeter in perimeters:
for perimeter, result in self.moulinette.sage.results_by_perimeter.items():
if result not in ("interdit", "soumis", "action_requise"):
continue
if perimeter.contact_email:
bcc_recipients.append(perimeter.contact_email)
else:
Expand Down
58 changes: 54 additions & 4 deletions envergo/evaluations/tests/test_eval_emails.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ def moulinette_url(footprint):
return f"https://envergo.beta.gouv.fr?{url}"


def fake_moulinette(url, lse, n2000, evalenv, sage, **eval_kwargs):
def fake_moulinette(
url, lse, n2000, evalenv, sage, sage_results_by_perimeter=None, **eval_kwargs
):
"""Create a moulinette with custom regulation results."""

eval_params = {
Expand All @@ -79,6 +81,7 @@ def fake_moulinette(url, lse, n2000, evalenv, sage, **eval_kwargs):

# We create mocks based on a real regulation, so it's easier to fake results
regulation = RegulationFactory()
sage_perimeter = Mock(contact_email="[email protected]")
moulinette.regulations = [
Mock(
regulation,
Expand All @@ -105,11 +108,14 @@ def fake_moulinette(url, lse, n2000, evalenv, sage, **eval_kwargs):
regulation,
wraps=regulation,
result=sage,
perimeters=Mock(
all=MagicMock(return_value=[Mock(contact_email="[email protected]")])
),
perimeters=Mock(all=MagicMock(return_value=[sage_perimeter])),
slug="sage",
do_not_call_in_templates=True,
results_by_perimeter=(
sage_results_by_perimeter
if sage_results_by_perimeter
else {sage_perimeter: sage}
),
),
]

Expand Down Expand Up @@ -650,3 +656,47 @@ def test_n2000_ein_out_of_n2000_site_no_bcc(rf, moulinette_url):
eval_email = eval.get_evaluation_email()
email = eval_email.get_email(req)
assert "[email protected]" not in email.bcc


@pytest.mark.parametrize("footprint", [1200])
def test_multiple_sage(rf, moulinette_url):
"""Test email when evalreq is:
- created by an instructor
- the eval result is "soumis"
- there is multiple Sage perimeter impacted with different results
"""
eval_kwargs = {
"user_type": USER_TYPES.instructor,
"moulinette_url": moulinette_url,
"send_eval_to_project_owner": True,
}
eval, moulinette = fake_moulinette(
moulinette_url,
"soumis",
"soumis",
"systematique",
"soumis",
sage_results_by_perimeter={
Mock(contact_email="[email protected]"): "interdit",
Mock(contact_email="[email protected]"): "action_requise",
Mock(contact_email="[email protected]"): "non_disponible",
},
**eval_kwargs,
)

req = rf.get("/")
eval_email = eval.get_evaluation_email()
email = eval_email.get_email(req)
assert email.to == ["[email protected]", "[email protected]"]
assert email.cc == ["[email protected]"]

assert email.bcc == [
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
]

body = email.body
assert "À transmettre au porteur" not in body
7 changes: 3 additions & 4 deletions envergo/evaluations/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,15 +561,14 @@ def test_eval_detail_shows_latest_published_version_content(client):
assert "This is version 2" in res.content.decode()


def test_eval_detail_without_versions_renders_content(client):
"""When there is no existing version, the eval detail page renders the content dynamically."""
def test_eval_detail_without_versions_does_not_render_content(client):
"""When there is no existing version, the eval detail page is not available."""
eval = EvaluationFactory(versions=[])
assert eval.versions.count() == 0

url = eval.get_absolute_url()
res = client.get(url)
assert res.status_code == 200
assert "<h1>Avis réglementaire</h1>" in res.content.decode()
assert res.status_code == 404


def test_only_one_version_can_be_published():
Expand Down
5 changes: 5 additions & 0 deletions envergo/evaluations/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ def get_queryset(self):
)
)
)

# AR not yet published should not be displayed unless in preview
if "preview" not in self.request.GET:
qs = qs.filter(versions__isnull=False).distinct()

return qs


Expand Down
6 changes: 0 additions & 6 deletions envergo/hedges/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import json

from django.http import JsonResponse
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.views.decorators.clickjacking import xframe_options_sameorigin
from django.views.decorators.csrf import csrf_exempt
Expand Down Expand Up @@ -34,11 +33,6 @@ def get_context_data(self, **kwargs):
hedge_data = json.dumps(self.object.data) if self.object else "[]"
context["hedge_data_json"] = hedge_data

if self.object:
save_url = reverse("input_hedges", args=[self.object.id])
else:
save_url = reverse("input_hedges")
context["save_url"] = save_url
return context

def post(self, request, *args, **kwargs):
Expand Down
21 changes: 21 additions & 0 deletions envergo/moulinette/forms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,29 @@ class MoulinetteFormAmenagement(BaseMoulinetteForm):
),
required=True,
min_value=0,
max_value=10000000,
help_text="Surface au sol nouvellement impactée par le projet",
widget=forms.TextInput(attrs={"placeholder": _("In square meters")}),
display_unit="m²",
display_label="Surface nouvellement impactée par le projet :",
display_help_text="Bâti, voirie, espaces verts, remblais et bassins — temporaires et définitifs",
error_messages={
"max_value": "La valeur saisie est trop élevée. Veuillez saisir un nombre inférieur à 10 000 000.",
},
)
existing_surface = DisplayIntegerField(
label=_("Existing surface before the project"),
required=False,
min_value=0,
max_value=10000000,
help_text="Construction, voirie, espaces verts, remblais et bassins",
widget=forms.HiddenInput,
display_unit="m²",
display_label="Surface déjà impactée avant le projet :",
display_help_text="Bâti, voirie, espaces verts, remblais et bassins",
error_messages={
"max_value": "La valeur saisie est trop élevée. Veuillez saisir un nombre inférieur à 10 000 000.",
},
)
final_surface = DisplayIntegerField(
label=mark_safe(
Expand All @@ -64,11 +72,15 @@ class MoulinetteFormAmenagement(BaseMoulinetteForm):
),
required=False,
min_value=0,
max_value=10000000,
help_text="Surface au sol impactée totale, en comptant l'existant",
widget=forms.TextInput(attrs={"placeholder": _("In square meters")}),
display_unit="m²",
display_label="Surface impactée totale, y compris l'existant :",
display_help_text="Bâti, voirie, espaces verts, remblais et bassins — temporaires et définitifs",
error_messages={
"max_value": "La valeur saisie est trop élevée. Veuillez saisir un nombre inférieur à 10 000 000.",
},
)
address = forms.CharField(
label=_("Search for the address to center the map"),
Expand Down Expand Up @@ -247,6 +259,15 @@ def clean(self):

return data

def clean_haies(self):
haies = self.cleaned_data["haies"]
if haies.length_to_remove() == 0:
self.add_error(
"haies",
"Vous devez indiquer les haies à arracher.",
)
return haies


class TriageFormHaie(forms.Form):
department = DisplayCharField(
Expand Down
Loading

0 comments on commit f045daf

Please sign in to comment.