Skip to content

Commit

Permalink
job_seekers_views: generalize the Start view to get/create job seeker
Browse files Browse the repository at this point in the history
The `Start` view is now plugged to both `UpdateJobSeeker*` views and
`CheckNIR*` views (which are the first step in the get orrr create job
seeker process).

All `job_seeker_session`s are now initialized with this `Start` view.
  • Loading branch information
EwenKorr committed Jan 10, 2025
1 parent e4f592e commit 1165cf3
Show file tree
Hide file tree
Showing 9 changed files with 493 additions and 227 deletions.
3 changes: 2 additions & 1 deletion itou/templates/apply/submit/application/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ <h1 class="mb-0 me-3 text-md-nowrap">{% include 'apply/includes/_submit_title.ht
<p>
Dernière actualisation du profil : {{ job_seeker.last_checked_at|date }} à {{ job_seeker.last_checked_at|time }}
{% if can_view_personal_information and not request.user.is_job_seeker %}
<a class="btn-link ms-3" href="{% url "job_seekers_views:update_job_seeker_start" %}{% querystring job_seeker=job_seeker.public_id company=siae.pk from_url=request.get_full_path|urlencode %}">Vérifier le profil</a>
<a class="btn-link ms-3"
href="{% url "job_seekers_views:start" %}{% querystring session_kind="job-seeker-update" job_seeker=job_seeker.public_id company=siae.pk from_url=request.get_full_path|urlencode %}">Vérifier le profil</a>
{% endif %}
{% if new_check_needed %}<i class="ri-information-line ri-xl text-warning"></i>{% endif %}
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ <h1 class="mb-0 me-3 text-md-nowrap">Informations personnelles de {{ job_seeker.
<h2>
Informations personnelles
<a class="btn btn-outline-primary float-end"
href="{% url "job_seekers_views:update_job_seeker_start" %}{% querystring job_seeker=job_seeker.public_id company=siae.pk from_url=request.get_full_path|urlencode %}">Mettre à jour</a>
href="{% url "job_seekers_views:start" %}{% querystring session_kind="job-seeker-update" job_seeker=job_seeker.public_id company=siae.pk from_url=request.get_full_path|urlencode %}">Mettre à jour</a>
</h2>

{% include "apply/includes/profile_infos.html" %}
Expand Down
37 changes: 15 additions & 22 deletions itou/www/apply/views/submit_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,18 +140,6 @@ def get_reset_url(self):
return reverse("companies_views:card", kwargs={"siae_id": self.company.pk})
return reverse("companies_views:job_description_card", kwargs={"job_description_id": job_description})

def init_job_seeker_session(self, request):
job_seeker_session = SessionNamespace.create_uuid_namespace(
request.session,
data={
"config": {
"reset_url": self.get_reset_url(),
},
"apply": {"company_pk": self.company.pk},
},
)
return job_seeker_session

def get_context_data(self, **kwargs):
return super().get_context_data(**kwargs) | {
"siae": self.company,
Expand Down Expand Up @@ -296,24 +284,29 @@ def get(self, request, *args, **kwargs):
reverse("apply:pending_authorization_for_sender", kwargs={"company_pk": self.company.pk})
)

# Init a job_seeker_session needed for job_seekers_views
job_seeker_session = self.init_job_seeker_session(request)
params = {
"session_kind": f"job-seeker-get-or-create-{tunnel}",
"company": self.company.pk,
"from_url": self.get_reset_url(),
"gps": "true" if self.is_gps else None,
}

return HttpResponseRedirect(
reverse(f"job_seekers_views:check_nir_for_{tunnel}", kwargs={"session_uuid": job_seeker_session.name})
+ ("?gps=true" if self.is_gps else "")
)
next_url = add_url_params(reverse("job_seekers_views:start"), params)
return HttpResponseRedirect(next_url)


class PendingAuthorizationForSender(ApplyStepForSenderBaseView):
template_name = "apply/submit_step_pending_authorization.html"

def setup(self, request, *args, **kwargs):
super().setup(request, *args, **kwargs)
self.job_seeker_session = self.init_job_seeker_session(request)
self.next_url = reverse(
"job_seekers_views:check_nir_for_sender", kwargs={"session_uuid": self.job_seeker_session.name}
)
params = {
"session_kind": "job-seeker-get-or-create-sender",
"company": self.company.pk,
"from_url": self.get_reset_url(),
}

self.next_url = add_url_params(reverse("job_seekers_views:start"), params)

def get_context_data(self, **kwargs):
return super().get_context_data(**kwargs) | {"next_url": self.next_url}
Expand Down
10 changes: 5 additions & 5 deletions itou/www/job_seekers_views/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
urlpatterns = [
path("details/<uuid:public_id>", views.JobSeekerDetailView.as_view(), name="details"),
path("list", views.JobSeekerListView.as_view(), name="list"),
path(
"start",
views.JobSeekerStartView.as_view(),
name="start",
),
# For sender
path("<uuid:session_uuid>/sender/check-nir", views.CheckNIRForSenderView.as_view(), name="check_nir_for_sender"),
path(
Expand Down Expand Up @@ -110,11 +115,6 @@
name="check_nir_for_job_seeker",
),
# Job seeker check/updates
path(
"update/start",
views.UpdateJobSeekerStartView.as_view(),
name="update_job_seeker_start",
),
path(
"update/<uuid:session_uuid>/1",
views.UpdateJobSeekerStep1View.as_view(),
Expand Down
82 changes: 58 additions & 24 deletions itou/www/job_seekers_views/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ def get_back_url(self):
return None

def get_reset_url(self):
return self.job_seeker_session.get("config", {}).get("reset_url") or reverse("dashboard:index")
return self.job_seeker_session.get("config", {}).get("from_url") or reverse("dashboard:index")

def get_context_data(self, **kwargs):
return super().get_context_data(**kwargs) | {
Expand Down Expand Up @@ -766,41 +766,75 @@ def get_context_data(self, **kwargs):
return super().get_context_data(**kwargs) | {"profile": self.profile, "progress": "80"}


class UpdateJobSeekerStartView(View):
class JobSeekerStartView(View):
def setup(self, request, *args, **kwargs):
super().setup(request, *args, **kwargs)

try:
job_seeker = get_object_or_404(
User.objects.filter(kind=UserKind.JOB_SEEKER), public_id=request.GET.get("job_seeker")
)
except ValidationError:
raise Http404("Aucun candidat n'a été trouvé")
self.session_kind = request.GET.get("session_kind")
self.is_gps = "gps" in request.GET and request.GET["gps"] == "true"
from_url = get_safe_url(request, "from_url")

try:
company = get_object_or_404(Company.objects.with_has_active_members(), pk=request.GET.get("company"))
except ValueError:
raise Http404("Aucune entreprise n'a été trouvée")
job_seeker = None
if job_seeker_public_id := request.GET.get("job_seeker"):
try:
job_seeker = get_object_or_404(
User.objects.filter(kind=UserKind.JOB_SEEKER), public_id=job_seeker_public_id
)
except ValidationError:
raise Http404("Aucun candidat n'a été trouvé")

from_url = get_safe_url(request, "from_url", fallback_url=reverse("dashboard:index"))
company = None
if company_pk := request.GET.get("company"):
try:
company = (
get_object_or_404(Company.objects.with_has_active_members(), pk=company_pk)
if not self.is_gps
else Company.unfiltered_objects.get(siret=companies_enums.POLE_EMPLOI_SIRET)
)
except ValueError:
raise Http404("Aucune entreprise n'a été trouvée")

if request.user.is_job_seeker or not request.user.can_view_personal_information(job_seeker):
# Data validation per session_kind
if (
not self.session_kind
or not from_url
or (self.session_kind == "job-seeker-update" and not job_seeker)
or (self.session_kind.startswith("job-seeker-get-or-create") and not company)
):
raise Http404

if (request.user.is_job_seeker and self.session_kind != "job-seeker-get-or-create-job_seeker") or (
job_seeker and not request.user.can_view_personal_information(job_seeker)
):
raise PermissionDenied("Votre utilisateur n'est pas autorisé à vérifier les informations de ce candidat")

self.job_seeker_session = SessionNamespace.create_uuid_namespace(
request.session,
data={
"config": {"from_url": from_url, "session_kind": "job-seeker-update"},
"job_seeker_pk": job_seeker.pk,
"apply": {"company_pk": company.pk},
apply_data = {"company_pk": company.pk} if company_pk else {}

data = {
"config": {
"from_url": from_url,
"session_kind": self.session_kind,
},
)
"apply": apply_data,
} | ({"job_seeker_pk": job_seeker.pk} if job_seeker else {})

self.job_seeker_session = SessionNamespace.create_uuid_namespace(request.session, data)

def get(self, request, *args, **kwargs):
if self.session_kind == "job-seeker-get-or-create-job_seeker":
view_name = "job_seekers_views:check_nir_for_job_seeker"
elif self.session_kind == "job-seeker-get-or-create-sender":
view_name = "job_seekers_views:check_nir_for_sender"
elif self.session_kind == "job-seeker-get-or-create-hire":
view_name = "job_seekers_views:check_nir_for_hire"
elif self.session_kind == "job-seeker-update":
view_name = "job_seekers_views:update_job_seeker_step_1"
else:
raise Http404

return HttpResponseRedirect(
reverse(
"job_seekers_views:update_job_seeker_step_1", kwargs={"session_uuid": self.job_seeker_session.name}
)
reverse(view_name, kwargs={"session_uuid": self.job_seeker_session.name})
+ ("?gps=true" if self.is_gps else "")
)


Expand Down
48 changes: 46 additions & 2 deletions tests/gps/test_create_beneficiary.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from itou.users.models import User
from itou.utils.mocks.address_format import mock_get_geocoding_data_by_ban_api_resolved
from itou.utils.models import InclusiveDateRange
from itou.utils.urls import add_url_params
from tests.cities.factories import create_city_geispolsheim, create_test_cities
from tests.companies.factories import CompanyWithMembershipAndJobsFactory
from tests.prescribers.factories import PrescriberOrganizationWithMembershipFactory
Expand Down Expand Up @@ -53,6 +54,16 @@ def test_create_job_seeker(_mock, client):
apply_start_url = reverse("apply:start", kwargs={"company_pk": singleton.pk}) + "?gps=true"

response = client.get(apply_start_url)
params = {
"session_kind": "job-seeker-get-or-create-sender",
"company": singleton.pk,
"from_url": reverse("companies_views:card", kwargs={"siae_id": singleton.pk}),
"gps": "true",
}
next_url = add_url_params(reverse("job_seekers_views:start"), params)
assert response.url == next_url

response = client.get(next_url)
[job_seeker_session_name] = [k for k in client.session.keys() if k not in KNOWN_SESSION_KEYS]
next_url = (
reverse("job_seekers_views:check_nir_for_sender", kwargs={"session_uuid": job_seeker_session_name})
Expand All @@ -79,7 +90,8 @@ def test_create_job_seeker(_mock, client):

expected_job_seeker_session = {
"config": {
"reset_url": reverse("companies_views:card", kwargs={"siae_id": singleton.pk}),
"from_url": reverse("companies_views:card", kwargs={"siae_id": singleton.pk}),
"session_kind": "job-seeker-get-or-create-sender",
},
"apply": {"company_pk": singleton.pk},
"profile": {
Expand Down Expand Up @@ -238,6 +250,16 @@ def test_gps_bypass(client):
apply_start_url = reverse("apply:start", kwargs={"company_pk": singleton.pk}) + "?gps=true"
response = client.get(apply_start_url)

params = {
"session_kind": "job-seeker-get-or-create-sender",
"company": singleton.pk,
"from_url": reverse("companies_views:card", kwargs={"siae_id": singleton.pk}),
"gps": "true",
}
next_url = add_url_params(reverse("job_seekers_views:start"), params)
assert response.url == next_url

response = client.get(next_url)
[job_seeker_session_name] = [k for k in client.session.keys() if k not in KNOWN_SESSION_KEYS]
next_url = (
reverse("job_seekers_views:check_nir_for_sender", kwargs={"session_uuid": job_seeker_session_name})
Expand All @@ -258,6 +280,17 @@ def test_gps_bypass(client):
apply_start_url = reverse("apply:start", kwargs={"company_pk": singleton.pk}) + "?gps=true"
response = client.get(apply_start_url)

params = {
"session_kind": "job-seeker-get-or-create-sender",
"company": singleton.pk,
"from_url": reverse("companies_views:card", kwargs={"siae_id": singleton.pk}),
"gps": "true",
}
next_url = add_url_params(reverse("job_seekers_views:start"), params)
assert response.url == next_url

response = client.get(next_url)

[job_seeker_session_name] = [k for k in client.session.keys() if k not in KNOWN_SESSION_KEYS]
next_url = (
reverse("job_seekers_views:check_nir_for_sender", kwargs={"session_uuid": job_seeker_session_name})
Expand Down Expand Up @@ -308,7 +341,8 @@ def test_existing_user_with_email(client):
)
expected_job_seeker_session = {
"config": {
"reset_url": reverse("companies_views:card", kwargs={"siae_id": singleton.pk}),
"from_url": reverse("companies_views:card", kwargs={"siae_id": singleton.pk}),
"session_kind": "job-seeker-get-or-create-sender",
},
"apply": {"company_pk": singleton.pk},
"profile": {
Expand Down Expand Up @@ -411,6 +445,16 @@ def test_creation_by_user_kind(client, UserFactory, factory_args, expected_acces
assert response.status_code == 403

response = client.get(create_beneficiary_url)
params = {
"session_kind": "job-seeker-get-or-create-sender",
"company": singleton.pk,
"from_url": reverse("companies_views:card", kwargs={"siae_id": singleton.pk}),
"gps": "true",
}
next_url = add_url_params(reverse("job_seekers_views:start"), params)
assert response.url == next_url

response = client.get(next_url)
[job_seeker_session_name] = [k for k in client.session.keys() if k not in KNOWN_SESSION_KEYS]
assert response.status_code == 302
assert (
Expand Down
Loading

0 comments on commit 1165cf3

Please sign in to comment.