-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: GraphQL Group filters using deleted associated objects
There was a specific case where using Django built-in lookups for relationships doesn't work properly with the soft delete solution we implemented with `django-safedelete`. According to the library maintainers, it's a known limitation[1]. To work around this limitation, a customized filter set were created for Group schema on GraphQL. This custom filter set implements the adjustments expected to ignore soft deleted objects when filtering by relationships (joins). [1] - makinacorpus/django-safedelete#158
- Loading branch information
1 parent
86ff7a5
commit 701f3aa
Showing
2 changed files
with
170 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
import pytest | ||
from mixer.backend.django import mixer | ||
|
||
from apps.core.models import Group, Membership | ||
|
||
pytestmark = pytest.mark.django_db | ||
|
||
|
||
def test_groups_filter_by_membership_user_ignores_deleted_memberships(client_query, memberships): | ||
membership = memberships[0] | ||
membership.delete() | ||
|
||
response = client_query( | ||
""" | ||
{groups(memberships_Email: "%s") { | ||
edges { | ||
node { | ||
slug | ||
} | ||
} | ||
}} | ||
""" | ||
% membership.user.email | ||
) | ||
edges = response.json()["data"]["groups"]["edges"] | ||
|
||
assert not edges | ||
|
||
|
||
def test_groups_filter_by_with_landscape_association(client_query, users, landscape_groups): | ||
user = users[0] | ||
default_group_association, common_group_association = landscape_groups | ||
mixer.blend(Membership, user=user, group=default_group_association.group) | ||
mixer.blend(Membership, user=user, group=common_group_association.group) | ||
|
||
response = client_query( | ||
""" | ||
{groups( | ||
associatedLandscapes_Isnull: false, | ||
memberships_Email: "%s" | ||
) { | ||
edges { | ||
node { | ||
slug | ||
} | ||
} | ||
}} | ||
""" | ||
% user.email | ||
) | ||
edges = response.json()["data"]["groups"]["edges"] | ||
groups_result = [edge["node"]["slug"] for edge in edges] | ||
|
||
assert len(groups_result) == 2 | ||
assert default_group_association.group.slug in groups_result | ||
assert common_group_association.group.slug in groups_result | ||
|
||
|
||
def test_groups_filter_by_with_landscape_association_ignores_deleted_associations( | ||
client_query, users, landscape_groups | ||
): | ||
user = users[0] | ||
default_group_association, common_group_association = landscape_groups | ||
mixer.blend(Membership, user=user, group=default_group_association.group) | ||
mixer.blend(Membership, user=user, group=common_group_association.group) | ||
|
||
default_group_association.delete() | ||
|
||
response = client_query( | ||
""" | ||
{groups( | ||
associatedLandscapes_Isnull: false, | ||
memberships_Email: "%s" | ||
) { | ||
edges { | ||
node { | ||
slug | ||
} | ||
} | ||
}} | ||
""" | ||
% user.email | ||
) | ||
edges = response.json()["data"]["groups"]["edges"] | ||
groups_result = [edge["node"]["slug"] for edge in edges] | ||
|
||
assert len(groups_result) == 1 | ||
|
||
|
||
def test_groups_filter_by_default_landscape_group(client_query, users, landscape_groups): | ||
user = users[0] | ||
default_group_association, common_group_association = landscape_groups | ||
mixer.blend(Membership, user=user, group=default_group_association.group) | ||
mixer.blend(Membership, user=user, group=common_group_association.group) | ||
|
||
response = client_query( | ||
""" | ||
{groups( | ||
associatedLandscapes_IsDefaultLandscapeGroup: true, | ||
memberships_Email: "%s" | ||
) { | ||
edges { | ||
node { | ||
slug | ||
} | ||
} | ||
}} | ||
""" | ||
% user.email | ||
) | ||
edges = response.json()["data"]["groups"]["edges"] | ||
groups_result = [edge["node"]["slug"] for edge in edges] | ||
|
||
assert len(groups_result) == 1 | ||
assert default_group_association.group.slug in groups_result | ||
|
||
|
||
def test_groups_filter_by_without_landscape_association(client_query, users): | ||
user = users[0] | ||
group = mixer.blend(Group) | ||
membership = mixer.blend(Membership, user=user, group=group) | ||
|
||
response = client_query( | ||
""" | ||
{groups( | ||
associatedLandscapes_Isnull: true, | ||
memberships_Email: "%s" | ||
) { | ||
edges { | ||
node { | ||
slug | ||
} | ||
} | ||
}} | ||
""" | ||
% membership.user.email | ||
) | ||
edges = response.json()["data"]["groups"]["edges"] | ||
groups_result = [edge["node"]["slug"] for edge in edges] | ||
assert len(groups_result) == 1 | ||
assert groups_result[0] == group.slug |