Skip to content

Commit

Permalink
Publications are done :) We have 13 tests
Browse files Browse the repository at this point in the history
  • Loading branch information
TheBirdie authored and TheBirdie committed Feb 15, 2016
1 parent 76ecf5c commit 4cb9e1a
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 18 deletions.
1 change: 0 additions & 1 deletion sigma_publications/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ class Publication(models.Model):
# Related fields
# - comments (model PublicationComment)
# - posts (model GroupPost)
# - posted_in (model Group.publications through GroupPost)


class GroupPost(models.Model):
Expand Down
7 changes: 3 additions & 4 deletions sigma_publications/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@
class PublicationSerializer(serializers.ModelSerializer):
class Meta:
model = Publication
read_only_fields = ('poster_group', 'poster_user')
read_only_fields = ('poster_group', 'poster_user', )

poster_group = serializers.PrimaryKeyRelatedField(allow_null=True, queryset=Group.objects.all())
poster_group = serializers.PrimaryKeyRelatedField(read_only=True, allow_null=True)
poster_user = serializers.PrimaryKeyRelatedField(
read_only=True,
default=serializers.CurrentUserDefault()
)
default=serializers.CurrentUserDefault())
text = serializers.CharField()


Expand Down
70 changes: 63 additions & 7 deletions sigma_publications/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@
faker = FakerFactory.create('fr_FR')
class PublicationFactory(factory.django.DjangoModelFactory):
class Meta:
model = User
model = Publication

title = factory.LazyAttribute(lambda obj: faker.last_name())
body = factory.LazyAttribute(lambda obj: faker.text())
text = factory.LazyAttribute(lambda obj: faker.text())


class GroupPostFactory(factory.django.DjangoModelFactory):
Expand All @@ -45,6 +44,7 @@ class Meta:
from rest_framework.test import APITestCase

from sigma_core.tests.factories import UserFactory, GroupFactory, AdminUserFactory, GroupMemberFactory
from sigma_publications.serializers import PublicationSerializer


class PublicationTestsSituation(APITestCase):
Expand All @@ -53,26 +53,35 @@ def setUpTestData(self):
super(APITestCase, self).setUpTestData()
# Situation
# User0
# -> Group0
# -> Group0 [Group admin]
# -> Group1
# -> Group2
# -> Publication0 ("draft")
# User1
# -> Group1 [Group admin]
# -> GroupPost -> Publication1
# -> Publication1
# User2
# -> Group2
self.users = UserFactory.create_batch(3)
self.groups = GroupFactory.create_batch(3)
GroupMemberFactory(user=self.users[0], group=self.groups[0])
GroupMemberFactory(user=self.users[0], group=self.groups[0], perm_rank=Group.ADMINISTRATOR_RANK)
GroupMemberFactory(user=self.users[0], group=self.groups[1])
GroupMemberFactory(user=self.users[0], group=self.groups[2])
GroupMemberFactory(user=self.users[1], group=self.groups[1], perm_rank=Group.ADMINISTRATOR_RANK)
GroupMemberFactory(user=self.users[2], group=self.groups[2])

# Publications
self.publications = [PublicationFactory(poster_user=self.users[0]),
PublicationFactory(poster_user=self.users[1])]
GroupPostFactory(publication=self.publications[1], group=self.groups[1])

# Routes
self.publications_route = '/publication/'


class PublicationTests(PublicationTestsSituation):
# CREATE
def gen_new_publication(self, poster_user, poster_group):
pub = {'text' : 'Random text', 'poster_user': '', 'poster_group' : ''}
if poster_user is not None:
Expand All @@ -99,8 +108,9 @@ def test_create_publication_as_someone_else(self):
self.client.force_authenticate(user=self.users[0])
response = self.client.post(self.publications_route, self.gen_new_publication(self.users[1], None))
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Publication.objects.filter(poster_user=self.users[0]).count(), 1)
self.assertEqual(Publication.objects.filter(poster_user=self.users[1]).count(), 0)
qs = Publication.objects.filter(pk=response.data.get('id'))
self.assertEqual(qs.filter(poster_user=self.users[0]).count(), 1)
self.assertEqual(qs.filter(poster_user=self.users[1]).count(), 0)

def test_create_publication_as_group_ok(self):
self.client.force_authenticate(user=self.users[1])
Expand All @@ -111,3 +121,49 @@ def test_create_publication_as_user_ok(self):
self.client.force_authenticate(user=self.users[0])
response = self.client.post(self.publications_route, self.gen_new_publication(self.users[0], None))
self.assertEqual(response.status_code, status.HTTP_201_CREATED)

# UPDATE
def test_update_not_authed(self):
data = PublicationSerializer(self.publications[0]).data
data['text'] = 'Just edit this'
response = self.client.put("%s%d/" % (self.publications_route, self.publications[0].id), data)
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

def test_update_not_owner(self):
self.client.force_authenticate(user=self.users[1])
data = PublicationSerializer(self.publications[0]).data
data['text'] = 'Just edit this'
response = self.client.put("%s%d/" % (self.publications_route, self.publications[0].id), data)
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

def test_update_poster_group_read_only(self):
self.client.force_authenticate(user=self.users[0])
data = PublicationSerializer(self.publications[0]).data
data['poster_group'] = self.groups[0].id
response = self.client.put("%s%d/" % (self.publications_route, self.publications[0].id), data)
# Response code is 200 ...
self.publications[0].refresh_from_db()
self.assertEqual(self.publications[0].poster_group, None)

def test_update_ok(self):
self.client.force_authenticate(user=self.users[0])
data = PublicationSerializer(self.publications[0]).data
data['text'] = 'Just edit this'
response = self.client.put("%s%d/" % (self.publications_route, self.publications[0].id), data)
self.assertEqual(response.status_code, status.HTTP_200_OK)

# DESTROY
def test_delete_not_draft(self):
self.client.force_authenticate(user=self.users[1])
response = self.client.delete("%s%d/" % (self.publications_route, self.publications[1].id))
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

def test_delete_not_own_publication(self):
self.client.force_authenticate(user=self.users[1])
response = self.client.delete("%s%d/" % (self.publications_route, self.publications[0].id))
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

def test_delete_own_draft_ok(self):
self.client.force_authenticate(user=self.users[0])
response = self.client.delete("%s%d/" % (self.publications_route, self.publications[0].id))
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
41 changes: 35 additions & 6 deletions sigma_publications/views/publication.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from django.http import Http404, HttpResponseForbidden
from django.core.exceptions import ValidationError
from django.core.exceptions import ValidationError, PermissionDenied

from rest_framework import viewsets, decorators, status, mixins
from rest_framework.response import Response
Expand All @@ -12,17 +12,21 @@

from django.db.models import F

class PublicationViewSet(mixins.CreateModelMixin, # Everyone can create a publication
#mixins.RetrieveModelMixin, # TODO?
mixins.UpdateModelMixin, # TODO
mixins.DestroyModelMixin, # TODO
#mixins.ListModelMixin, # TODO?
class PublicationViewSet(mixins.CreateModelMixin, # Everyone can create a publication
#mixins.RetrieveModelMixin, # Not needed. Will be retrieved with the GroupPost view
# TODO: Maybe for sigma admins, to see where it is posted ?
mixins.UpdateModelMixin, # Only your own Publication
mixins.DestroyModelMixin, # Only if it is not posted already, or for sigma admins
#mixins.ListModelMixin, # Not needed. Will be retrieved with the GroupPost view
viewsets.GenericViewSet):
queryset = Publication.objects.all()
serializer_class = PublicationSerializer
permission_classes = [IsAuthenticated, ]

def create(self, request):
"""
Create a new Publication. Only visible by the user at first.
"""
serializer = self.get_serializer(data=request.data)
allowed_groups = Group.objects.filter(memberships__user=request.user,
memberships__perm_rank__gte=F('req_rank_create_group_publication'))
Expand All @@ -33,3 +37,28 @@ def create(self, request):

serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)

def update(self, request, *args, **kwargs):
"""
Update the Publication text. The autor User or autor Group are not modifiable.
"""
if not request.user.is_sigma_admin():
self.queryset = self.queryset.filter(poster_user=request.user)
return super().update(request, *args, **kwargs)

def check_object_permissions(self, request, publication):
if self.action == "destroy":
if publication.comments.all():
raise PermissionDenied()
if publication.posts.all():
raise PermissionDenied()
return super().check_object_permissions(request, publication)

def destroy(self, request, *args, **kwargs):
"""
Destroy the Publication.
Only possible if there is no comment and if the publication is not already posted.
"""
if not request.user.is_sigma_admin():
self.queryset = self.queryset.filter(poster_user=request.user)
return super().destroy(request, *args, **kwargs)

0 comments on commit 4cb9e1a

Please sign in to comment.