From 6f24fe304b2b78d67c8843569edbd83e17cf4a6d Mon Sep 17 00:00:00 2001 From: Xavier Fernandez Date: Fri, 13 Dec 2024 18:00:15 +0100 Subject: [PATCH] organizations: fix member_required behavior --- itou/common_apps/organizations/models.py | 13 +++++++++++-- tests/companies/test_models.py | 14 ++++++++++++++ tests/institutions/tests.py | 16 ++++++++++++++++ tests/prescribers/tests.py | 16 ++++++++++++++++ tests/www/apply/__snapshots__/test_submit.ambr | 13 +++++++++---- 5 files changed, 66 insertions(+), 6 deletions(-) diff --git a/itou/common_apps/organizations/models.py b/itou/common_apps/organizations/models.py index fddb9bb758..1776d52408 100644 --- a/itou/common_apps/organizations/models.py +++ b/itou/common_apps/organizations/models.py @@ -2,7 +2,7 @@ from django.conf import settings from django.db import models -from django.db.models import Prefetch, Q +from django.db.models import Exists, OuterRef, Prefetch, Q from django.forms import ValidationError from django.utils import timezone @@ -16,7 +16,16 @@ class OrganizationQuerySet(models.QuerySet): """ def member_required(self, user): - return self.filter(members=user, members__is_active=True) + membership_model = self.model.members.through + # through_fields contains a tuple like ("company", "user") + structure_field, _user_field = self.model.members.rel.through_fields + return self.filter( + Exists( + membership_model.objects.filter( + user=user, is_active=True, user__is_active=True, **{structure_field: OuterRef("pk")} + ) + ) + ) def prefetch_active_memberships(self): membership_model = self.model.members.through diff --git a/tests/companies/test_models.py b/tests/companies/test_models.py index 233b60f816..5564173ee3 100644 --- a/tests/companies/test_models.py +++ b/tests/companies/test_models.py @@ -271,6 +271,20 @@ def test_add_or_activate_member(self): class TestCompanyQuerySet: + def test_member_required(self): + company = CompanyFactory() + user = EmployerFactory() + assert Company.objects.member_required(user).count() == 0 + + company.add_or_activate_member(user) + assert Company.objects.member_required(user).get() == company + + membership = company.memberships.get() + membership.is_active = False + membership.save(update_fields=("is_active",)) + + assert Company.objects.member_required(user).count() == 0 + def test_with_count_recent_received_job_applications(self): company = CompanyFactory() model = JobApplicationFactory._meta.model diff --git a/tests/institutions/tests.py b/tests/institutions/tests.py index c45900e046..11bd9531fb 100644 --- a/tests/institutions/tests.py +++ b/tests/institutions/tests.py @@ -71,6 +71,22 @@ def test_add_or_activate_member(self): institution.add_or_activate_member(wrong_kind_user) +class TestInstitutionQuerySet: + def test_member_required(self): + institution = InstitutionFactory() + user = LaborInspectorFactory() + assert Institution.objects.member_required(user).count() == 0 + + institution.add_or_activate_member(user) + assert Institution.objects.member_required(user).get() == institution + + membership = institution.memberships.get() + membership.is_active = False + membership.save(update_fields=("is_active",)) + + assert Institution.objects.member_required(user).count() == 0 + + def test_deactivate_last_admin(admin_client, mailoutbox): institution = InstitutionWithMembershipFactory(department="") membership = institution.memberships.first() diff --git a/tests/prescribers/tests.py b/tests/prescribers/tests.py index ecadbf7d5d..1298013a82 100644 --- a/tests/prescribers/tests.py +++ b/tests/prescribers/tests.py @@ -246,6 +246,22 @@ def test_update_prescriber_with_api_entreprise(self, settings): assert organization.is_head_office is True +class TestPrescriberOrganizationQuerySet: + def test_member_required(self): + organization = PrescriberOrganizationFactory() + user = PrescriberFactory() + assert PrescriberOrganization.objects.member_required(user).count() == 0 + + organization.add_or_activate_member(user) + assert PrescriberOrganization.objects.member_required(user).get() == organization + + membership = organization.memberships.get() + membership.is_active = False + membership.save(update_fields=("is_active",)) + + assert PrescriberOrganization.objects.member_required(user).count() == 0 + + class TestPrescriberOrganizationAdmin: ACCEPT_BUTTON_LABEL = "Valider l'habilitation" REFUSE_BUTTON_LABEL = "Refuser l'habilitation" diff --git a/tests/www/apply/__snapshots__/test_submit.ambr b/tests/www/apply/__snapshots__/test_submit.ambr index 5b409c4a0d..fa0d926182 100644 --- a/tests/www/apply/__snapshots__/test_submit.ambr +++ b/tests/www/apply/__snapshots__/test_submit.ambr @@ -210,11 +210,16 @@ "companies_company"."is_searchable", "companies_company"."rdv_solidarites_id" FROM "companies_company" - INNER JOIN "companies_companymembership" ON ("companies_company"."id" = "companies_companymembership"."company_id") - INNER JOIN "users_user" ON ("companies_companymembership"."user_id" = "users_user"."id") WHERE (NOT ("companies_company"."siret" = %s) - AND "companies_companymembership"."user_id" = %s - AND "users_user"."is_active" + AND EXISTS + (SELECT %s AS "a" + FROM "companies_companymembership" U0 + INNER JOIN "users_user" U2 ON (U0."user_id" = U2."id") + WHERE (U0."company_id" = ("companies_company"."id") + AND U0."is_active" + AND U0."user_id" = %s + AND U2."is_active") + LIMIT 1) AND "companies_company"."id" = %s) LIMIT 21 ''',