Skip to content
Snippets Groups Projects
Commit f35a8dd1 authored by Bastien Abadie's avatar Bastien Abadie
Browse files

Merge branch 'members-id' into 'master'

Serializer membership ID in the ListMembers endpoint

Closes #559

See merge request !1104
parents b9af5a4d e689aaac
No related branches found
No related tags found
1 merge request!1104Serializer membership ID in the ListMembers endpoint
......@@ -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, )
......
......@@ -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',
)
......@@ -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
})
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment