Skip to content

Commit

Permalink
job applications: hide job seekers' name from filter for orienteur
Browse files Browse the repository at this point in the history
  • Loading branch information
xavfernandez committed Oct 4, 2024
1 parent a588fba commit 8663e30
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 28 deletions.
28 changes: 24 additions & 4 deletions itou/www/apply/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from itou.users.models import JobSeekerProfile, User
from itou.utils import constants as global_constants
from itou.utils.emails import redact_email_address
from itou.utils.templatetags.str_filters import mask_unless
from itou.utils.types import InclusiveDateRange
from itou.utils.validators import validate_nir
from itou.utils.widgets import DuetDatePickerWidget
Expand Down Expand Up @@ -1038,14 +1039,14 @@ def __init__(self, job_applications_qs, *args, **kwargs):
self.job_applications_qs = job_applications_qs
super().__init__(*args, **kwargs)
senders = self.job_applications_qs.get_unique_fk_objects("sender")
self.fields["senders"].choices += self._get_choices_for(senders)
self.fields["senders"].choices += self._get_choices_for_sender(senders)
job_seekers = self.job_applications_qs.get_unique_fk_objects("job_seeker")
self.fields["job_seeker"].choices = self._get_choices_for(job_seekers)
self.fields["job_seeker"].choices = self._get_choices_for_job_seeker(job_seekers)
self.fields["criteria"].choices = self._get_choices_for_administrativecriteria()
self.fields["departments"].choices = self._get_choices_for_departments(job_seekers)
self.fields["selected_jobs"].choices = self._get_choices_for_jobs()

def _get_choices_for(self, users):
def _get_choices_for_sender(self, users):
users = [user for user in users if user.get_full_name()]
users = [(user.id, user.get_full_name().title()) for user in users]
return sorted(users, key=lambda user: user[1])
Expand Down Expand Up @@ -1131,6 +1132,11 @@ def filter(self, queryset):
queryset = queryset.filter(sender_company__id__in=sender_companies)
return queryset

def _get_choices_for_job_seeker(self, users):
users = [user for user in users if user.get_full_name()]
users = [(user.id, user.get_full_name().title()) for user in users]
return sorted(users, key=lambda user: user[1])

def get_sender_prescriber_organization_choices(self):
sender_orgs = self.job_applications_qs.get_unique_fk_objects("sender_prescriber_organization")
sender_orgs = [sender for sender in sender_orgs if sender.display_name]
Expand All @@ -1151,10 +1157,24 @@ class PrescriberFilterJobApplicationsForm(CompanyPrescriberFilterJobApplications

to_companies = forms.MultipleChoiceField(required=False, label="Organisation", widget=Select2MultipleWidget)

def __init__(self, job_applications_qs, *args, **kwargs):
def __init__(self, job_applications_qs, *args, request_user, **kwargs):
self.request_user = request_user
super().__init__(job_applications_qs, *args, **kwargs)
self.fields["to_companies"].choices += self.get_to_companies_choices()

def _get_choices_for_job_seeker(self, users):
users = [user for user in users if user.get_full_name()]
users = [
(
user.id,
mask_unless(
user.get_full_name().title(), predicate=self.request_user.can_view_personal_information(user)
),
)
for user in users
]
return sorted(users, key=lambda user: user[1])

def filter(self, queryset):
queryset = super().filter(queryset)
if to_companies := self.cleaned_data.get("to_companies"):
Expand Down
2 changes: 1 addition & 1 deletion itou/www/apply/views/list_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def list_prescriptions(request, template_name="apply/list_prescriptions.html"):
"""
job_applications = JobApplication.objects.prescriptions_of(request.user, request.current_organization)

filters_form = PrescriberFilterJobApplicationsForm(job_applications, request.GET)
filters_form = PrescriberFilterJobApplicationsForm(job_applications, request.GET, request_user=request.user)

# Add related data giving the criteria for adding the necessary annotations
job_applications = job_applications.with_list_related_data(criteria=filters_form.data.getlist("criteria", []))
Expand Down
43 changes: 23 additions & 20 deletions tests/www/apply/__snapshots__/test_list_prescriptions.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,29 @@
ORDER BY "job_applications_jobapplication"."job_seeker_id" ASC
''',
}),
dict({
'origin': list([
'User.is_prescriber_with_authorized_org[users/models.py]',
'User.can_edit_personal_information[users/models.py]',
'User.can_view_personal_information[users/models.py]',
'PrescriberFilterJobApplicationsForm.<listcomp>[www/apply/forms.py]',
'PrescriberFilterJobApplicationsForm._get_choices_for_job_seeker[www/apply/forms.py]',
'PrescriberFilterJobApplicationsForm.__init__[www/apply/forms.py]',
'PrescriberFilterJobApplicationsForm.__init__[www/apply/forms.py]',
'list_prescriptions[www/apply/views/list_views.py]',
]),
'sql': '''
SELECT %s AS "a"
FROM "prescribers_prescribermembership"
INNER JOIN "users_user" ON ("prescribers_prescribermembership"."user_id" = "users_user"."id")
INNER JOIN "prescribers_prescriberorganization" ON ("prescribers_prescribermembership"."organization_id" = "prescribers_prescriberorganization"."id")
WHERE ("prescribers_prescribermembership"."user_id" = %s
AND "prescribers_prescribermembership"."is_active"
AND "prescribers_prescriberorganization"."is_authorized"
AND "users_user"."is_active")
LIMIT 1
''',
}),
dict({
'origin': list([
'PrescriberFilterJobApplicationsForm._get_choices_for_administrativecriteria[www/apply/forms.py]',
Expand Down Expand Up @@ -921,26 +944,6 @@
ORDER BY "approvals_approval"."start_at" DESC
''',
}),
dict({
'origin': list([
'User.is_prescriber_with_authorized_org[users/models.py]',
'User.can_edit_personal_information[users/models.py]',
'User.can_view_personal_information[users/models.py]',
'_add_user_can_view_personal_information[www/apply/views/list_views.py]',
'list_prescriptions[www/apply/views/list_views.py]',
]),
'sql': '''
SELECT %s AS "a"
FROM "prescribers_prescribermembership"
INNER JOIN "users_user" ON ("prescribers_prescribermembership"."user_id" = "users_user"."id")
INNER JOIN "prescribers_prescriberorganization" ON ("prescribers_prescribermembership"."organization_id" = "prescribers_prescriberorganization"."id")
WHERE ("prescribers_prescribermembership"."user_id" = %s
AND "prescribers_prescribermembership"."is_active"
AND "prescribers_prescriberorganization"."is_authorized"
AND "users_user"."is_active")
LIMIT 1
''',
}),
dict({
'origin': list([
'_add_administrative_criteria[www/apply/views/list_views.py]',
Expand Down
46 changes: 43 additions & 3 deletions tests/www/apply/test_list_prescriptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from itou.utils.urls import add_url_params
from tests.job_applications.factories import JobApplicationFactory
from tests.prescribers.factories import (
PrescriberMembershipFactory,
PrescriberOrganizationWith2MembershipFactory,
)
from tests.users.factories import JobSeekerFactory, PrescriberFactory
Expand Down Expand Up @@ -98,8 +99,7 @@ def test_as_unauthorized_prescriber(client, snapshot):
"job_seekers_views:details", kwargs={"public_id": job_application.job_seeker.public_id}
)
assertContains(response, f'<a href="{job_seeker_detail_url}?back_url={list_url}" class="btn-link">S… U…</a>')
# Unfortunately, the job seeker's name is available in the filters
# assertNotContains(response, "Supersecretname")
assertNotContains(response, "Supersecretname")
another_job_seeker_detail_url = reverse(
"job_seekers_views:details", kwargs={"public_id": another_job_application.job_seeker.public_id}
)
Expand Down Expand Up @@ -143,7 +143,7 @@ def test_filtered_by_sender(client):

def test_filtered_by_job_seeker(client):
job_seeker = JobSeekerFactory()
prescriber = PrescriberFactory()
prescriber = PrescriberMembershipFactory(organization__authorized=True).user
JobApplicationFactory(sender=prescriber, job_seeker=job_seeker)
JobApplicationFactory.create_batch(2, sender=prescriber)
client.force_login(prescriber)
Expand All @@ -153,9 +153,49 @@ def test_filtered_by_job_seeker(client):
assert len(applications) == 1
assert applications[0].job_seeker.pk == job_seeker.pk

response = client.get(reverse("apply:list_prescriptions"))

filters_form = response.context["filters_form"]
assert len(filters_form.fields["job_seeker"].choices) == 3

applications = response.context["job_applications_page"].object_list
assert len(applications) == 3


def test_filtered_by_job_seeker_for_unauthorized_prescriber(client):
prescriber = PrescriberFactory()
a_b_job_seeker = JobApplicationFactory(
sender=prescriber, job_seeker__first_name="A_something", job_seeker__last_name="B_something"
).job_seeker
created_job_seeker = JobApplicationFactory(
sender=prescriber,
job_seeker__created_by=prescriber,
job_seeker__first_name="Zorro",
job_seeker__last_name="Martin",
).job_seeker
c_d_job_seeker = JobApplicationFactory(
sender=prescriber,
job_seeker__created_by=prescriber,
job_seeker__last_login=timezone.now(),
job_seeker__first_name="C_something",
job_seeker__last_name="D_something",
).job_seeker
client.force_login(prescriber)

response = client.get(reverse("apply:list_prescriptions"), {"job_seeker": created_job_seeker.pk})
applications = response.context["job_applications_page"].object_list
assert len(applications) == 1
assert applications[0].job_seeker.pk == created_job_seeker.pk

response = client.get(reverse("apply:list_prescriptions"))
applications = response.context["job_applications_page"].object_list
assert len(applications) == 3
filters_form = response.context["filters_form"]
assert filters_form.fields["job_seeker"].choices == [
(a_b_job_seeker.pk, "A… B…"),
(c_d_job_seeker.pk, "C… D…"),
(created_job_seeker.pk, "Zorro Martin"),
]


def test_filtered_by_company(client):
Expand Down

0 comments on commit 8663e30

Please sign in to comment.