From 3d2d852ae840cf1777981ff868018c0bf8dd24ef Mon Sep 17 00:00:00 2001 From: David Code Howard Date: Fri, 6 Oct 2023 17:05:47 -0400 Subject: [PATCH 1/2] test: Test user in project query returns deleted memberships --- .../apps/collaboration/models/memberships.py | 2 +- .../project_management/models/projects.py | 6 +++++ terraso_backend/tests/graphql/test_users.py | 24 ++++++++++++++++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/terraso_backend/apps/collaboration/models/memberships.py b/terraso_backend/apps/collaboration/models/memberships.py index 69de78eb4..ab382c2eb 100644 --- a/terraso_backend/apps/collaboration/models/memberships.py +++ b/terraso_backend/apps/collaboration/models/memberships.py @@ -125,7 +125,7 @@ def is_approved_member(self, user: User) -> bool: return self.approved_members.filter(id=user.id).exists() def is_member(self, user: User) -> bool: - return self.members.filter(id=user.id).exists() + return self.memberships.filter(user=user).exists() def get_membership(self, user: User): if not user: diff --git a/terraso_backend/apps/project_management/models/projects.py b/terraso_backend/apps/project_management/models/projects.py index 54682bf05..2312f4e81 100644 --- a/terraso_backend/apps/project_management/models/projects.py +++ b/terraso_backend/apps/project_management/models/projects.py @@ -153,5 +153,11 @@ def get_membership(self, user: User): def mark_seen_by(self, user: User): self.seen_by.add(user) + def remove_user(self, user: User): + membership = self.get_membership(user) + if membership: + membership.delete() + self.save() + def __str__(self): return self.name diff --git a/terraso_backend/tests/graphql/test_users.py b/terraso_backend/tests/graphql/test_users.py index eca29fd73..02cb2be3f 100644 --- a/terraso_backend/tests/graphql/test_users.py +++ b/terraso_backend/tests/graphql/test_users.py @@ -12,8 +12,11 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see https://www.gnu.org/licenses/. - import pytest +from graphene_django.utils.testing import graphql_query +from mixer.backend.django import mixer + +from apps.core.models import User pytestmark = pytest.mark.django_db @@ -84,6 +87,7 @@ def test_users_query_has_total_count(client_query, users): id } } + totalCount } } """ @@ -98,3 +102,21 @@ def test_users_query_in_project(client_query, project, project_user): contents = response.json() assert "errors" not in contents assert contents["data"]["users"]["edges"][0]["node"]["id"] == str(project_user.id) + + +def test_users_query_in_project_deleted_member(client, project, project_user): + user = mixer.blend(User) + project.add_viewer(user) + assert project.is_member(user) + project.remove_user(user) + assert not project.is_member(user) + + client.force_login(project_user) + response = graphql_query( + USER_IN_PROJECT_QUERY, + client=client, + variables={"projectId": str(project.id), "email": user.email}, + ) + contents = response.json() + assert "errors" not in contents + assert contents["data"]["users"]["totalCount"] == 0 From 6acabd94ae21c0d2616441ae70a9033002b2b552 Mon Sep 17 00:00:00 2001 From: David Code Howard Date: Fri, 6 Oct 2023 17:22:31 -0400 Subject: [PATCH 2/2] feat: Provide filtering method to exclude deleted memberships --- terraso_backend/apps/graphql/schema/users.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/terraso_backend/apps/graphql/schema/users.py b/terraso_backend/apps/graphql/schema/users.py index a0c406d56..9263b0f0d 100644 --- a/terraso_backend/apps/graphql/schema/users.py +++ b/terraso_backend/apps/graphql/schema/users.py @@ -16,12 +16,12 @@ import graphene import rules import structlog -from django_filters import FilterSet +from django_filters import CharFilter, FilterSet from graphene import relay from graphene_django import DjangoObjectType -from graphene_django.filter import TypedFilter from apps.auth.services import JWTService +from apps.collaboration.models import Membership from apps.core.models import User, UserPreference from apps.core.models.users import NOTIFICATION_KEYS from apps.graphql.exceptions import GraphQLNotAllowedException @@ -38,7 +38,7 @@ class UserFilter(FilterSet): - project = TypedFilter(field_name="collaboration_memberships__membership_list__project") + project = CharFilter(method="filter_user_in_project") class Meta: model = User @@ -48,6 +48,10 @@ class Meta: "last_name": ["icontains"], } + def filter_user_in_project(self, queryset, name, value): + memberships = Membership.objects.filter(membership_list__project=value) + return queryset.filter(collaboration_memberships__in=memberships) + class UserNode(DjangoObjectType): id = graphene.ID(source="pk", required=True)