Skip to content

Commit

Permalink
N - Added test get/delete/update for comment
Browse files Browse the repository at this point in the history
  • Loading branch information
parisafarivashh authored and hmnfalahi committed Dec 19, 2023
1 parent 9944aa7 commit a971786
Show file tree
Hide file tree
Showing 6 changed files with 329 additions and 10 deletions.
13 changes: 9 additions & 4 deletions api/controllers/comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
from rest_framework import generics
from rest_framework.exceptions import NotFound
from rest_framework.filters import SearchFilter, OrderingFilter
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.permissions import IsAuthenticated

from ..models import Comment, Product
from ..permissions import IsCommentOwnerOrReadOnly
from ..serializers.comment import CommentSerializer


Expand All @@ -29,19 +29,19 @@ def get(self, request, *args, **kwargs):

def get_object(self):
comment = Comment.objects \
.filter(created_by=self.request.user) \
.filter(product_id=self.kwargs['product_id']) \
.filter(id=self.kwargs['id'])

obj = get_object_or_404(comment)
self.check_object_permissions(self.request, obj)
return obj

def get_permissions(self):
# Your logic should be all here
if self.request.method == 'GET':
self.permission_classes = []
else:
self.permission_classes = [IsAuthenticated]
self.permission_classes = [IsAuthenticated, IsCommentOwnerOrReadOnly]

return super(CommentView, self).get_permissions()

Expand All @@ -66,5 +66,10 @@ def perform_update(self, serializer):
product = Product.objects.get(id=self.kwargs.get('product_id'))
except Product.DoesNotExist:
raise NotFound
serializer.save(created_by=self.request.user, product=product)

if not self.request.user.is_admin:
# Remove 'is_approved' field from data for non-admin users
if 'is_approved' in serializer.validated_data:
del serializer.validated_data['is_approved']
serializer.save(product=product)

7 changes: 7 additions & 0 deletions api/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,10 @@ class IsAdmin(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
return request.user.is_staff is True


class IsCommentOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if obj.created_by == request.user or request.user.is_admin:
return True
return False

7 changes: 1 addition & 6 deletions api/serializers/comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@ class CommentSerializer(ModelSerializer):
class Meta:
model = Comment
fields = ['id', 'body', 'is_approved', 'created_by', 'product']

extra_kwargs = {
'is_approved': {'required': False},
'created_by': {'required': False},
'product': {'required': False},
}
read_only_fields = ['created_by', 'product']

def create(self, validated_data):
# Make the field not required for updates
Expand Down
95 changes: 95 additions & 0 deletions tests/test_comment_delete.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import json

import pytest
from rest_framework.test import APITransactionTestCase

from api.models import Product, Comment
from authorize.helpers import generate_jwt_token
from authorize.models import User


class TestComment(APITransactionTestCase):

@classmethod
@pytest.mark.django_db
def setUp(cls):
cls.admin = User.objects.create_superuser(
title='admin',
email='[email protected]',
password='Mypassword',
)
cls.user1 = User.objects.create_user(
title='user1',
email='[email protected]',
password='Mypassword',
)
cls.user2 = User.objects.create_user(
title='user2',
email='[email protected]',
password='Mypassword',
)

cls.product1 = Product.objects.create(
title='product 1',
description='description 1',
created_by=cls.user1,
)
cls.comment1 = Comment.objects.create(
body='comment1',
is_approved=False,
created_by=cls.user1,
product=cls.product1,
)
cls.comment2 = Comment.objects.create(
body='comment2',
is_approved=True,
created_by=cls.user1,
product=cls.product1,
)
cls.comment3 = Comment.objects.create(
body='comment3',
is_approved=True,
created_by=cls.user2,
product=cls.product1,
)

def test_delete(self):
"""Delete Comment"""

self.jwt_token = generate_jwt_token(self.user1.id)
self.client.force_authenticate(user=self.user1, token=self.jwt_token)

response = self.client.delete(
path=f'/api/products/{self.product1.id}/comments/{self.comment1.id}',
content_type='application/json'
)
assert response.status_code == 204

# when user is not admin, user can not delete others comment
response = self.client.delete(
path=f'/api/products/{self.product1.id}/comments/{self.comment3.id}',
content_type='application/json'
)
assert response.status_code == 403

self.jwt_token = generate_jwt_token(self.admin.id)
self.client.force_authenticate(user=self.admin, token=self.jwt_token)
# when user is admin, admin can delete others comment
response = self.client.delete(
path=f'/api/products/{self.product1.id}/comments/{self.comment3.id}',
content_type='application/json'
)
assert response.status_code == 204

response = self.client.delete(
path=f'/api/products/{self.product1.id}/comments/{0}',
content_type='application/json'
)
assert response.status_code == 404

response = self.client.delete(
path=f'/api/products/{self.product1.id}/comments/{"0"}',
content_type='application/json'
)
assert response.status_code == 404

89 changes: 89 additions & 0 deletions tests/test_comment_get.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import json

import pytest
from rest_framework.test import APITransactionTestCase

from api.models import Product, Comment
from authorize.helpers import generate_jwt_token
from authorize.models import User


class TestComment(APITransactionTestCase):

@classmethod
@pytest.mark.django_db
def setUp(cls):
cls.user1 = User.objects.create_user(
title='user1',
email='[email protected]',
password='Mypassword',
)
cls.user2 = User.objects.create_user(
title='user2',
email='[email protected]',
password='Mypassword',
)

cls.product1 = Product.objects.create(
title='product 1',
description='description 1',
created_by=cls.user1,
)
cls.comment1 = Comment.objects.create(
body='comment1',
is_approved=False,
created_by=cls.user1,
product=cls.product1,
)
cls.comment2 = Comment.objects.create(
body='comment2',
is_approved=True,
created_by=cls.user1,
product=cls.product1,
)

def test_get(self):
"""getting Comment"""

response = self.client.get(
path=f'/api/products/{self.product1.id}/comments/{self.comment1.id}',
content_type='application/json'
)
assert response.status_code == 200
assert response.data['id'] is not None
assert response.data['body'] == self.comment1.body
assert response.data['created_by'] == self.user1.id

response = self.client.get(
path=f'/api/products/{self.product1.id}/comments/{self.comment2.id}',
content_type='application/json'
)
assert response.status_code == 200
assert response.data['id'] is not None
assert response.data['body'] == self.comment2.body
assert response.data['created_by'] == self.user1.id

self.jwt_token = generate_jwt_token(self.user2.id)
self.client.force_authenticate(user=self.user2, token=self.jwt_token)

response = self.client.get(
path=f'/api/products/{self.product1.id}/comments/{self.comment2.id}',
content_type='application/json'
)
assert response.status_code == 200
assert response.data['id'] is not None
assert response.data['body'] == self.comment2.body
assert response.data['created_by'] == self.user1.id

response = self.client.get(
path=f'/api/products/{self.product1.id}/comments/{0}',
content_type='application/json'
)
assert response.status_code == 404

response = self.client.get(
path=f'/api/products/{self.product1.id}/comments/{"0"}',
content_type='application/json'
)
assert response.status_code == 404

128 changes: 128 additions & 0 deletions tests/test_comment_update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import json

import pytest
from rest_framework.test import APITransactionTestCase

from api.models import Product, Comment
from authorize.helpers import generate_jwt_token
from authorize.models import User


class TestComment(APITransactionTestCase):

@classmethod
@pytest.mark.django_db
def setUp(cls):
cls.admin = User.objects.create_superuser(
title='admin',
email='[email protected]',
password='Mypassword',
)
cls.user1 = User.objects.create_user(
title='user1',
email='[email protected]',
password='Mypassword',
)
cls.user2 = User.objects.create_user(
title='user2',
email='[email protected]',
password='Mypassword',
)

cls.product1 = Product.objects.create(
title='product 1',
description='description 1',
created_by=cls.user1,
)
cls.comment1 = Comment.objects.create(
body='comment1',
is_approved=False,
created_by=cls.user1,
product=cls.product1,
)
cls.comment2 = Comment.objects.create(
body='comment2',
is_approved=True,
created_by=cls.user1,
product=cls.product1,
)
cls.comment3 = Comment.objects.create(
body='comment3',
is_approved=True,
created_by=cls.user2,
product=cls.product1,
)

def test_update(self):
"""Updating Comment"""

self.jwt_token = generate_jwt_token(self.user1.id)
self.client.force_authenticate(user=self.user1, token=self.jwt_token)

response = self.client.patch(
path=f'/api/products/{self.product1.id}/comments/{self.comment1.id}',
data=json.dumps({
'body': 'test',
}),
content_type='application/json'
)
assert response.status_code == 200
assert response.data['id'] is not None
assert response.data['body'] == 'test'
assert response.data['created_by'] == self.user1.id

# when user is not admin, user can not update is_approved field
response = self.client.patch(
path=f'/api/products/{self.product1.id}/comments/{self.comment1.id}',
data=json.dumps({
'body': 'test 2',
'is_approved': True,
}),
content_type='application/json'
)
assert response.status_code == 200
assert response.data['id'] is not None
assert response.data['body'] == 'test 2'
assert response.data['created_by'] == self.user1.id
assert response.data['is_approved'] is False

self.jwt_token = generate_jwt_token(self.admin.id)
self.client.force_authenticate(user=self.admin, token=self.jwt_token)

# when user is admin, user can update is_approved field for comments
response = self.client.patch(
path=f'/api/products/{self.product1.id}/comments/{self.comment1.id}',
data=json.dumps({'is_approved': True}),
content_type='application/json'
)
assert response.status_code == 200
assert response.data['id'] is not None
assert response.data['body'] == 'test 2'
assert response.data['created_by'] == self.user1.id
assert response.data['is_approved'] is True

self.jwt_token = generate_jwt_token(self.user2.id)
self.client.force_authenticate(user=self.user2, token=self.jwt_token)

# user 2 do not have access to comment of user 1
response = self.client.patch(
path=f'/api/products/{self.product1.id}/comments/{self.comment2.id}',
data=json.dumps({'body': 'test 3'}),
content_type='application/json'
)
assert response.status_code == 403

response = self.client.patch(
path=f'/api/products/{self.product1.id}/comments/{0}',
data=json.dumps({'body': 'test 4'}),
content_type='application/json'
)
assert response.status_code == 404

response = self.client.patch(
path=f'/api/products/{self.product1.id}/comments/{"0"}',
data=json.dumps({'body': 'test 5'}),
content_type='application/json'
)
assert response.status_code == 404

0 comments on commit a971786

Please sign in to comment.