From 69106b73a6711cba27593e1cc8ec37b1923a3a43 Mon Sep 17 00:00:00 2001 From: Xavier Fernandez Date: Fri, 13 Sep 2024 11:03:37 +0200 Subject: [PATCH] www.employees_views: limit access if an accepted application exists --- itou/www/employees_views/views.py | 17 ++++++++++- .../__snapshots__/test_detail.ambr | 30 +++++++++++++++++-- tests/www/employees_views/test_detail.py | 13 ++++---- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/itou/www/employees_views/views.py b/itou/www/employees_views/views.py index ca0201aba7..a29bfcdb1f 100644 --- a/itou/www/employees_views/views.py +++ b/itou/www/employees_views/views.py @@ -4,7 +4,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.core.exceptions import PermissionDenied -from django.db.models import Prefetch +from django.db.models import Exists, OuterRef, Prefetch from django.urls import reverse_lazy from django.utils import timezone from django.views.generic import DetailView @@ -43,6 +43,21 @@ def setup(self, request, *args, **kwargs): if not self.siae.is_subject_to_eligibility_rules: raise PermissionDenied + def get_queryset(self): + return ( + super() + .get_queryset() + .filter( + Exists( + JobApplication.objects.filter( + job_seeker_id=OuterRef("pk"), + to_company_id=self.siae.pk, + state=JobApplicationState.ACCEPTED, + ) + ) + ) + ) + def get_job_application(self, employee): return ( JobApplication.objects.filter( diff --git a/tests/www/employees_views/__snapshots__/test_detail.ambr b/tests/www/employees_views/__snapshots__/test_detail.ambr index bd0352d34a..116c803548 100644 --- a/tests/www/employees_views/__snapshots__/test_detail.ambr +++ b/tests/www/employees_views/__snapshots__/test_detail.ambr @@ -226,6 +226,13 @@ FROM "users_user" LEFT OUTER JOIN "users_jobseekerprofile" ON ("users_user"."id" = "users_jobseekerprofile"."user_id") WHERE ("users_user"."kind" = %s + AND EXISTS + (SELECT %s AS "a" + FROM "job_applications_jobapplication" U0 + WHERE (U0."job_seeker_id" = ("users_user"."id") + AND U0."state" = %s + AND U0."to_company_id" = %s) + LIMIT 1) AND "users_user"."public_id" = %s) LIMIT 21 ''', @@ -1245,7 +1252,8 @@ FROM "companies_jobdescription" INNER JOIN "job_applications_jobapplication_selected_jobs" ON ("companies_jobdescription"."id" = "job_applications_jobapplication_selected_jobs"."jobdescription_id") INNER JOIN "jobs_appellation" ON ("companies_jobdescription"."appellation_id" = "jobs_appellation"."code") - WHERE "job_applications_jobapplication_selected_jobs"."jobapplication_id" IN (%s) + WHERE "job_applications_jobapplication_selected_jobs"."jobapplication_id" IN (%s, + %s) ORDER BY "jobs_appellation"."name" ASC, "companies_jobdescription"."ui_rank" ASC ''', @@ -1796,6 +1804,13 @@ FROM "users_user" LEFT OUTER JOIN "users_jobseekerprofile" ON ("users_user"."id" = "users_jobseekerprofile"."user_id") WHERE ("users_user"."kind" = %s + AND EXISTS + (SELECT %s AS "a" + FROM "job_applications_jobapplication" U0 + WHERE (U0."job_seeker_id" = ("users_user"."id") + AND U0."state" = %s + AND U0."to_company_id" = %s) + LIMIT 1) AND "users_user"."public_id" = %s) LIMIT 21 ''', @@ -2741,7 +2756,8 @@ FROM "companies_jobdescription" INNER JOIN "job_applications_jobapplication_selected_jobs" ON ("companies_jobdescription"."id" = "job_applications_jobapplication_selected_jobs"."jobdescription_id") INNER JOIN "jobs_appellation" ON ("companies_jobdescription"."appellation_id" = "jobs_appellation"."code") - WHERE "job_applications_jobapplication_selected_jobs"."jobapplication_id" IN (%s) + WHERE "job_applications_jobapplication_selected_jobs"."jobapplication_id" IN (%s, + %s) ORDER BY "jobs_appellation"."name" ASC, "companies_jobdescription"."ui_rank" ASC ''', @@ -3482,6 +3498,13 @@ FROM "users_user" LEFT OUTER JOIN "users_jobseekerprofile" ON ("users_user"."id" = "users_jobseekerprofile"."user_id") WHERE ("users_user"."kind" = %s + AND EXISTS + (SELECT %s AS "a" + FROM "job_applications_jobapplication" U0 + WHERE (U0."job_seeker_id" = ("users_user"."id") + AND U0."state" = %s + AND U0."to_company_id" = %s) + LIMIT 1) AND "users_user"."public_id" = %s) LIMIT 21 ''', @@ -4196,7 +4219,8 @@ FROM "companies_jobdescription" INNER JOIN "job_applications_jobapplication_selected_jobs" ON ("companies_jobdescription"."id" = "job_applications_jobapplication_selected_jobs"."jobdescription_id") INNER JOIN "jobs_appellation" ON ("companies_jobdescription"."appellation_id" = "jobs_appellation"."code") - WHERE "job_applications_jobapplication_selected_jobs"."jobapplication_id" IN (%s) + WHERE "job_applications_jobapplication_selected_jobs"."jobapplication_id" IN (%s, + %s) ORDER BY "jobs_appellation"."name" ASC, "companies_jobdescription"."ui_rank" ASC ''', diff --git a/tests/www/employees_views/test_detail.py b/tests/www/employees_views/test_detail.py index 01af5b3cbf..27b76dca94 100644 --- a/tests/www/employees_views/test_detail.py +++ b/tests/www/employees_views/test_detail.py @@ -102,10 +102,7 @@ def test_detail_view_no_job_application(self, client): url = reverse("employees:detail", kwargs={"public_id": approval.user.public_id}) response = client.get(url) - # Check that the page didn't crash - assertContains(response, self.APPROVAL_NUMBER_LABEL) - assertContains(response, "Informations du salariƩ") - assertContains(response, "Candidatures de ce salariƩ") + assert response.status_code == 404 def test_detail_view_no_approval(self, client): company = CompanyFactory(with_membership=True, subject_to_eligibility=True) @@ -147,8 +144,14 @@ def test_approval_status_includes(self, client, snapshot): This template is used in approval views but also in many other places. Test its content only once. """ - job_application = JobApplicationFactory( + # This gives access to the employer + accepted_app = JobApplicationFactory( job_seeker__public_id="11111111-9999-2222-8888-555555555555", + state=JobApplicationState.ACCEPTED, + ) + job_application = JobApplicationFactory( + job_seeker=accepted_app.job_seeker, + to_company=accepted_app.to_company, state=JobApplicationState.PROCESSING, with_approval=True, approval__id=1,