Skip to content

Commit

Permalink
feat: add group admin to list groups (#4779)
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewelwell authored Oct 30, 2024
1 parent a1600c5 commit 391b377
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 5 deletions.
65 changes: 64 additions & 1 deletion api/tests/unit/users/test_unit_users_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
from integrations.lead_tracking.hubspot.constants import HUBSPOT_COOKIE_NAME
from organisations.invites.models import Invite, InviteLink
from organisations.models import Organisation, OrganisationRole
from users.models import FFAdminUser, HubspotTracker, UserPermissionGroup
from users.models import (
FFAdminUser,
HubspotTracker,
UserPermissionGroup,
UserPermissionGroupMembership,
)


def test_join_organisation(
Expand Down Expand Up @@ -867,3 +872,61 @@ def test_send_reset_password_emails_rate_limit_resets_after_password_reset(

# Then - we should receive another email
assert len(mail.outbox) == 1


def test_list_user_groups(
organisation: Organisation,
admin_client: APIClient,
django_assert_num_queries: DjangoAssertNumQueries,
) -> None:
# Given
user1 = FFAdminUser.objects.create(email="user1@example.com")
user2 = FFAdminUser.objects.create(email="user2@example.com")

user1.add_organisation(organisation)
user2.add_organisation(organisation)

user_permission_group_1 = UserPermissionGroup.objects.create(
organisation=organisation, name="group1"
)
user_permission_group_2 = UserPermissionGroup.objects.create(
organisation=organisation, name="group2"
)

UserPermissionGroupMembership.objects.create(
ffadminuser=user1, userpermissiongroup=user_permission_group_1, group_admin=True
)
UserPermissionGroupMembership.objects.create(
ffadminuser=user2, userpermissiongroup=user_permission_group_2, group_admin=True
)
UserPermissionGroupMembership.objects.create(
ffadminuser=user1, userpermissiongroup=user_permission_group_2
)

url = reverse(
"api-v1:organisations:organisation-groups-list", args=[organisation.id]
)

# When
with django_assert_num_queries(7):
response = admin_client.get(url)

# Then
assert response.status_code == status.HTTP_200_OK

response_json = response.json()
assert response_json["count"] == 2

group_1 = response_json["results"][0]
group_1_users = group_1["users"]
assert len(group_1_users) == 1
assert group_1_users[0]["id"] == user1.pk
assert group_1_users[0]["group_admin"] is True

group_2 = response_json["results"][1]
group_2_users = group_2["users"]
assert len(group_2_users) == 2
assert tuple((user["id"], user["group_admin"]) for user in group_2_users) == (
(user1.pk, False),
(user2.pk, True),
)
23 changes: 19 additions & 4 deletions api/users/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
from organisations.models import Organisation
from organisations.serializers import UserOrganisationSerializer

from .models import FFAdminUser, UserPermissionGroup
from .models import (
FFAdminUser,
UserPermissionGroup,
UserPermissionGroupMembership,
)


class UserIdSerializer(serializers.Serializer):
Expand Down Expand Up @@ -106,13 +110,24 @@ class Meta:


class ListUserPermissionGroupMembershipSerializer(serializers.ModelSerializer):
# Note that in order to add the group_admin attribute, we use the UserPermissionGroupMembership
# object instead of the FFAdminUser object. As such, we need to manually define the fields
# and sources here.
id = serializers.IntegerField(source="ffadminuser.id")
email = serializers.EmailField(source="ffadminuser.email")
first_name = serializers.CharField(source="ffadminuser.first_name")
last_name = serializers.CharField(source="ffadminuser.last_name")
last_login = serializers.CharField(source="ffadminuser.last_login")

class Meta:
model = FFAdminUser
fields = ("id", "email", "first_name", "last_name", "last_login")
model = UserPermissionGroupMembership
fields = ("id", "email", "first_name", "last_name", "last_login", "group_admin")


class ListUserPermissionGroupSerializer(UserPermissionGroupSerializer):
users = ListUserPermissionGroupMembershipSerializer(many=True, read_only=True)
users = ListUserPermissionGroupMembershipSerializer(
many=True, read_only=True, source="userpermissiongroupmembership_set"
)


class UserPermissionGroupMembershipSerializer(serializers.ModelSerializer):
Expand Down
10 changes: 10 additions & 0 deletions api/users/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,16 @@ def get_queryset(self):
q = q & Q(userpermissiongroupmembership__group_admin=True)
qs = qs.filter(q)

if self.action == "list":
qs = qs.prefetch_related(
Prefetch(
"userpermissiongroupmembership_set",
queryset=UserPermissionGroupMembership.objects.select_related(
"ffadminuser"
),
)
)

return qs

def paginate_queryset(self, queryset: QuerySet) -> list[UserPermissionGroup] | None:
Expand Down

0 comments on commit 391b377

Please sign in to comment.