From e689aaac93fcf05c34d8541051b7688331e80dfa Mon Sep 17 00:00:00 2001 From: Valentin Rigal <rigal@teklia.com> Date: Fri, 27 Nov 2020 12:56:24 +0100 Subject: [PATCH] Serializer membership ID in the ListMembers endpoint --- arkindex/users/api.py | 3 +- arkindex/users/serializers.py | 78 +++++++++++++------------ arkindex/users/tests/test_membership.py | 33 ++--------- 3 files changed, 49 insertions(+), 65 deletions(-) diff --git a/arkindex/users/api.py b/arkindex/users/api.py index e8692d5e79..a764b103a1 100644 --- a/arkindex/users/api.py +++ b/arkindex/users/api.py @@ -514,7 +514,8 @@ class JobRetrieve(RetrieveDestroyAPIView): class GroupMembershipsList(ListCreateAPIView): """ - List members of a group to which user belongs with their privileges + List members of a group to which user belongs with their privileges. + Response `id` field identifies the membership and not the user. """ serializer_class = MemberSerializer permission_classes = (IsVerified, ) diff --git a/arkindex/users/serializers.py b/arkindex/users/serializers.py index be4787cc2d..bbd83a0e9e 100644 --- a/arkindex/users/serializers.py +++ b/arkindex/users/serializers.py @@ -216,6 +216,27 @@ class UserTranskribusSerializer(serializers.Serializer): return instance +class JobSerializer(serializers.Serializer): + """ + Serializers a RQ job. + """ + id = serializers.UUIDField(read_only=True) + description = serializers.CharField(read_only=True) + progress = serializers.FloatField(min_value=0, max_value=1, read_only=True, allow_null=True) + status = serializers.SerializerMethodField() + enqueued_at = serializers.DateTimeField(read_only=True, allow_null=True) + started_at = serializers.DateTimeField(read_only=True, allow_null=True) + ended_at = serializers.DateTimeField(read_only=True, allow_null=True) + + def get_status(self, instance): + """ + Avoid causing more Redis queries to fetch a job's current status + Note that a job status is part of a JobStatus enum, + but the enum is just a plain object and not an Enum for Py2 compatibility. + """ + return instance.get_status(refresh=False) + + class GroupSerializer(serializers.ModelSerializer): """ A light group serializer with properties and members count @@ -241,37 +262,37 @@ class GroupSerializer(serializers.ModelSerializer): return group -class JobSerializer(serializers.Serializer): +class MembershipSerializer(serializers.ModelSerializer): """ - Serializers a RQ job. + Simple serializer for a membership """ - id = serializers.UUIDField(read_only=True) - description = serializers.CharField(read_only=True) - progress = serializers.FloatField(min_value=0, max_value=1, read_only=True, allow_null=True) - status = serializers.SerializerMethodField() - enqueued_at = serializers.DateTimeField(read_only=True, allow_null=True) - started_at = serializers.DateTimeField(read_only=True, allow_null=True) - ended_at = serializers.DateTimeField(read_only=True, allow_null=True) + class Meta: + model = Membership + fields = ( + 'id', + 'level', + ) - def get_status(self, instance): - """ - Avoid causing more Redis queries to fetch a job's current status - Note that a job status is part of a JobStatus enum, - but the enum is just a plain object and not an Enum for Py2 compatibility. - """ - return instance.get_status(refresh=False) +class MemberGroupSerializer(MembershipSerializer): + """ + Serialize a group for a specific member with its privilege level + """ + group = GroupSerializer() + + class Meta(MembershipSerializer.Meta): + fields = MembershipSerializer.Meta.fields + ('group', ) -class MemberSerializer(serializers.ModelSerializer): + +class MemberSerializer(MembershipSerializer): """ - Serialize a user member of a group with its privileges level + Serialize the user of a group with its member privilege level """ - id = serializers.IntegerField(source='user.id', read_only=True) + id = serializers.IntegerField(read_only=True) email = serializers.EmailField(source='user.email') display_name = serializers.StringRelatedField(source='user.display_name', read_only=True) - class Meta: - model = Membership + class Meta(MembershipSerializer.Meta): fields = ( 'level', 'id', @@ -293,18 +314,3 @@ class MemberSerializer(serializers.ModelSerializer): def create(self, validated_data): return Membership.objects.create(group=self.context['group'], **validated_data) - - -class MemberGroupSerializer(serializers.ModelSerializer): - """ - Serialize a group for a specific member with its privileges level - """ - group = GroupSerializer() - - class Meta: - model = Membership - fields = ( - 'id', - 'group', - 'level', - ) diff --git a/arkindex/users/tests/test_membership.py b/arkindex/users/tests/test_membership.py index c053cd6c93..41e025c481 100644 --- a/arkindex/users/tests/test_membership.py +++ b/arkindex/users/tests/test_membership.py @@ -140,46 +140,22 @@ class TestMembership(FixtureAPITestCase): { 'display_name': 'Test user', 'email': admin_member.user.email, - 'id': admin_member.user.id, + 'id': admin_member.id, 'level': Group.ADMIN_LEVEL }, { 'display_name': 'Test user read', 'email': read_member.user.email, - 'id': read_member.user.id, + 'id': read_member.id, 'level': read_member.level }, { 'display_name': 'Test user write', 'email': write_member.user.email, - 'id': write_member.user.id, + 'id': write_member.id, 'level': write_member.level } ] }) - def test_list_members_null_right(self): - """ - Non defined right level should return None - """ - self.client.force_login(self.user) - group = self.user.groups.create(name='Another group', through_defaults={'level': 1}) - with self.assertNumQueries(6): - response = self.client.get(reverse('api:group-members', kwargs={'pk': str(group.id)})) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(response.json(), { - 'count': 1, - 'next': None, - 'number': 1, - 'previous': None, - 'results': [ - { - 'display_name': self.user.display_name, - 'email': self.user.email, - 'id': self.user.id, - 'level': 1 - } - ] - }) - def test_retrieve_group_no_member(self): """ A non memeber of a group may not retrieve its details, even if it is public @@ -410,9 +386,10 @@ class TestMembership(FixtureAPITestCase): {'email': user.email, 'level': 10} ) self.assertEqual(response.status_code, status.HTTP_201_CREATED) + membership = user.memberships.get(group=self.group) self.assertDictEqual(response.json(), { 'display_name': user.display_name, 'email': user.email, - 'id': user.id, + 'id': membership.id, 'level': 10 }) -- GitLab