Skip to content

Commit

Permalink
tests: add strict_template_literal pytest marker
Browse files Browse the repository at this point in the history
To detect even more unexisting variables in templates
  • Loading branch information
xavfernandez committed Apr 30, 2024
1 parent 7b4ba63 commit 37afc61
Show file tree
Hide file tree
Showing 23 changed files with 97 additions and 0 deletions.
1 change: 1 addition & 0 deletions tests/approvals/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,7 @@ def test_create_pe_approval_manually(self):

@pytest.mark.usefixtures("unittest_compatibility")
class CustomApprovalAdminViewsTest(MessagesTestMixin, TestCase):
@pytest.mark.ignore_unknown_variable_template_error
def test_manually_add_approval(self):
# When a Pôle emploi ID has been forgotten and the user has no NIR, an approval must be delivered
# with a manual verification.
Expand Down
25 changes: 25 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ def pytest_configure(config) -> None:
hook_impl.plugin_name == "randomly", # Then pytest-randomly's and after that all the other ones
)
)
config.addinivalue_line(
"markers", "ignore_unknown_variable_template_error: ignore unknown variable error in templates"
)


@pytest.fixture
Expand Down Expand Up @@ -280,6 +283,28 @@ def _fail_for_invalid_template_variable_improved(_fail_for_invalid_template_vari
)


@pytest.fixture(autouse=True, scope="function")
def unknown_variable_template_error(monkeypatch, request):
marker = request.keywords.get("ignore_unknown_variable_template_error", None)
if os.environ.get(INVALID_TEMPLATE_VARS_ENV, "false") == "true" and marker is None:
origin_resolve = base_template.FilterExpression.resolve

def stricter_resolve(self, context, ignore_failures=False):
if (
self.is_var
and self.var.lookups is not None
and self.var.lookups[0] not in context
# debug can be injected by django.template.context_processors.debug
# user can be injected by django.contrib.auth.context_processors.auth
# TODO(xfernandez): remove user from allow list (and remove the matching processor ?)
and self.var.lookups[0] not in ("debug", "user")
):
ignore_failures = False
return origin_resolve(self, context, ignore_failures)

monkeypatch.setattr(base_template.FilterExpression, "resolve", stricter_resolve)


@pytest.fixture(scope="session", autouse=True)
def make_unordered_queries_randomly_ordered():
"""
Expand Down
2 changes: 2 additions & 0 deletions tests/openid_connect/inclusion_connect/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,7 @@ def test_logout_with_incomplete_state(self):


class InclusionConnectmapChannelTest(MessagesTestMixin, InclusionConnectBaseTestCase):
@pytest.mark.ignore_unknown_variable_template_error
@respx.mock
def test_happy_path(self):
job_application = JobApplicationSentByPrescriberPoleEmploiFactory(
Expand Down Expand Up @@ -814,6 +815,7 @@ def test_happy_path(self):
response = self.client.get(response.url)
assert response.status_code == 200

@pytest.mark.ignore_unknown_variable_template_error
@respx.mock
def test_create_user(self):
# Application sent by a colleague from the same agency but not by the prescriber himself.
Expand Down
2 changes: 2 additions & 0 deletions tests/users/test_admin_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,15 @@ def test_transfer_without_change_permission(self, client):
response = client.get(transfer_url_2)
assert response.status_code == 403

@pytest.mark.ignore_unknown_variable_template_error
def test_transfer_no_data_to_transfer(self, admin_client):
user = JobSeekerFactory()
transfer_url = reverse("admin:transfer_user_data", kwargs={"from_user_pk": user.pk})
response = admin_client.get(transfer_url)
assertContains(response, self.IMPOSSIBLE_TRANSFER_TEXT)
assertNotContains(response, self.CHOOSE_TARGET_TEXT, html=True)

@pytest.mark.ignore_unknown_variable_template_error
@freeze_time("2023-08-31 12:34:56")
def test_transfer_data(self, admin_client, snapshot):
job_application = JobApplicationFactory(with_approval=True)
Expand Down
2 changes: 2 additions & 0 deletions tests/utils/test_redirect_legacy_views.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import pytest
from django.urls import reverse
from pytest_django.asserts import assertRedirects

from tests.companies.factories import CompanyFactory


@pytest.mark.ignore_unknown_variable_template_error
def test_redirect_siae_views(client):
company = CompanyFactory()

Expand Down
1 change: 1 addition & 0 deletions tests/utils/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1432,6 +1432,7 @@ def test_redact_email_adresse(email, expected):
assert redact_email_address(email) == expected


@pytest.mark.ignore_unknown_variable_template_error
def test_matomo_context_processor(client, settings, snapshot):
"""Test on a canically problematic view that we get the right Matomo properties.
Expand Down
13 changes: 13 additions & 0 deletions tests/www/apply/test_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
)


@pytest.mark.ignore_unknown_variable_template_error
@pytest.mark.usefixtures("unittest_compatibility")
class ProcessViewsTest(MessagesTestMixin, TestCase):
DIAGORIENTE_INVITE_TITLE = "Ce candidat n’a pas de CV ?"
Expand Down Expand Up @@ -2661,6 +2662,7 @@ def test_refuse_jobapplication_geiq_reasons(client, reason):
}


@pytest.mark.ignore_unknown_variable_template_error
def test_details_for_prescriber_not_can_have_prior_actions(client):
kind = random.choice(list(set(CompanyKind) - {CompanyKind.GEIQ}))
job_application = JobApplicationFactory(
Expand All @@ -2675,6 +2677,7 @@ def test_details_for_prescriber_not_can_have_prior_actions(client):
assertNotContains(response, PRIOR_ACTION_SECTION_TITLE)


@pytest.mark.ignore_unknown_variable_template_error
def test_details_for_prescriber_geiq_without_prior_actions(client):
job_application = JobApplicationFactory(
sent_by_authorized_prescriber_organisation=True,
Expand All @@ -2692,6 +2695,7 @@ def test_details_for_prescriber_geiq_without_prior_actions(client):
assertNotContains(response, PRIOR_ACTION_SECTION_TITLE)


@pytest.mark.ignore_unknown_variable_template_error
def test_details_for_prescriber_geiq_with_prior_actions(client):
job_application = JobApplicationFactory(
sent_by_authorized_prescriber_organisation=True,
Expand All @@ -2716,6 +2720,7 @@ def test_details_for_prescriber_geiq_with_prior_actions(client):
assertNotContains(response, delete_button)


@pytest.mark.ignore_unknown_variable_template_error
def test_details_for_jobseeker_geiq_with_prior_actions(client):
job_application = JobApplicationFactory(
sent_by_authorized_prescriber_organisation=True,
Expand All @@ -2741,6 +2746,7 @@ def test_details_for_jobseeker_geiq_with_prior_actions(client):
assertNotContains(response, delete_button)


@pytest.mark.ignore_unknown_variable_template_error
def test_details_sender_email_display_for_job_seeker(client):
SENDER_EMAIL_HIDDEN = "<small>Adresse e-mail</small><strong>Non communiquée</strong>"

Expand Down Expand Up @@ -2779,6 +2785,7 @@ def test_details_sender_email_display_for_job_seeker(client):
assertNotContains(response, SENDER_EMAIL_HIDDEN, html=True)


@pytest.mark.ignore_unknown_variable_template_error
def test_accept_button(client):
job_application = JobApplicationFactory(
state=job_applications_enums.JobApplicationState.PROCESSING,
Expand Down Expand Up @@ -2822,6 +2829,7 @@ def test_add_prior_action_new(client):
assert not job_application.prior_actions.exists()


@pytest.mark.ignore_unknown_variable_template_error
@freeze_time("2023-12-12 13:37:00", tz_offset=-1)
def test_add_prior_action_processing(client, snapshot):
job_application = JobApplicationFactory(
Expand Down Expand Up @@ -2943,6 +2951,7 @@ def test_delete_prior_action_accepted(client):
prior_action.refresh_from_db()


@pytest.mark.ignore_unknown_variable_template_error
@pytest.mark.parametrize("with_geiq_diagnosis", [True, False])
@freeze_time("2023-12-12 13:37:00", tz_offset=-1)
def test_delete_prior_action(client, snapshot, with_geiq_diagnosis):
Expand Down Expand Up @@ -3016,6 +3025,7 @@ def test_delete_prior_action(client, snapshot, with_geiq_diagnosis):
assertSoupEqual(parse_response_to_soup(response, selector="#main"), simulated_page)


@pytest.mark.ignore_unknown_variable_template_error
def test_htmx_add_prior_action_and_cancel(client):
job_application = JobApplicationFactory(
to_company__kind=CompanyKind.GEIQ, state=job_applications_enums.JobApplicationState.PROCESSING
Expand Down Expand Up @@ -3046,6 +3056,7 @@ def test_htmx_add_prior_action_and_cancel(client):
assertSoupEqual(parse_response_to_soup(response, selector="#main"), simulated_page)


@pytest.mark.ignore_unknown_variable_template_error
def test_htmx_modify_prior_action_and_cancel(client):
job_application = JobApplicationFactory(
to_company__kind=CompanyKind.GEIQ, state=job_applications_enums.JobApplicationState.PROCESSING
Expand Down Expand Up @@ -3075,6 +3086,7 @@ def test_htmx_modify_prior_action_and_cancel(client):
assertSoupEqual(parse_response_to_soup(response, selector="#main"), simulated_page)


@pytest.mark.ignore_unknown_variable_template_error
@pytest.mark.parametrize("with_geiq_diagnosis", [True, False])
def test_details_for_company_with_prior_action(client, with_geiq_diagnosis):
job_application = JobApplicationFactory(to_company__kind=CompanyKind.GEIQ)
Expand Down Expand Up @@ -3190,6 +3202,7 @@ def test_details_for_company_with_prior_action(client, with_geiq_diagnosis):
assertSoupEqual(parse_response_to_soup(response, selector="#main"), simulated_page)


@pytest.mark.ignore_unknown_variable_template_error
def test_precriber_details_with_older_valid_approval(client, faker):
# Ensure that the approval details are displayed for a prescriber
# when the job seeker has a valid approval created on an older approval
Expand Down
15 changes: 15 additions & 0 deletions tests/www/apply/test_submit.py
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ def test_apply_end_view_wo_phone_number_as_prescriber(self):
self.assertContains(response, expected_html, html=True)


@pytest.mark.ignore_unknown_variable_template_error
@pytest.mark.usefixtures("unittest_compatibility")
class ApplyAsAuthorizedPrescriberTest(TestCase):
def setUp(self):
Expand Down Expand Up @@ -1298,6 +1299,7 @@ def default_session_data(self):
"selected_jobs": [],
}

@pytest.mark.ignore_unknown_variable_template_error
def test_apply_as_prescriber_with_suspension_sanction(self):
company = CompanyWithMembershipAndJobsFactory(romes=("N1101", "N1105"))
Sanctions.objects.create(
Expand All @@ -1314,6 +1316,7 @@ def test_apply_as_prescriber_with_suspension_sanction(self):
response, expected_url=reverse("apply:check_nir_for_sender", kwargs={"company_pk": company.pk})
)

@pytest.mark.ignore_unknown_variable_template_error
@override_settings(API_BAN_BASE_URL="http://ban-api")
@mock.patch(
"itou.utils.apis.geocoding.get_geocoding_data",
Expand Down Expand Up @@ -1605,6 +1608,7 @@ def test_apply_as_prescriber_on_job_seeker_tunnel(self):
)


@pytest.mark.ignore_unknown_variable_template_error
class ApplyAsPrescriberNirExceptionsTest(TestCase):
"""
The following normal use cases are tested in tests above:
Expand Down Expand Up @@ -1795,6 +1799,7 @@ def test_apply_as_siae_with_suspension_sanction(self):
status_code=403,
)

@pytest.mark.ignore_unknown_variable_template_error
@override_settings(API_BAN_BASE_URL="http://ban-api")
@mock.patch(
"itou.utils.apis.geocoding.get_geocoding_data",
Expand Down Expand Up @@ -2058,6 +2063,7 @@ def test_apply_as_company(self, _mock):
response = self.client.get(next_url)
assert response.status_code == 200

@pytest.mark.ignore_unknown_variable_template_error
def test_cannot_create_job_seeker_with_pole_emploi_email(self):
# It's unlikely to happen
membership = CompanyMembershipFactory()
Expand Down Expand Up @@ -2127,6 +2133,7 @@ def test_hire_as_siae_with_suspension_sanction(self):
status_code=403,
)

@pytest.mark.ignore_unknown_variable_template_error
@override_settings(API_BAN_BASE_URL="http://ban-api")
@mock.patch(
"itou.utils.apis.geocoding.get_geocoding_data",
Expand Down Expand Up @@ -3425,6 +3432,7 @@ def test_job_seeker_with_profile_has_check_boxes_ticked_in_step3(self):
)


@pytest.mark.ignore_unknown_variable_template_error
def test_detect_existing_job_seeker(client):
company = CompanyWithMembershipAndJobsFactory(romes=("N1101", "N1105"))

Expand Down Expand Up @@ -3879,6 +3887,7 @@ def test_with_previous_as_employer(self):
self.assertContains(response, self.check_prev_applications_url)


@pytest.mark.ignore_unknown_variable_template_error
class FindJobSeekerForHireViewTestCase(TestCase):
@classmethod
def setUpTestData(cls):
Expand Down Expand Up @@ -4079,6 +4088,7 @@ def test_geiq(self):
self.assertContains(response, reverse("dashboard:index"))


@pytest.mark.ignore_unknown_variable_template_error
class CheckPreviousApplicationsForHireViewTestCase(TestCase):
@classmethod
def setUpTestData(cls):
Expand Down Expand Up @@ -4128,6 +4138,7 @@ def test_with_previous_as_geiq_staff(self):
self.assertRedirects(response, self._reverse("apply:geiq_eligibility_for_hire"))


@pytest.mark.ignore_unknown_variable_template_error
class EligibilityForHireTestCase(TestCase):
@classmethod
def setUpTestData(cls):
Expand Down Expand Up @@ -4189,6 +4200,7 @@ def test_not_geiq(self):
response = self.client.get(self._reverse("apply:geiq_eligibility_for_hire"))
assert response.status_code == 404

@pytest.mark.ignore_unknown_variable_template_error
def test_job_seeker_with_valid_diagnosis(self):
diagnosis = GEIQEligibilityDiagnosisFactory(job_seeker=self.job_seeker, with_geiq=True)
diagnosis.administrative_criteria.add(GEIQAdministrativeCriteria.objects.get(pk=19))
Expand Down Expand Up @@ -4239,6 +4251,7 @@ def test_job_seeker_without_valid_diagnosis(self):
assert GEIQEligibilityDiagnosis.objects.valid_diagnoses_for(self.job_seeker, self.company).exists()


@pytest.mark.ignore_unknown_variable_template_error
class HireConfirmationTestCase(TestCase):
@classmethod
def setUpTestData(cls):
Expand Down Expand Up @@ -4399,6 +4412,7 @@ def test_as_job_seeker(self):
self.assertNotContains(response, self.GEIQ_APPLY_PROCESS_INFO)
self.assertNotContains(response, self.GEIQ_DIRECT_HIRE_PROCESS_INFO)

@pytest.mark.ignore_unknown_variable_template_error
def test_as_prescriber(self):
self.client.force_login(PrescriberFactory())
response = self.client.get(reverse("apply:check_nir_for_sender", kwargs={"company_pk": self.company.pk}))
Expand All @@ -4408,6 +4422,7 @@ def test_as_prescriber(self):
self.assertNotContains(response, self.GEIQ_APPLY_PROCESS_INFO)
self.assertNotContains(response, self.GEIQ_DIRECT_HIRE_PROCESS_INFO)

@pytest.mark.ignore_unknown_variable_template_error
def test_as_employer(self):
self.client.force_login(self.company.members.first())
response = self.client.get(reverse("apply:check_nir_for_sender", kwargs={"company_pk": self.company.pk}))
Expand Down
5 changes: 5 additions & 0 deletions tests/www/apply/test_templates.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import pytest
from django.conf import Path
from django.template import Context, Template
from django.test.client import RequestFactory
Expand Down Expand Up @@ -115,6 +116,7 @@ def test_job_application_job_seeker_in_list():
# QPV / ZRR eligibility details


@pytest.mark.ignore_unknown_variable_template_error
def test_known_criteria_template_with_no_criterion():
tmpl = load_template("apply/includes/known_criteria.html")
rendered = tmpl.render(Context({"job_seeker": JobSeekerWithAddressFactory()}))
Expand All @@ -124,6 +126,7 @@ def test_known_criteria_template_with_no_criterion():
assert "est partiellement classée en ZRR" not in rendered


@pytest.mark.ignore_unknown_variable_template_error
def test_known_criteria_template_with_qpv_criterion():
tmpl = load_template("apply/includes/known_criteria.html")
job_seeker = JobSeekerWithAddressFactory(with_address_in_qpv=True)
Expand All @@ -135,6 +138,7 @@ def test_known_criteria_template_with_qpv_criterion():
assert escape(job_seeker.address_on_one_line) in rendered


@pytest.mark.ignore_unknown_variable_template_error
def test_known_criteria_template_with_zrr_criterion():
tmpl = load_template("apply/includes/known_criteria.html")
job_seeker = JobSeekerWithAddressFactory(with_city_in_zrr=True)
Expand All @@ -146,6 +150,7 @@ def test_known_criteria_template_with_zrr_criterion():
assert escape(job_seeker.city) in rendered


@pytest.mark.ignore_unknown_variable_template_error
def test_known_criteria_template_with_partial_zrr_criterion():
tmpl = load_template("apply/includes/known_criteria.html")
job_seeker = JobSeekerWithAddressFactory(with_city_partially_in_zrr=True)
Expand Down
1 change: 1 addition & 0 deletions tests/www/approvals_views/test_detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def test_detail_view_no_job_application(self, client):
assertContains(response, "Informations du salarié")
assertContains(response, "Candidatures de ce salarié")

@pytest.mark.ignore_unknown_variable_template_error
@freeze_time("2023-04-26")
def test_approval_status_includes(self, client, snapshot):
"""
Expand Down
2 changes: 2 additions & 0 deletions tests/www/approvals_views/test_list.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import datetime

import pytest
from dateutil.relativedelta import relativedelta
from django.urls import reverse
from django.utils import timezone
Expand Down Expand Up @@ -297,6 +298,7 @@ def test_approval_expiry_filters(self, client):
response = client.get(url)
assertContains(response, "0 résultat")

@pytest.mark.ignore_unknown_variable_template_error
def test_approval_expiry_filter_default(self, client):
company = CompanyFactory(with_membership=True)
# Make sure we have access to page 2
Expand Down
1 change: 1 addition & 0 deletions tests/www/approvals_views/test_prolongation.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from tests.utils.test import parse_response_to_soup


@pytest.mark.ignore_unknown_variable_template_error
@pytest.mark.usefixtures("unittest_compatibility")
@freeze_time("2023-08-23")
class ApprovalProlongationTest(TestCase):
Expand Down
Loading

0 comments on commit 37afc61

Please sign in to comment.