From dae281cd561c13a4670c84614ae5899864d99c08 Mon Sep 17 00:00:00 2001 From: Xavier Fernandez Date: Thu, 3 Oct 2024 08:57:23 +0200 Subject: [PATCH 1/3] tests: switch list prescription test to assertSnapshotQueries --- .../test_list_prescriptions.ambr | 1180 +++++++++++++++++ tests/www/apply/test_list_prescriptions.py | 22 +- 2 files changed, 1183 insertions(+), 19 deletions(-) diff --git a/tests/www/apply/__snapshots__/test_list_prescriptions.ambr b/tests/www/apply/__snapshots__/test_list_prescriptions.ambr index 50cc25b7d7..7eaef0e2d8 100644 --- a/tests/www/apply/__snapshots__/test_list_prescriptions.ambr +++ b/tests/www/apply/__snapshots__/test_list_prescriptions.ambr @@ -1,4 +1,1184 @@ # serializer version: 1 +# name: test_as_unauthorized_prescriber[SQL queries for prescriptions list] + dict({ + 'num_queries': 22, + 'queries': list([ + dict({ + 'origin': list([ + 'SessionStore._get_session_from_db[/django/contrib/sessions/backends/db.py]', + ]), + 'sql': ''' + SELECT "django_session"."session_key", + "django_session"."session_data", + "django_session"."expire_date" + FROM "django_session" + WHERE ("django_session"."expire_date" > %s + AND "django_session"."session_key" = %s) + LIMIT 21 + ''', + }), + dict({ + 'origin': list([ + 'ItouCurrentOrganizationMiddleware.__call__[utils/perms/middleware.py]', + ]), + 'sql': ''' + SELECT "users_user"."id", + "users_user"."password", + "users_user"."last_login", + "users_user"."is_superuser", + "users_user"."username", + "users_user"."first_name", + "users_user"."last_name", + "users_user"."is_staff", + "users_user"."is_active", + "users_user"."date_joined", + "users_user"."address_line_1", + "users_user"."address_line_2", + "users_user"."post_code", + "users_user"."city", + "users_user"."department", + "users_user"."coords", + "users_user"."geocoding_score", + "users_user"."geocoding_updated_at", + "users_user"."ban_api_resolved_address", + "users_user"."insee_city_id", + "users_user"."title", + "users_user"."email", + "users_user"."phone", + "users_user"."kind", + "users_user"."identity_provider", + "users_user"."has_completed_welcoming_tour", + "users_user"."created_by_id", + "users_user"."external_data_source_history", + "users_user"."last_checked_at", + "users_user"."public_id", + "users_user"."address_filled_at", + "users_user"."first_login" + FROM "users_user" + WHERE "users_user"."id" = %s + LIMIT 21 + ''', + }), + dict({ + 'origin': list([ + 'ItouCurrentOrganizationMiddleware.__call__[utils/perms/middleware.py]', + ]), + 'sql': ''' + SELECT "prescribers_prescribermembership"."id", + "prescribers_prescribermembership"."user_id", + "prescribers_prescribermembership"."joined_at", + "prescribers_prescribermembership"."is_admin", + "prescribers_prescribermembership"."is_active", + "prescribers_prescribermembership"."created_at", + "prescribers_prescribermembership"."updated_at", + "prescribers_prescribermembership"."organization_id", + "prescribers_prescribermembership"."updated_by_id", + "prescribers_prescriberorganization"."id", + "prescribers_prescriberorganization"."address_line_1", + "prescribers_prescriberorganization"."address_line_2", + "prescribers_prescriberorganization"."post_code", + "prescribers_prescriberorganization"."city", + "prescribers_prescriberorganization"."department", + "prescribers_prescriberorganization"."coords", + "prescribers_prescriberorganization"."geocoding_score", + "prescribers_prescriberorganization"."geocoding_updated_at", + "prescribers_prescriberorganization"."ban_api_resolved_address", + "prescribers_prescriberorganization"."insee_city_id", + "prescribers_prescriberorganization"."name", + "prescribers_prescriberorganization"."created_at", + "prescribers_prescriberorganization"."updated_at", + "prescribers_prescriberorganization"."uid", + "prescribers_prescriberorganization"."active_members_email_reminder_last_sent_at", + "prescribers_prescriberorganization"."siret", + "prescribers_prescriberorganization"."is_head_office", + "prescribers_prescriberorganization"."kind", + "prescribers_prescriberorganization"."is_brsa", + "prescribers_prescriberorganization"."phone", + "prescribers_prescriberorganization"."email", + "prescribers_prescriberorganization"."website", + "prescribers_prescriberorganization"."description", + "prescribers_prescriberorganization"."is_authorized", + "prescribers_prescriberorganization"."code_safir_pole_emploi", + "prescribers_prescriberorganization"."created_by_id", + "prescribers_prescriberorganization"."authorization_status", + "prescribers_prescriberorganization"."authorization_updated_at", + "prescribers_prescriberorganization"."authorization_updated_by_id" + FROM "prescribers_prescribermembership" + INNER JOIN "prescribers_prescriberorganization" ON ("prescribers_prescribermembership"."organization_id" = "prescribers_prescriberorganization"."id") + WHERE ("prescribers_prescribermembership"."user_id" = %s + AND "prescribers_prescribermembership"."is_active") + ORDER BY "prescribers_prescribermembership"."created_at" ASC + ''', + }), + dict({ + 'origin': list([ + 'Atomic.__enter__[/django/db/transaction.py]', + ]), + 'sql': 'SAVEPOINT ""', + }), + dict({ + 'origin': list([ + 'JobApplicationQuerySet.get_unique_fk_objects[job_applications/models.py]', + 'PrescriberFilterJobApplicationsForm.__init__[www/apply/forms.py]', + 'PrescriberFilterJobApplicationsForm.__init__[www/apply/forms.py]', + 'list_prescriptions[www/apply/views/list_views.py]', + ]), + 'sql': ''' + SELECT DISTINCT ON ("job_applications_jobapplication"."sender_id") "job_applications_jobapplication"."id", + "job_applications_jobapplication"."job_seeker_id", + "job_applications_jobapplication"."eligibility_diagnosis_id", + "job_applications_jobapplication"."geiq_eligibility_diagnosis_id", + "job_applications_jobapplication"."create_employee_record", + "job_applications_jobapplication"."resume_link", + "job_applications_jobapplication"."sender_id", + "job_applications_jobapplication"."sender_kind", + "job_applications_jobapplication"."sender_company_id", + "job_applications_jobapplication"."sender_prescriber_organization_id", + "job_applications_jobapplication"."to_company_id", + "job_applications_jobapplication"."state", + "job_applications_jobapplication"."archived_at", + "job_applications_jobapplication"."archived_by_id", + "job_applications_jobapplication"."hired_job_id", + "job_applications_jobapplication"."message", + "job_applications_jobapplication"."answer", + "job_applications_jobapplication"."answer_to_prescriber", + "job_applications_jobapplication"."refusal_reason", + "job_applications_jobapplication"."refusal_reason_shared_with_job_seeker", + "job_applications_jobapplication"."hiring_start_at", + "job_applications_jobapplication"."hiring_end_at", + "job_applications_jobapplication"."hiring_without_approval", + "job_applications_jobapplication"."origin", + "job_applications_jobapplication"."approval_id", + "job_applications_jobapplication"."approval_delivery_mode", + "job_applications_jobapplication"."approval_number_sent_by_email", + "job_applications_jobapplication"."approval_number_sent_at", + "job_applications_jobapplication"."approval_manually_delivered_by_id", + "job_applications_jobapplication"."approval_manually_refused_by_id", + "job_applications_jobapplication"."approval_manually_refused_at", + "job_applications_jobapplication"."transferred_at", + "job_applications_jobapplication"."transferred_by_id", + "job_applications_jobapplication"."transferred_from_id", + "job_applications_jobapplication"."created_at", + "job_applications_jobapplication"."updated_at", + "job_applications_jobapplication"."processed_at", + "job_applications_jobapplication"."prehiring_guidance_days", + "job_applications_jobapplication"."contract_type", + "job_applications_jobapplication"."nb_hours_per_week", + "job_applications_jobapplication"."contract_type_details", + "job_applications_jobapplication"."qualification_type", + "job_applications_jobapplication"."qualification_level", + "job_applications_jobapplication"."planned_training_hours", + "job_applications_jobapplication"."inverted_vae_contract", + "job_applications_jobapplication"."diagoriente_invite_sent_at", + "users_user"."id", + "users_user"."password", + "users_user"."last_login", + "users_user"."is_superuser", + "users_user"."username", + "users_user"."first_name", + "users_user"."last_name", + "users_user"."is_staff", + "users_user"."is_active", + "users_user"."date_joined", + "users_user"."address_line_1", + "users_user"."address_line_2", + "users_user"."post_code", + "users_user"."city", + "users_user"."department", + "users_user"."coords", + "users_user"."geocoding_score", + "users_user"."geocoding_updated_at", + "users_user"."ban_api_resolved_address", + "users_user"."insee_city_id", + "users_user"."title", + "users_user"."email", + "users_user"."phone", + "users_user"."kind", + "users_user"."identity_provider", + "users_user"."has_completed_welcoming_tour", + "users_user"."created_by_id", + "users_user"."external_data_source_history", + "users_user"."last_checked_at", + "users_user"."public_id", + "users_user"."address_filled_at", + "users_user"."first_login" + FROM "job_applications_jobapplication" + INNER JOIN "users_user" ON ("job_applications_jobapplication"."sender_id" = "users_user"."id") + WHERE "job_applications_jobapplication"."sender_id" = %s + ORDER BY "job_applications_jobapplication"."sender_id" ASC + ''', + }), + dict({ + 'origin': list([ + 'JobApplicationQuerySet.get_unique_fk_objects[job_applications/models.py]', + 'PrescriberFilterJobApplicationsForm.__init__[www/apply/forms.py]', + 'PrescriberFilterJobApplicationsForm.__init__[www/apply/forms.py]', + 'list_prescriptions[www/apply/views/list_views.py]', + ]), + 'sql': ''' + SELECT DISTINCT ON ("job_applications_jobapplication"."job_seeker_id") "job_applications_jobapplication"."id", + "job_applications_jobapplication"."job_seeker_id", + "job_applications_jobapplication"."eligibility_diagnosis_id", + "job_applications_jobapplication"."geiq_eligibility_diagnosis_id", + "job_applications_jobapplication"."create_employee_record", + "job_applications_jobapplication"."resume_link", + "job_applications_jobapplication"."sender_id", + "job_applications_jobapplication"."sender_kind", + "job_applications_jobapplication"."sender_company_id", + "job_applications_jobapplication"."sender_prescriber_organization_id", + "job_applications_jobapplication"."to_company_id", + "job_applications_jobapplication"."state", + "job_applications_jobapplication"."archived_at", + "job_applications_jobapplication"."archived_by_id", + "job_applications_jobapplication"."hired_job_id", + "job_applications_jobapplication"."message", + "job_applications_jobapplication"."answer", + "job_applications_jobapplication"."answer_to_prescriber", + "job_applications_jobapplication"."refusal_reason", + "job_applications_jobapplication"."refusal_reason_shared_with_job_seeker", + "job_applications_jobapplication"."hiring_start_at", + "job_applications_jobapplication"."hiring_end_at", + "job_applications_jobapplication"."hiring_without_approval", + "job_applications_jobapplication"."origin", + "job_applications_jobapplication"."approval_id", + "job_applications_jobapplication"."approval_delivery_mode", + "job_applications_jobapplication"."approval_number_sent_by_email", + "job_applications_jobapplication"."approval_number_sent_at", + "job_applications_jobapplication"."approval_manually_delivered_by_id", + "job_applications_jobapplication"."approval_manually_refused_by_id", + "job_applications_jobapplication"."approval_manually_refused_at", + "job_applications_jobapplication"."transferred_at", + "job_applications_jobapplication"."transferred_by_id", + "job_applications_jobapplication"."transferred_from_id", + "job_applications_jobapplication"."created_at", + "job_applications_jobapplication"."updated_at", + "job_applications_jobapplication"."processed_at", + "job_applications_jobapplication"."prehiring_guidance_days", + "job_applications_jobapplication"."contract_type", + "job_applications_jobapplication"."nb_hours_per_week", + "job_applications_jobapplication"."contract_type_details", + "job_applications_jobapplication"."qualification_type", + "job_applications_jobapplication"."qualification_level", + "job_applications_jobapplication"."planned_training_hours", + "job_applications_jobapplication"."inverted_vae_contract", + "job_applications_jobapplication"."diagoriente_invite_sent_at", + T3."id", + T3."password", + T3."last_login", + T3."is_superuser", + T3."username", + T3."first_name", + T3."last_name", + T3."is_staff", + T3."is_active", + T3."date_joined", + T3."address_line_1", + T3."address_line_2", + T3."post_code", + T3."city", + T3."department", + T3."coords", + T3."geocoding_score", + T3."geocoding_updated_at", + T3."ban_api_resolved_address", + T3."insee_city_id", + T3."title", + T3."email", + T3."phone", + T3."kind", + T3."identity_provider", + T3."has_completed_welcoming_tour", + T3."created_by_id", + T3."external_data_source_history", + T3."last_checked_at", + T3."public_id", + T3."address_filled_at", + T3."first_login" + FROM "job_applications_jobapplication" + INNER JOIN "users_user" T3 ON ("job_applications_jobapplication"."job_seeker_id" = T3."id") + WHERE "job_applications_jobapplication"."sender_id" = %s + ORDER BY "job_applications_jobapplication"."job_seeker_id" ASC + ''', + }), + dict({ + 'origin': list([ + 'PrescriberFilterJobApplicationsForm._get_choices_for_administrativecriteria[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 "eligibility_administrativecriteria"."id", + "eligibility_administrativecriteria"."kind", + "eligibility_administrativecriteria"."level", + "eligibility_administrativecriteria"."name", + "eligibility_administrativecriteria"."desc", + "eligibility_administrativecriteria"."written_proof", + "eligibility_administrativecriteria"."written_proof_url", + "eligibility_administrativecriteria"."written_proof_validity", + "eligibility_administrativecriteria"."ui_rank", + "eligibility_administrativecriteria"."created_at", + "eligibility_administrativecriteria"."created_by_id" + FROM "eligibility_administrativecriteria" + ORDER BY "eligibility_administrativecriteria"."level" ASC, + "eligibility_administrativecriteria"."ui_rank" ASC + ''', + }), + dict({ + 'origin': list([ + 'PrescriberFilterJobApplicationsForm._get_choices_for_jobs[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 "job_applications_jobapplication"."id", + "job_applications_jobapplication"."job_seeker_id", + "job_applications_jobapplication"."eligibility_diagnosis_id", + "job_applications_jobapplication"."geiq_eligibility_diagnosis_id", + "job_applications_jobapplication"."create_employee_record", + "job_applications_jobapplication"."resume_link", + "job_applications_jobapplication"."sender_id", + "job_applications_jobapplication"."sender_kind", + "job_applications_jobapplication"."sender_company_id", + "job_applications_jobapplication"."sender_prescriber_organization_id", + "job_applications_jobapplication"."to_company_id", + "job_applications_jobapplication"."state", + "job_applications_jobapplication"."archived_at", + "job_applications_jobapplication"."archived_by_id", + "job_applications_jobapplication"."hired_job_id", + "job_applications_jobapplication"."message", + "job_applications_jobapplication"."answer", + "job_applications_jobapplication"."answer_to_prescriber", + "job_applications_jobapplication"."refusal_reason", + "job_applications_jobapplication"."refusal_reason_shared_with_job_seeker", + "job_applications_jobapplication"."hiring_start_at", + "job_applications_jobapplication"."hiring_end_at", + "job_applications_jobapplication"."hiring_without_approval", + "job_applications_jobapplication"."origin", + "job_applications_jobapplication"."approval_id", + "job_applications_jobapplication"."approval_delivery_mode", + "job_applications_jobapplication"."approval_number_sent_by_email", + "job_applications_jobapplication"."approval_number_sent_at", + "job_applications_jobapplication"."approval_manually_delivered_by_id", + "job_applications_jobapplication"."approval_manually_refused_by_id", + "job_applications_jobapplication"."approval_manually_refused_at", + "job_applications_jobapplication"."transferred_at", + "job_applications_jobapplication"."transferred_by_id", + "job_applications_jobapplication"."transferred_from_id", + "job_applications_jobapplication"."created_at", + "job_applications_jobapplication"."updated_at", + "job_applications_jobapplication"."processed_at", + "job_applications_jobapplication"."prehiring_guidance_days", + "job_applications_jobapplication"."contract_type", + "job_applications_jobapplication"."nb_hours_per_week", + "job_applications_jobapplication"."contract_type_details", + "job_applications_jobapplication"."qualification_type", + "job_applications_jobapplication"."qualification_level", + "job_applications_jobapplication"."planned_training_hours", + "job_applications_jobapplication"."inverted_vae_contract", + "job_applications_jobapplication"."diagoriente_invite_sent_at" + FROM "job_applications_jobapplication" + WHERE "job_applications_jobapplication"."sender_id" = %s + ORDER BY "job_applications_jobapplication"."created_at" DESC + ''', + }), + dict({ + 'origin': list([ + 'PrescriberFilterJobApplicationsForm._get_choices_for_jobs[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 ("job_applications_jobapplication_selected_jobs"."jobapplication_id") AS "_prefetch_related_val_jobapplication_id", + "companies_jobdescription"."id", + "companies_jobdescription"."appellation_id", + "companies_jobdescription"."company_id", + "companies_jobdescription"."created_at", + "companies_jobdescription"."updated_at", + "companies_jobdescription"."is_active", + "companies_jobdescription"."custom_name", + "companies_jobdescription"."description", + "companies_jobdescription"."ui_rank", + "companies_jobdescription"."contract_type", + "companies_jobdescription"."other_contract_type", + "companies_jobdescription"."contract_nature", + "companies_jobdescription"."location_id", + "companies_jobdescription"."hours_per_week", + "companies_jobdescription"."open_positions", + "companies_jobdescription"."profile_description", + "companies_jobdescription"."is_resume_mandatory", + "companies_jobdescription"."is_qpv_mandatory", + "companies_jobdescription"."market_context_description", + "companies_jobdescription"."source_id", + "companies_jobdescription"."source_kind", + "companies_jobdescription"."source_url", + "companies_jobdescription"."field_history", + "companies_jobdescription"."creation_source" + 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) + ORDER BY "jobs_appellation"."name" ASC, + "companies_jobdescription"."ui_rank" ASC + ''', + }), + dict({ + 'origin': list([ + 'JobApplicationQuerySet.get_unique_fk_objects[job_applications/models.py]', + 'PrescriberFilterJobApplicationsForm.get_to_companies_choices[www/apply/forms.py]', + 'PrescriberFilterJobApplicationsForm.__init__[www/apply/forms.py]', + 'list_prescriptions[www/apply/views/list_views.py]', + ]), + 'sql': ''' + SELECT DISTINCT ON ("job_applications_jobapplication"."to_company_id") "job_applications_jobapplication"."id", + "job_applications_jobapplication"."job_seeker_id", + "job_applications_jobapplication"."eligibility_diagnosis_id", + "job_applications_jobapplication"."geiq_eligibility_diagnosis_id", + "job_applications_jobapplication"."create_employee_record", + "job_applications_jobapplication"."resume_link", + "job_applications_jobapplication"."sender_id", + "job_applications_jobapplication"."sender_kind", + "job_applications_jobapplication"."sender_company_id", + "job_applications_jobapplication"."sender_prescriber_organization_id", + "job_applications_jobapplication"."to_company_id", + "job_applications_jobapplication"."state", + "job_applications_jobapplication"."archived_at", + "job_applications_jobapplication"."archived_by_id", + "job_applications_jobapplication"."hired_job_id", + "job_applications_jobapplication"."message", + "job_applications_jobapplication"."answer", + "job_applications_jobapplication"."answer_to_prescriber", + "job_applications_jobapplication"."refusal_reason", + "job_applications_jobapplication"."refusal_reason_shared_with_job_seeker", + "job_applications_jobapplication"."hiring_start_at", + "job_applications_jobapplication"."hiring_end_at", + "job_applications_jobapplication"."hiring_without_approval", + "job_applications_jobapplication"."origin", + "job_applications_jobapplication"."approval_id", + "job_applications_jobapplication"."approval_delivery_mode", + "job_applications_jobapplication"."approval_number_sent_by_email", + "job_applications_jobapplication"."approval_number_sent_at", + "job_applications_jobapplication"."approval_manually_delivered_by_id", + "job_applications_jobapplication"."approval_manually_refused_by_id", + "job_applications_jobapplication"."approval_manually_refused_at", + "job_applications_jobapplication"."transferred_at", + "job_applications_jobapplication"."transferred_by_id", + "job_applications_jobapplication"."transferred_from_id", + "job_applications_jobapplication"."created_at", + "job_applications_jobapplication"."updated_at", + "job_applications_jobapplication"."processed_at", + "job_applications_jobapplication"."prehiring_guidance_days", + "job_applications_jobapplication"."contract_type", + "job_applications_jobapplication"."nb_hours_per_week", + "job_applications_jobapplication"."contract_type_details", + "job_applications_jobapplication"."qualification_type", + "job_applications_jobapplication"."qualification_level", + "job_applications_jobapplication"."planned_training_hours", + "job_applications_jobapplication"."inverted_vae_contract", + "job_applications_jobapplication"."diagoriente_invite_sent_at", + "companies_company"."id", + "companies_company"."address_line_1", + "companies_company"."address_line_2", + "companies_company"."post_code", + "companies_company"."city", + "companies_company"."department", + "companies_company"."coords", + "companies_company"."geocoding_score", + "companies_company"."geocoding_updated_at", + "companies_company"."ban_api_resolved_address", + "companies_company"."insee_city_id", + "companies_company"."name", + "companies_company"."created_at", + "companies_company"."updated_at", + "companies_company"."uid", + "companies_company"."active_members_email_reminder_last_sent_at", + "companies_company"."siret", + "companies_company"."naf", + "companies_company"."kind", + "companies_company"."brand", + "companies_company"."phone", + "companies_company"."email", + "companies_company"."auth_email", + "companies_company"."website", + "companies_company"."description", + "companies_company"."provided_support", + "companies_company"."source", + "companies_company"."created_by_id", + "companies_company"."block_job_applications", + "companies_company"."job_applications_blocked_at", + "companies_company"."convention_id", + "companies_company"."job_app_score", + "companies_company"."rdv_solidarites_id" + FROM "job_applications_jobapplication" + INNER JOIN "companies_company" ON ("job_applications_jobapplication"."to_company_id" = "companies_company"."id") + WHERE "job_applications_jobapplication"."sender_id" = %s + ORDER BY "job_applications_jobapplication"."to_company_id" ASC + ''', + }), + dict({ + 'origin': list([ + 'pager[utils/pagination.py]', + 'list_prescriptions[www/apply/views/list_views.py]', + ]), + 'sql': ''' + SELECT COUNT(*) + FROM + (SELECT COALESCE("job_applications_jobapplication"."eligibility_diagnosis_id", + (SELECT U0."id" + FROM "eligibility_eligibilitydiagnosis" U0 + WHERE (U0."expires_at" > %s + AND (U0."author_kind" = %s + OR U0."author_siae_id" = ("job_applications_jobapplication"."to_company_id")) + AND U0."job_seeker_id" = ("job_applications_jobapplication"."job_seeker_id")) + ORDER BY U0."created_at" DESC + LIMIT 1), NULL) AS "jobseeker_eligibility_diagnosis", + GREATEST("job_applications_jobapplication"."created_at", MAX("job_applications_jobapplicationtransitionlog"."timestamp")) AS "last_change" + FROM "job_applications_jobapplication" + LEFT OUTER JOIN "job_applications_jobapplicationtransitionlog" ON ("job_applications_jobapplication"."id" = "job_applications_jobapplicationtransitionlog"."job_application_id") + WHERE ("job_applications_jobapplication"."sender_id" = %s + AND "job_applications_jobapplication"."archived_at" IS NULL) + GROUP BY "job_applications_jobapplication"."id", + 1) subquery + ''', + }), + dict({ + 'origin': list([ + '_add_pending_for_weeks[www/apply/views/list_views.py]', + 'list_prescriptions[www/apply/views/list_views.py]', + ]), + 'sql': ''' + SELECT "job_applications_jobapplication"."id", + "job_applications_jobapplication"."job_seeker_id", + "job_applications_jobapplication"."eligibility_diagnosis_id", + "job_applications_jobapplication"."geiq_eligibility_diagnosis_id", + "job_applications_jobapplication"."create_employee_record", + "job_applications_jobapplication"."resume_link", + "job_applications_jobapplication"."sender_id", + "job_applications_jobapplication"."sender_kind", + "job_applications_jobapplication"."sender_company_id", + "job_applications_jobapplication"."sender_prescriber_organization_id", + "job_applications_jobapplication"."to_company_id", + "job_applications_jobapplication"."state", + "job_applications_jobapplication"."archived_at", + "job_applications_jobapplication"."archived_by_id", + "job_applications_jobapplication"."hired_job_id", + "job_applications_jobapplication"."message", + "job_applications_jobapplication"."answer", + "job_applications_jobapplication"."answer_to_prescriber", + "job_applications_jobapplication"."refusal_reason", + "job_applications_jobapplication"."refusal_reason_shared_with_job_seeker", + "job_applications_jobapplication"."hiring_start_at", + "job_applications_jobapplication"."hiring_end_at", + "job_applications_jobapplication"."hiring_without_approval", + "job_applications_jobapplication"."origin", + "job_applications_jobapplication"."approval_id", + "job_applications_jobapplication"."approval_delivery_mode", + "job_applications_jobapplication"."approval_number_sent_by_email", + "job_applications_jobapplication"."approval_number_sent_at", + "job_applications_jobapplication"."approval_manually_delivered_by_id", + "job_applications_jobapplication"."approval_manually_refused_by_id", + "job_applications_jobapplication"."approval_manually_refused_at", + "job_applications_jobapplication"."transferred_at", + "job_applications_jobapplication"."transferred_by_id", + "job_applications_jobapplication"."transferred_from_id", + "job_applications_jobapplication"."created_at", + "job_applications_jobapplication"."updated_at", + "job_applications_jobapplication"."processed_at", + "job_applications_jobapplication"."prehiring_guidance_days", + "job_applications_jobapplication"."contract_type", + "job_applications_jobapplication"."nb_hours_per_week", + "job_applications_jobapplication"."contract_type_details", + "job_applications_jobapplication"."qualification_type", + "job_applications_jobapplication"."qualification_level", + "job_applications_jobapplication"."planned_training_hours", + "job_applications_jobapplication"."inverted_vae_contract", + "job_applications_jobapplication"."diagoriente_invite_sent_at", + GREATEST("job_applications_jobapplication"."created_at", MAX("job_applications_jobapplicationtransitionlog"."timestamp")) AS "last_change", + COALESCE("job_applications_jobapplication"."eligibility_diagnosis_id", + (SELECT U0."id" + FROM "eligibility_eligibilitydiagnosis" U0 + WHERE (U0."expires_at" > %s + AND (U0."author_kind" = %s + OR U0."author_siae_id" = ("job_applications_jobapplication"."to_company_id")) + AND U0."job_seeker_id" = ("job_applications_jobapplication"."job_seeker_id")) + ORDER BY U0."created_at" DESC + LIMIT 1), NULL) AS "jobseeker_eligibility_diagnosis", + T6."id", + T6."password", + T6."last_login", + T6."is_superuser", + T6."username", + T6."first_name", + T6."last_name", + T6."is_staff", + T6."is_active", + T6."date_joined", + T6."address_line_1", + T6."address_line_2", + T6."post_code", + T6."city", + T6."department", + T6."coords", + T6."geocoding_score", + T6."geocoding_updated_at", + T6."ban_api_resolved_address", + T6."insee_city_id", + T6."title", + T6."email", + T6."phone", + T6."kind", + T6."identity_provider", + T6."has_completed_welcoming_tour", + T6."created_by_id", + T6."external_data_source_history", + T6."last_checked_at", + T6."public_id", + T6."address_filled_at", + T6."first_login", + "users_jobseekerprofile"."user_id", + "users_jobseekerprofile"."birthdate", + "users_jobseekerprofile"."birth_place_id", + "users_jobseekerprofile"."birth_country_id", + "users_jobseekerprofile"."nir", + "users_jobseekerprofile"."lack_of_nir_reason", + "users_jobseekerprofile"."pole_emploi_id", + "users_jobseekerprofile"."lack_of_pole_emploi_id_reason", + "users_jobseekerprofile"."asp_uid", + "users_jobseekerprofile"."education_level", + "users_jobseekerprofile"."resourceless", + "users_jobseekerprofile"."rqth_employee", + "users_jobseekerprofile"."oeth_employee", + "users_jobseekerprofile"."pole_emploi_since", + "users_jobseekerprofile"."unemployed_since", + "users_jobseekerprofile"."has_rsa_allocation", + "users_jobseekerprofile"."rsa_allocation_since", + "users_jobseekerprofile"."ass_allocation_since", + "users_jobseekerprofile"."aah_allocation_since", + "users_jobseekerprofile"."ata_allocation_since", + "users_jobseekerprofile"."hexa_lane_number", + "users_jobseekerprofile"."hexa_std_extension", + "users_jobseekerprofile"."hexa_non_std_extension", + "users_jobseekerprofile"."hexa_lane_type", + "users_jobseekerprofile"."hexa_lane_name", + "users_jobseekerprofile"."hexa_additional_address", + "users_jobseekerprofile"."hexa_post_code", + "users_jobseekerprofile"."hexa_commune_id", + "users_jobseekerprofile"."pe_obfuscated_nir", + "users_jobseekerprofile"."pe_last_certification_attempt_at", + "users_user"."id", + "users_user"."password", + "users_user"."last_login", + "users_user"."is_superuser", + "users_user"."username", + "users_user"."first_name", + "users_user"."last_name", + "users_user"."is_staff", + "users_user"."is_active", + "users_user"."date_joined", + "users_user"."address_line_1", + "users_user"."address_line_2", + "users_user"."post_code", + "users_user"."city", + "users_user"."department", + "users_user"."coords", + "users_user"."geocoding_score", + "users_user"."geocoding_updated_at", + "users_user"."ban_api_resolved_address", + "users_user"."insee_city_id", + "users_user"."title", + "users_user"."email", + "users_user"."phone", + "users_user"."kind", + "users_user"."identity_provider", + "users_user"."has_completed_welcoming_tour", + "users_user"."created_by_id", + "users_user"."external_data_source_history", + "users_user"."last_checked_at", + "users_user"."public_id", + "users_user"."address_filled_at", + "users_user"."first_login", + T8."id", + T8."address_line_1", + T8."address_line_2", + T8."post_code", + T8."city", + T8."department", + T8."coords", + T8."geocoding_score", + T8."geocoding_updated_at", + T8."ban_api_resolved_address", + T8."insee_city_id", + T8."name", + T8."created_at", + T8."updated_at", + T8."uid", + T8."active_members_email_reminder_last_sent_at", + T8."siret", + T8."naf", + T8."kind", + T8."brand", + T8."phone", + T8."email", + T8."auth_email", + T8."website", + T8."description", + T8."provided_support", + T8."source", + T8."created_by_id", + T8."block_job_applications", + T8."job_applications_blocked_at", + T8."convention_id", + T8."job_app_score", + T8."rdv_solidarites_id", + "prescribers_prescriberorganization"."id", + "prescribers_prescriberorganization"."address_line_1", + "prescribers_prescriberorganization"."address_line_2", + "prescribers_prescriberorganization"."post_code", + "prescribers_prescriberorganization"."city", + "prescribers_prescriberorganization"."department", + "prescribers_prescriberorganization"."coords", + "prescribers_prescriberorganization"."geocoding_score", + "prescribers_prescriberorganization"."geocoding_updated_at", + "prescribers_prescriberorganization"."ban_api_resolved_address", + "prescribers_prescriberorganization"."insee_city_id", + "prescribers_prescriberorganization"."name", + "prescribers_prescriberorganization"."created_at", + "prescribers_prescriberorganization"."updated_at", + "prescribers_prescriberorganization"."uid", + "prescribers_prescriberorganization"."active_members_email_reminder_last_sent_at", + "prescribers_prescriberorganization"."siret", + "prescribers_prescriberorganization"."is_head_office", + "prescribers_prescriberorganization"."kind", + "prescribers_prescriberorganization"."is_brsa", + "prescribers_prescriberorganization"."phone", + "prescribers_prescriberorganization"."email", + "prescribers_prescriberorganization"."website", + "prescribers_prescriberorganization"."description", + "prescribers_prescriberorganization"."is_authorized", + "prescribers_prescriberorganization"."code_safir_pole_emploi", + "prescribers_prescriberorganization"."created_by_id", + "prescribers_prescriberorganization"."authorization_status", + "prescribers_prescriberorganization"."authorization_updated_at", + "prescribers_prescriberorganization"."authorization_updated_by_id", + "companies_company"."id", + "companies_company"."address_line_1", + "companies_company"."address_line_2", + "companies_company"."post_code", + "companies_company"."city", + "companies_company"."department", + "companies_company"."coords", + "companies_company"."geocoding_score", + "companies_company"."geocoding_updated_at", + "companies_company"."ban_api_resolved_address", + "companies_company"."insee_city_id", + "companies_company"."name", + "companies_company"."created_at", + "companies_company"."updated_at", + "companies_company"."uid", + "companies_company"."active_members_email_reminder_last_sent_at", + "companies_company"."siret", + "companies_company"."naf", + "companies_company"."kind", + "companies_company"."brand", + "companies_company"."phone", + "companies_company"."email", + "companies_company"."auth_email", + "companies_company"."website", + "companies_company"."description", + "companies_company"."provided_support", + "companies_company"."source", + "companies_company"."created_by_id", + "companies_company"."block_job_applications", + "companies_company"."job_applications_blocked_at", + "companies_company"."convention_id", + "companies_company"."job_app_score", + "companies_company"."rdv_solidarites_id", + "companies_siaeconvention"."id", + "companies_siaeconvention"."kind", + "companies_siaeconvention"."siret_signature", + "companies_siaeconvention"."is_active", + "companies_siaeconvention"."deactivated_at", + "companies_siaeconvention"."reactivated_by_id", + "companies_siaeconvention"."reactivated_at", + "companies_siaeconvention"."asp_id", + "companies_siaeconvention"."created_at", + "companies_siaeconvention"."updated_at", + "approvals_approval"."id", + "approvals_approval"."start_at", + "approvals_approval"."end_at", + "approvals_approval"."created_at", + "approvals_approval"."number", + "approvals_approval"."pe_notification_status", + "approvals_approval"."pe_notification_time", + "approvals_approval"."pe_notification_endpoint", + "approvals_approval"."pe_notification_exit_code", + "approvals_approval"."user_id", + "approvals_approval"."created_by_id", + "approvals_approval"."origin", + "approvals_approval"."eligibility_diagnosis_id", + "approvals_approval"."updated_at", + "approvals_approval"."origin_siae_siret", + "approvals_approval"."origin_siae_kind", + "approvals_approval"."origin_sender_kind", + "approvals_approval"."origin_prescriber_organization_kind" + FROM "job_applications_jobapplication" + INNER JOIN "users_user" ON ("job_applications_jobapplication"."sender_id" = "users_user"."id") + LEFT OUTER JOIN "job_applications_jobapplicationtransitionlog" ON ("job_applications_jobapplication"."id" = "job_applications_jobapplicationtransitionlog"."job_application_id") + INNER JOIN "companies_company" ON ("job_applications_jobapplication"."to_company_id" = "companies_company"."id") + INNER JOIN "users_user" T6 ON ("job_applications_jobapplication"."job_seeker_id" = T6."id") + LEFT OUTER JOIN "users_jobseekerprofile" ON (T6."id" = "users_jobseekerprofile"."user_id") + LEFT OUTER JOIN "companies_company" T8 ON ("job_applications_jobapplication"."sender_company_id" = T8."id") + LEFT OUTER JOIN "prescribers_prescriberorganization" ON ("job_applications_jobapplication"."sender_prescriber_organization_id" = "prescribers_prescriberorganization"."id") + LEFT OUTER JOIN "companies_siaeconvention" ON ("companies_company"."convention_id" = "companies_siaeconvention"."id") + LEFT OUTER JOIN "approvals_approval" ON ("job_applications_jobapplication"."approval_id" = "approvals_approval"."id") + WHERE ("job_applications_jobapplication"."sender_id" = %s + AND "job_applications_jobapplication"."archived_at" IS NULL) + GROUP BY "job_applications_jobapplication"."id", + 48, + T6."id", + "users_jobseekerprofile"."user_id", + "users_user"."id", + T8."id", + "prescribers_prescriberorganization"."id", + "companies_company"."id", + "companies_siaeconvention"."id", + "approvals_approval"."id" + ORDER BY "job_applications_jobapplication"."created_at" DESC, + "job_applications_jobapplication"."id" ASC + LIMIT 1 + ''', + }), + dict({ + 'origin': list([ + '_add_pending_for_weeks[www/apply/views/list_views.py]', + 'list_prescriptions[www/apply/views/list_views.py]', + ]), + 'sql': ''' + SELECT ("job_applications_jobapplication_selected_jobs"."jobapplication_id") AS "_prefetch_related_val_jobapplication_id", + "companies_jobdescription"."id", + "companies_jobdescription"."appellation_id", + "companies_jobdescription"."company_id", + "companies_jobdescription"."created_at", + "companies_jobdescription"."updated_at", + "companies_jobdescription"."is_active", + "companies_jobdescription"."custom_name", + "companies_jobdescription"."description", + "companies_jobdescription"."ui_rank", + "companies_jobdescription"."contract_type", + "companies_jobdescription"."other_contract_type", + "companies_jobdescription"."contract_nature", + "companies_jobdescription"."location_id", + "companies_jobdescription"."hours_per_week", + "companies_jobdescription"."open_positions", + "companies_jobdescription"."profile_description", + "companies_jobdescription"."is_resume_mandatory", + "companies_jobdescription"."is_qpv_mandatory", + "companies_jobdescription"."market_context_description", + "companies_jobdescription"."source_id", + "companies_jobdescription"."source_kind", + "companies_jobdescription"."source_url", + "companies_jobdescription"."field_history", + "companies_jobdescription"."creation_source" + 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) + ORDER BY "jobs_appellation"."name" ASC, + "companies_jobdescription"."ui_rank" ASC + ''', + }), + dict({ + 'origin': list([ + '_add_pending_for_weeks[www/apply/views/list_views.py]', + 'list_prescriptions[www/apply/views/list_views.py]', + ]), + 'sql': ''' + SELECT "approvals_approval"."id", + "approvals_approval"."start_at", + "approvals_approval"."end_at", + "approvals_approval"."created_at", + "approvals_approval"."number", + "approvals_approval"."pe_notification_status", + "approvals_approval"."pe_notification_time", + "approvals_approval"."pe_notification_endpoint", + "approvals_approval"."pe_notification_exit_code", + "approvals_approval"."user_id", + "approvals_approval"."created_by_id", + "approvals_approval"."origin", + "approvals_approval"."eligibility_diagnosis_id", + "approvals_approval"."updated_at", + "approvals_approval"."origin_siae_siret", + "approvals_approval"."origin_siae_kind", + "approvals_approval"."origin_sender_kind", + "approvals_approval"."origin_prescriber_organization_kind" + FROM "approvals_approval" + WHERE "approvals_approval"."user_id" IN (%s) + 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]', + 'list_prescriptions[www/apply/views/list_views.py]', + ]), + 'sql': ''' + SELECT "eligibility_selectedadministrativecriteria"."id", + "eligibility_selectedadministrativecriteria"."certified", + "eligibility_selectedadministrativecriteria"."certified_at", + "eligibility_selectedadministrativecriteria"."certification_period", + "eligibility_selectedadministrativecriteria"."data_returned_by_api", + "eligibility_selectedadministrativecriteria"."eligibility_diagnosis_id", + "eligibility_selectedadministrativecriteria"."administrative_criteria_id", + "eligibility_selectedadministrativecriteria"."created_at", + "eligibility_administrativecriteria"."id", + "eligibility_administrativecriteria"."kind", + "eligibility_administrativecriteria"."level", + "eligibility_administrativecriteria"."name", + "eligibility_administrativecriteria"."desc", + "eligibility_administrativecriteria"."written_proof", + "eligibility_administrativecriteria"."written_proof_url", + "eligibility_administrativecriteria"."written_proof_validity", + "eligibility_administrativecriteria"."ui_rank", + "eligibility_administrativecriteria"."created_at", + "eligibility_administrativecriteria"."created_by_id" + FROM "eligibility_selectedadministrativecriteria" + INNER JOIN "eligibility_administrativecriteria" ON ("eligibility_selectedadministrativecriteria"."administrative_criteria_id" = "eligibility_administrativecriteria"."id") + WHERE "eligibility_selectedadministrativecriteria"."eligibility_diagnosis_id" IN (%s) + ORDER BY "eligibility_administrativecriteria"."level" ASC, + "eligibility_administrativecriteria"."name" ASC + ''', + }), + dict({ + 'origin': list([ + 'CommonApprovalQuerySet.first[/django/db/models/query.py]', + 'User.latest_pe_approval[users/models.py]', + 'User.has_valid_common_approval[users/models.py]', + 'RelatedManager.has_considered_valid[eligibility/models/iae.py]', + 'User.has_valid_diagnosis[users/models.py]', + 'JobApplication.eligibility_diagnosis_by_siae_required[job_applications/models.py]', + '_add_eligibility_diagnosis_required[www/apply/views/list_views.py]', + 'list_prescriptions[www/apply/views/list_views.py]', + ]), + 'sql': ''' + SELECT "approvals_poleemploiapproval"."id", + "approvals_poleemploiapproval"."start_at", + "approvals_poleemploiapproval"."end_at", + "approvals_poleemploiapproval"."created_at", + "approvals_poleemploiapproval"."pe_notification_status", + "approvals_poleemploiapproval"."pe_notification_time", + "approvals_poleemploiapproval"."pe_notification_endpoint", + "approvals_poleemploiapproval"."pe_notification_exit_code", + "approvals_poleemploiapproval"."pe_structure_code", + "approvals_poleemploiapproval"."number", + "approvals_poleemploiapproval"."pole_emploi_id", + "approvals_poleemploiapproval"."first_name", + "approvals_poleemploiapproval"."last_name", + "approvals_poleemploiapproval"."birth_name", + "approvals_poleemploiapproval"."birthdate", + "approvals_poleemploiapproval"."nir", + "approvals_poleemploiapproval"."ntt_nia", + "approvals_poleemploiapproval"."siae_siret", + "approvals_poleemploiapproval"."siae_kind" + FROM "approvals_poleemploiapproval" + WHERE ("approvals_poleemploiapproval"."nir" = %s + AND NOT ("approvals_poleemploiapproval"."number" IN + (SELECT U0."number" + FROM "approvals_approval" U0 + WHERE U0."user_id" = %s))) + ORDER BY "approvals_poleemploiapproval"."end_at" DESC, + "approvals_poleemploiapproval"."start_at" ASC + LIMIT 1 + ''', + }), + dict({ + 'origin': list([ + 'EligibilityDiagnosisQuerySet.first[/django/db/models/query.py]', + 'RelatedManager.last_considered_valid[eligibility/models/iae.py]', + 'RelatedManager.has_considered_valid[eligibility/models/iae.py]', + 'User.has_valid_diagnosis[users/models.py]', + 'JobApplication.eligibility_diagnosis_by_siae_required[job_applications/models.py]', + '_add_eligibility_diagnosis_required[www/apply/views/list_views.py]', + 'list_prescriptions[www/apply/views/list_views.py]', + ]), + 'sql': ''' + SELECT "eligibility_eligibilitydiagnosis"."id", + "eligibility_eligibilitydiagnosis"."author_id", + "eligibility_eligibilitydiagnosis"."author_kind", + "eligibility_eligibilitydiagnosis"."author_prescriber_organization_id", + "eligibility_eligibilitydiagnosis"."created_at", + "eligibility_eligibilitydiagnosis"."updated_at", + "eligibility_eligibilitydiagnosis"."expires_at", + "eligibility_eligibilitydiagnosis"."job_seeker_id", + "eligibility_eligibilitydiagnosis"."author_siae_id", + CASE + WHEN "eligibility_eligibilitydiagnosis"."author_kind" = %s THEN %s + ELSE %s + END AS "from_prescriber", + T4."id", + T4."password", + T4."last_login", + T4."is_superuser", + T4."username", + T4."first_name", + T4."last_name", + T4."is_staff", + T4."is_active", + T4."date_joined", + T4."address_line_1", + T4."address_line_2", + T4."post_code", + T4."city", + T4."department", + T4."coords", + T4."geocoding_score", + T4."geocoding_updated_at", + T4."ban_api_resolved_address", + T4."insee_city_id", + T4."title", + T4."email", + T4."phone", + T4."kind", + T4."identity_provider", + T4."has_completed_welcoming_tour", + T4."created_by_id", + T4."external_data_source_history", + T4."last_checked_at", + T4."public_id", + T4."address_filled_at", + T4."first_login", + "prescribers_prescriberorganization"."id", + "prescribers_prescriberorganization"."address_line_1", + "prescribers_prescriberorganization"."address_line_2", + "prescribers_prescriberorganization"."post_code", + "prescribers_prescriberorganization"."city", + "prescribers_prescriberorganization"."department", + "prescribers_prescriberorganization"."coords", + "prescribers_prescriberorganization"."geocoding_score", + "prescribers_prescriberorganization"."geocoding_updated_at", + "prescribers_prescriberorganization"."ban_api_resolved_address", + "prescribers_prescriberorganization"."insee_city_id", + "prescribers_prescriberorganization"."name", + "prescribers_prescriberorganization"."created_at", + "prescribers_prescriberorganization"."updated_at", + "prescribers_prescriberorganization"."uid", + "prescribers_prescriberorganization"."active_members_email_reminder_last_sent_at", + "prescribers_prescriberorganization"."siret", + "prescribers_prescriberorganization"."is_head_office", + "prescribers_prescriberorganization"."kind", + "prescribers_prescriberorganization"."is_brsa", + "prescribers_prescriberorganization"."phone", + "prescribers_prescriberorganization"."email", + "prescribers_prescriberorganization"."website", + "prescribers_prescriberorganization"."description", + "prescribers_prescriberorganization"."is_authorized", + "prescribers_prescriberorganization"."code_safir_pole_emploi", + "prescribers_prescriberorganization"."created_by_id", + "prescribers_prescriberorganization"."authorization_status", + "prescribers_prescriberorganization"."authorization_updated_at", + "prescribers_prescriberorganization"."authorization_updated_by_id", + "companies_company"."id", + "companies_company"."address_line_1", + "companies_company"."address_line_2", + "companies_company"."post_code", + "companies_company"."city", + "companies_company"."department", + "companies_company"."coords", + "companies_company"."geocoding_score", + "companies_company"."geocoding_updated_at", + "companies_company"."ban_api_resolved_address", + "companies_company"."insee_city_id", + "companies_company"."name", + "companies_company"."created_at", + "companies_company"."updated_at", + "companies_company"."uid", + "companies_company"."active_members_email_reminder_last_sent_at", + "companies_company"."siret", + "companies_company"."naf", + "companies_company"."kind", + "companies_company"."brand", + "companies_company"."phone", + "companies_company"."email", + "companies_company"."auth_email", + "companies_company"."website", + "companies_company"."description", + "companies_company"."provided_support", + "companies_company"."source", + "companies_company"."created_by_id", + "companies_company"."block_job_applications", + "companies_company"."job_applications_blocked_at", + "companies_company"."convention_id", + "companies_company"."job_app_score", + "companies_company"."rdv_solidarites_id" + FROM "eligibility_eligibilitydiagnosis" + LEFT OUTER JOIN "companies_company" ON ("eligibility_eligibilitydiagnosis"."author_siae_id" = "companies_company"."id") + INNER JOIN "users_user" T4 ON ("eligibility_eligibilitydiagnosis"."author_id" = T4."id") + LEFT OUTER JOIN "prescribers_prescriberorganization" ON ("eligibility_eligibilitydiagnosis"."author_prescriber_organization_id" = "prescribers_prescriberorganization"."id") + WHERE ("eligibility_eligibilitydiagnosis"."job_seeker_id" = %s + AND ("eligibility_eligibilitydiagnosis"."author_kind" = %s + OR "eligibility_eligibilitydiagnosis"."author_siae_id" = %s) + AND "eligibility_eligibilitydiagnosis"."job_seeker_id" = %s + AND "eligibility_eligibilitydiagnosis"."expires_at" > %s) + ORDER BY 10 DESC, + "eligibility_eligibilitydiagnosis"."created_at" DESC + LIMIT 1 + ''', + }), + dict({ + 'origin': list([ + 'Atomic.__exit__[/django/db/transaction.py]', + ]), + 'sql': 'RELEASE SAVEPOINT ""', + }), + dict({ + 'origin': list([ + 'Atomic.__enter__[/django/db/transaction.py]', + 'SessionStore.save[/django/contrib/sessions/backends/db.py]', + ]), + 'sql': 'SAVEPOINT ""', + }), + dict({ + 'origin': list([ + 'SessionStore.save[/django/contrib/sessions/backends/db.py]', + ]), + 'sql': ''' + UPDATE "django_session" + SET "session_data" = %s, + "expire_date" = %s + WHERE "django_session"."session_key" = %s + ''', + }), + dict({ + 'origin': list([ + 'Atomic.__exit__[/django/db/transaction.py]', + 'SessionStore.save[/django/contrib/sessions/backends/db.py]', + ]), + 'sql': 'RELEASE SAVEPOINT ""', + }), + ]), + }) +# --- # name: test_exports_as_pole_emploi_prescriber '''
diff --git a/tests/www/apply/test_list_prescriptions.py b/tests/www/apply/test_list_prescriptions.py index 896c2dccf1..7ff8059d22 100644 --- a/tests/www/apply/test_list_prescriptions.py +++ b/tests/www/apply/test_list_prescriptions.py @@ -5,7 +5,7 @@ from django.urls import reverse from django.utils import timezone from freezegun import freeze_time -from pytest_django.asserts import assertContains, assertNotContains, assertNumQueries +from pytest_django.asserts import assertContains, assertNotContains from itou.job_applications.enums import JobApplicationState, SenderKind from itou.job_applications.models import JobApplicationWorkflow @@ -19,7 +19,6 @@ from tests.users.factories import JobSeekerFactory, PrescriberFactory from tests.utils.htmx.test import assertSoupEqual, update_page_with_htmx from tests.utils.test import ( - BASE_NUM_QUERIES, assert_previous_step, assertSnapshotQueries, get_rows_from_streaming_response, @@ -71,7 +70,7 @@ def test_get(client): ) -def test_as_unauthorized_prescriber(client): +def test_as_unauthorized_prescriber(client, snapshot): prescriber = PrescriberFactory() job_application = JobApplicationFactory( job_seeker_with_address=True, @@ -84,22 +83,7 @@ def test_as_unauthorized_prescriber(client): client.force_login(prescriber) list_url = reverse("apply:list_prescriptions") - with assertNumQueries( - BASE_NUM_QUERIES - + 1 # fetch django session - + 1 # fetch user - + 1 # fetch user memberships - + 1 # get list of senders (distinct sender_id) - + 1 # get list of job seekers (distinct job_seeker_id) - + 1 # get list of administrative criteria - + 2 # get list of job application + prefetch of job descriptions - + 1 # get list of siaes (distinct to_company_id) - + 3 # count, list & prefetch of job application - + 1 # get job seekers approvals - + 1 # check user authorized membership (can_edit_personal_information) - + 3 # get job seekers administrative criteria - + 3 # update session - ): + with assertSnapshotQueries(snapshot(name="SQL queries for prescriptions list")): response = client.get(list_url) job_seeker_detail_url = reverse( From 71e6e909ba65942bfeb22bc439fd1c529978af20 Mon Sep 17 00:00:00 2001 From: Xavier Fernandez Date: Thu, 3 Oct 2024 09:05:19 +0200 Subject: [PATCH 2/3] tests: add extra application to test --- .../test_list_prescriptions.ambr | 191 +++++++++++++++++- tests/www/apply/test_list_prescriptions.py | 14 ++ 2 files changed, 199 insertions(+), 6 deletions(-) diff --git a/tests/www/apply/__snapshots__/test_list_prescriptions.ambr b/tests/www/apply/__snapshots__/test_list_prescriptions.ambr index 7eaef0e2d8..b82b7de7ce 100644 --- a/tests/www/apply/__snapshots__/test_list_prescriptions.ambr +++ b/tests/www/apply/__snapshots__/test_list_prescriptions.ambr @@ -1,7 +1,7 @@ # serializer version: 1 # name: test_as_unauthorized_prescriber[SQL queries for prescriptions list] dict({ - 'num_queries': 22, + 'num_queries': 24, 'queries': list([ dict({ 'origin': list([ @@ -419,7 +419,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 ''', @@ -847,7 +848,7 @@ "approvals_approval"."id" ORDER BY "job_applications_jobapplication"."created_at" DESC, "job_applications_jobapplication"."id" ASC - LIMIT 1 + LIMIT 2 ''', }), dict({ @@ -884,7 +885,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 ''', @@ -914,7 +916,8 @@ "approvals_approval"."origin_sender_kind", "approvals_approval"."origin_prescriber_organization_kind" FROM "approvals_approval" - WHERE "approvals_approval"."user_id" IN (%s) + WHERE "approvals_approval"."user_id" IN (%s, + %s) ORDER BY "approvals_approval"."start_at" DESC ''', }), @@ -965,7 +968,8 @@ "eligibility_administrativecriteria"."created_by_id" FROM "eligibility_selectedadministrativecriteria" INNER JOIN "eligibility_administrativecriteria" ON ("eligibility_selectedadministrativecriteria"."administrative_criteria_id" = "eligibility_administrativecriteria"."id") - WHERE "eligibility_selectedadministrativecriteria"."eligibility_diagnosis_id" IN (%s) + WHERE "eligibility_selectedadministrativecriteria"."eligibility_diagnosis_id" IN (%s, + %s) ORDER BY "eligibility_administrativecriteria"."level" ASC, "eligibility_administrativecriteria"."name" ASC ''', @@ -1145,6 +1149,181 @@ LIMIT 1 ''', }), + dict({ + 'origin': list([ + 'CommonApprovalQuerySet.first[/django/db/models/query.py]', + 'User.latest_pe_approval[users/models.py]', + 'User.has_valid_common_approval[users/models.py]', + 'RelatedManager.has_considered_valid[eligibility/models/iae.py]', + 'User.has_valid_diagnosis[users/models.py]', + 'JobApplication.eligibility_diagnosis_by_siae_required[job_applications/models.py]', + '_add_eligibility_diagnosis_required[www/apply/views/list_views.py]', + 'list_prescriptions[www/apply/views/list_views.py]', + ]), + 'sql': ''' + SELECT "approvals_poleemploiapproval"."id", + "approvals_poleemploiapproval"."start_at", + "approvals_poleemploiapproval"."end_at", + "approvals_poleemploiapproval"."created_at", + "approvals_poleemploiapproval"."pe_notification_status", + "approvals_poleemploiapproval"."pe_notification_time", + "approvals_poleemploiapproval"."pe_notification_endpoint", + "approvals_poleemploiapproval"."pe_notification_exit_code", + "approvals_poleemploiapproval"."pe_structure_code", + "approvals_poleemploiapproval"."number", + "approvals_poleemploiapproval"."pole_emploi_id", + "approvals_poleemploiapproval"."first_name", + "approvals_poleemploiapproval"."last_name", + "approvals_poleemploiapproval"."birth_name", + "approvals_poleemploiapproval"."birthdate", + "approvals_poleemploiapproval"."nir", + "approvals_poleemploiapproval"."ntt_nia", + "approvals_poleemploiapproval"."siae_siret", + "approvals_poleemploiapproval"."siae_kind" + FROM "approvals_poleemploiapproval" + WHERE ("approvals_poleemploiapproval"."nir" = %s + AND NOT ("approvals_poleemploiapproval"."number" IN + (SELECT U0."number" + FROM "approvals_approval" U0 + WHERE U0."user_id" = %s))) + ORDER BY "approvals_poleemploiapproval"."end_at" DESC, + "approvals_poleemploiapproval"."start_at" ASC + LIMIT 1 + ''', + }), + dict({ + 'origin': list([ + 'EligibilityDiagnosisQuerySet.first[/django/db/models/query.py]', + 'RelatedManager.last_considered_valid[eligibility/models/iae.py]', + 'RelatedManager.has_considered_valid[eligibility/models/iae.py]', + 'User.has_valid_diagnosis[users/models.py]', + 'JobApplication.eligibility_diagnosis_by_siae_required[job_applications/models.py]', + '_add_eligibility_diagnosis_required[www/apply/views/list_views.py]', + 'list_prescriptions[www/apply/views/list_views.py]', + ]), + 'sql': ''' + SELECT "eligibility_eligibilitydiagnosis"."id", + "eligibility_eligibilitydiagnosis"."author_id", + "eligibility_eligibilitydiagnosis"."author_kind", + "eligibility_eligibilitydiagnosis"."author_prescriber_organization_id", + "eligibility_eligibilitydiagnosis"."created_at", + "eligibility_eligibilitydiagnosis"."updated_at", + "eligibility_eligibilitydiagnosis"."expires_at", + "eligibility_eligibilitydiagnosis"."job_seeker_id", + "eligibility_eligibilitydiagnosis"."author_siae_id", + CASE + WHEN "eligibility_eligibilitydiagnosis"."author_kind" = %s THEN %s + ELSE %s + END AS "from_prescriber", + T4."id", + T4."password", + T4."last_login", + T4."is_superuser", + T4."username", + T4."first_name", + T4."last_name", + T4."is_staff", + T4."is_active", + T4."date_joined", + T4."address_line_1", + T4."address_line_2", + T4."post_code", + T4."city", + T4."department", + T4."coords", + T4."geocoding_score", + T4."geocoding_updated_at", + T4."ban_api_resolved_address", + T4."insee_city_id", + T4."title", + T4."email", + T4."phone", + T4."kind", + T4."identity_provider", + T4."has_completed_welcoming_tour", + T4."created_by_id", + T4."external_data_source_history", + T4."last_checked_at", + T4."public_id", + T4."address_filled_at", + T4."first_login", + "prescribers_prescriberorganization"."id", + "prescribers_prescriberorganization"."address_line_1", + "prescribers_prescriberorganization"."address_line_2", + "prescribers_prescriberorganization"."post_code", + "prescribers_prescriberorganization"."city", + "prescribers_prescriberorganization"."department", + "prescribers_prescriberorganization"."coords", + "prescribers_prescriberorganization"."geocoding_score", + "prescribers_prescriberorganization"."geocoding_updated_at", + "prescribers_prescriberorganization"."ban_api_resolved_address", + "prescribers_prescriberorganization"."insee_city_id", + "prescribers_prescriberorganization"."name", + "prescribers_prescriberorganization"."created_at", + "prescribers_prescriberorganization"."updated_at", + "prescribers_prescriberorganization"."uid", + "prescribers_prescriberorganization"."active_members_email_reminder_last_sent_at", + "prescribers_prescriberorganization"."siret", + "prescribers_prescriberorganization"."is_head_office", + "prescribers_prescriberorganization"."kind", + "prescribers_prescriberorganization"."is_brsa", + "prescribers_prescriberorganization"."phone", + "prescribers_prescriberorganization"."email", + "prescribers_prescriberorganization"."website", + "prescribers_prescriberorganization"."description", + "prescribers_prescriberorganization"."is_authorized", + "prescribers_prescriberorganization"."code_safir_pole_emploi", + "prescribers_prescriberorganization"."created_by_id", + "prescribers_prescriberorganization"."authorization_status", + "prescribers_prescriberorganization"."authorization_updated_at", + "prescribers_prescriberorganization"."authorization_updated_by_id", + "companies_company"."id", + "companies_company"."address_line_1", + "companies_company"."address_line_2", + "companies_company"."post_code", + "companies_company"."city", + "companies_company"."department", + "companies_company"."coords", + "companies_company"."geocoding_score", + "companies_company"."geocoding_updated_at", + "companies_company"."ban_api_resolved_address", + "companies_company"."insee_city_id", + "companies_company"."name", + "companies_company"."created_at", + "companies_company"."updated_at", + "companies_company"."uid", + "companies_company"."active_members_email_reminder_last_sent_at", + "companies_company"."siret", + "companies_company"."naf", + "companies_company"."kind", + "companies_company"."brand", + "companies_company"."phone", + "companies_company"."email", + "companies_company"."auth_email", + "companies_company"."website", + "companies_company"."description", + "companies_company"."provided_support", + "companies_company"."source", + "companies_company"."created_by_id", + "companies_company"."block_job_applications", + "companies_company"."job_applications_blocked_at", + "companies_company"."convention_id", + "companies_company"."job_app_score", + "companies_company"."rdv_solidarites_id" + FROM "eligibility_eligibilitydiagnosis" + LEFT OUTER JOIN "companies_company" ON ("eligibility_eligibilitydiagnosis"."author_siae_id" = "companies_company"."id") + INNER JOIN "users_user" T4 ON ("eligibility_eligibilitydiagnosis"."author_id" = T4."id") + LEFT OUTER JOIN "prescribers_prescriberorganization" ON ("eligibility_eligibilitydiagnosis"."author_prescriber_organization_id" = "prescribers_prescriberorganization"."id") + WHERE ("eligibility_eligibilitydiagnosis"."job_seeker_id" = %s + AND ("eligibility_eligibilitydiagnosis"."author_kind" = %s + OR "eligibility_eligibilitydiagnosis"."author_siae_id" = %s) + AND "eligibility_eligibilitydiagnosis"."job_seeker_id" = %s + AND "eligibility_eligibilitydiagnosis"."expires_at" > %s) + ORDER BY 10 DESC, + "eligibility_eligibilitydiagnosis"."created_at" DESC + LIMIT 1 + ''', + }), dict({ 'origin': list([ 'Atomic.__exit__[/django/db/transaction.py]', diff --git a/tests/www/apply/test_list_prescriptions.py b/tests/www/apply/test_list_prescriptions.py index 7ff8059d22..7ffc97f5fc 100644 --- a/tests/www/apply/test_list_prescriptions.py +++ b/tests/www/apply/test_list_prescriptions.py @@ -80,6 +80,14 @@ def test_as_unauthorized_prescriber(client, snapshot): sender=prescriber, sender_kind=SenderKind.PRESCRIBER, ) + another_job_application = JobApplicationFactory( + job_seeker_with_address=True, + job_seeker__first_name="Liz", + job_seeker__last_name="Ible", + job_seeker__created_by=prescriber, # to check for useless queries + sender=prescriber, + sender_kind=SenderKind.PRESCRIBER, + ) client.force_login(prescriber) list_url = reverse("apply:list_prescriptions") @@ -92,6 +100,12 @@ def test_as_unauthorized_prescriber(client, snapshot): assertContains(response, f'S… U…') # Unfortunately, the job seeker's name is available in the filters # assertNotContains(response, "Supersecretname") + another_job_seeker_detail_url = reverse( + "job_seekers_views:details", kwargs={"public_id": another_job_application.job_seeker.public_id} + ) + assertContains( + response, f'Liz IBLE' + ) def test_filtered_by_state(client): From 5b5f3620a903b8b065a44f5febc8b24afe9077e0 Mon Sep 17 00:00:00 2001 From: Xavier Fernandez Date: Wed, 2 Oct 2024 16:29:06 +0200 Subject: [PATCH 3/3] job applications: hide job seekers' name from filter for orienteur --- itou/www/apply/forms.py | 28 +++++++++-- itou/www/apply/views/list_views.py | 2 +- .../test_list_prescriptions.ambr | 43 +++++++++-------- tests/www/apply/test_list_prescriptions.py | 46 +++++++++++++++++-- 4 files changed, 91 insertions(+), 28 deletions(-) diff --git a/itou/www/apply/forms.py b/itou/www/apply/forms.py index 8c677f1746..0ea4a884d7 100644 --- a/itou/www/apply/forms.py +++ b/itou/www/apply/forms.py @@ -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 @@ -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]) @@ -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] @@ -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"): diff --git a/itou/www/apply/views/list_views.py b/itou/www/apply/views/list_views.py index d8ad990430..37aa3c5a1d 100644 --- a/itou/www/apply/views/list_views.py +++ b/itou/www/apply/views/list_views.py @@ -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", [])) diff --git a/tests/www/apply/__snapshots__/test_list_prescriptions.ambr b/tests/www/apply/__snapshots__/test_list_prescriptions.ambr index b82b7de7ce..75563ff773 100644 --- a/tests/www/apply/__snapshots__/test_list_prescriptions.ambr +++ b/tests/www/apply/__snapshots__/test_list_prescriptions.ambr @@ -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.[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]', @@ -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]', diff --git a/tests/www/apply/test_list_prescriptions.py b/tests/www/apply/test_list_prescriptions.py index 7ffc97f5fc..ca3a27f0e1 100644 --- a/tests/www/apply/test_list_prescriptions.py +++ b/tests/www/apply/test_list_prescriptions.py @@ -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 @@ -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'S… U…') - # 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} ) @@ -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) @@ -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):