Skip to content

Commit

Permalink
Merge 486881d into 013b54f
Browse files Browse the repository at this point in the history
  • Loading branch information
RutaleIvanPaul committed Aug 9, 2018
2 parents 013b54f + 486881d commit 9c7cb88
Show file tree
Hide file tree
Showing 10 changed files with 266 additions and 3 deletions.
20 changes: 20 additions & 0 deletions authors/apps/articles/migrations/0007_article_likes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 2.0.7 on 2018-08-08 10:05

from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('articles', '0006_auto_20180801_0945'),
]

operations = [
migrations.AddField(
model_name='article',
name='likes',
field=models.ManyToManyField(blank=True, related_name='likes', to=settings.AUTH_USER_MODEL),
),
]
20 changes: 20 additions & 0 deletions authors/apps/articles/migrations/0008_article_dislikes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 2.0.7 on 2018-08-08 14:11

from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('articles', '0007_article_likes'),
]

operations = [
migrations.AddField(
model_name='article',
name='dislikes',
field=models.ManyToManyField(blank=True, related_name='dislikes', to=settings.AUTH_USER_MODEL),
),
]
18 changes: 18 additions & 0 deletions authors/apps/articles/migrations/0009_article_dislikescount.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.0.7 on 2018-08-08 14:28

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('articles', '0008_article_dislikes'),
]

operations = [
migrations.AddField(
model_name='article',
name='dislikesCount',
field=models.IntegerField(default=0),
),
]
14 changes: 14 additions & 0 deletions authors/apps/articles/migrations/0024_merge_20180809_0647.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Generated by Django 2.0.7 on 2018-08-09 06:47

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('articles', '0023_auto_20180808_1545'),
('articles', '0009_article_dislikescount'),
]

operations = [
]
4 changes: 3 additions & 1 deletion authors/apps/articles/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ class Article(models.Model):
author = models.ForeignKey(User, related_name = "user_articles", on_delete = models.CASCADE)
favorited = models.BooleanField(default = False)
favoritesCount = models.IntegerField(default = 0)
dislikesCount = models.IntegerField(default = 0)
tags = TaggableManager(blank = True)
rating = models.PositiveIntegerField(blank = True, editable = False, null = True)

likes = models.ManyToManyField(User,related_name="likes",blank=True)
dislikes = models.ManyToManyField(User,related_name="dislikes",blank=True)

def save(self, *args, **kwargs):
if not self.id:
Expand Down
1 change: 1 addition & 0 deletions authors/apps/articles/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ def render(self, data, media_type=None, renderer_context=None):
return json.dumps({
'comment': data,
})

1 change: 1 addition & 0 deletions authors/apps/articles/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,5 @@ def get_article(self, obj):
class Meta:
model = Comment
fields = '__all__'


110 changes: 110 additions & 0 deletions authors/apps/articles/tests/test_like_dislike.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
from django.test import TestCase, RequestFactory
from authors.apps.articles.views import ArticleCreateAPIView,LikeArticleAPIView,DislikeArticleAPIView
from authors.apps.authentication.views import RegistrationAPIView
from rest_framework.test import force_authenticate
import json

class LikeDislikeTestCase(TestCase):

def setUp(self):
self.factory = RequestFactory()

self.user = {
"user" : {
"email":"test@gmail.com",
"username":"tester",
"password":"testpass@word"
}
}

self.request = self.factory.post('/api/users/', data = json.dumps(self.user), content_type='application/json')
self.response = RegistrationAPIView.as_view()(self.request)
self.headers = {
'HTTP_AUTHORIZATION': 'Token ' + self.response.data["token"]
}

self.article_data = {
"title":"How to Survive",
"description":"How?",
"body":"This is how to survive"
}


request = self.factory.post('api/articles', data = json.dumps(self.article_data), **self.headers, content_type = 'application/json')
response = ArticleCreateAPIView.as_view()(request)

def test_like_normal(self):
kwargs = {"slug":"how-to-survive"}
request = self.factory.post('api/articles/how-to-survive/favorite', **self.headers)
response = LikeArticleAPIView.as_view()(request,**kwargs)
self.assertEqual(response.status_code, 201)

def test_like_already_liked(self):
kwargs = {"slug":"how-to-survive"}
request = self.factory.post('api/articles/how-to-survive/favorite', **self.headers)
response = LikeArticleAPIView.as_view()(request,**kwargs)
response = LikeArticleAPIView.as_view()(request,**kwargs)
self.assertEqual(response.status_code, 409)

def test_like_missing_slug(self):
request = self.factory.post('api/articles/favorite', **self.headers)
response = LikeArticleAPIView.as_view()(request)
self.assertEqual(response.status_code, 404)

def test_delete_like_normal(self):
kwargs = {"slug":"how-to-survive"}
LikeArticleAPIView.as_view()(self.factory.post('api/articles/how-to-survive/favorite', **self.headers),**kwargs)
request = self.factory.delete('api/articles/how-to-survive/favorite', **self.headers)
response = LikeArticleAPIView.as_view()(request,**kwargs)
self.assertEqual(response.status_code, 200)

def test_delete_like_before_like(self):
kwargs = {"slug":"how-to-survive"}
request = self.factory.delete('api/articles/how-to-survive/favorite', **self.headers)
response = LikeArticleAPIView.as_view()(request,**kwargs)
self.assertEqual(response.status_code, 409)

def test_delete_like_missing_slug(self):
request = self.factory.delete('api/articles/favorite', **self.headers)
response = LikeArticleAPIView.as_view()(request)
self.assertEqual(response.status_code, 404)

def test_dislike_normal(self):
kwargs = {"slug":"how-to-survive"}
request = self.factory.post('api/articles/how-to-survive/dislike', **self.headers)
response = DislikeArticleAPIView.as_view()(request,**kwargs)
self.assertEqual(response.status_code, 201)

def test_dislike_already_disliked(self):
kwargs = {"slug":"how-to-survive"}
request = self.factory.post('api/articles/how-to-survive/dislike', **self.headers)
response = DislikeArticleAPIView.as_view()(request,**kwargs)
response = DislikeArticleAPIView.as_view()(request,**kwargs)
self.assertEqual(response.status_code, 409)

def test_dislike_missing_slug(self):
request = self.factory.post('api/articles/dislike', **self.headers)
response = DislikeArticleAPIView.as_view()(request)
self.assertEqual(response.status_code, 404)

def test_delete_dislike_normal(self):
kwargs = {"slug":"how-to-survive"}
DislikeArticleAPIView.as_view()(self.factory.post('api/articles/how-to-survive/dislike', **self.headers),**kwargs)
request = self.factory.delete('api/articles/how-to-survive/dislike', **self.headers)
response = DislikeArticleAPIView.as_view()(request,**kwargs)
self.assertEqual(response.status_code, 200)

def test_delete_dislike_before_dislike(self):
kwargs = {"slug":"how-to-survive"}
request = self.factory.delete('api/articles/how-to-survive/dislike', **self.headers)
response = DislikeArticleAPIView.as_view()(request,**kwargs)
self.assertEqual(response.status_code, 409)

def test_delete_dislike_missing_slug(self):
request = self.factory.delete('api/articles//dislike', **self.headers)
response = DislikeArticleAPIView.as_view()(request,)
self.assertEqual(response.status_code, 404)




5 changes: 4 additions & 1 deletion authors/apps/articles/urls.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from django.urls import path

from .views import ArticleCreateAPIView, RateArticleAPIView,CommentCreateAPIView
from .views import ArticleCreateAPIView, RateArticleAPIView,CommentCreateAPIView,LikeArticleAPIView,DislikeArticleAPIView


app_name = "articles"

urlpatterns = [
path('articles', ArticleCreateAPIView.as_view()),
path('articles/<slug>/rate/', RateArticleAPIView.as_view()),
path('articles/<slug>/comment', CommentCreateAPIView.as_view()),
path('articles/<slug>/like',LikeArticleAPIView.as_view()),
path('articles/<slug>/dislike',DislikeArticleAPIView.as_view()),
]

76 changes: 75 additions & 1 deletion authors/apps/articles/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from django.shortcuts import render
from rest_framework.generics import CreateAPIView, RetrieveAPIView
from rest_framework.generics import CreateAPIView, RetrieveAPIView, UpdateAPIView
from authors.apps.articles.serializers import CreateArticleSerializer, RateArticleSerializer,CreateCommentSerializer
from authors.apps.articles.renderers import ArticleJSONRenderer, RateArticleJSONRenderer,CommentJSONRenderer
from rest_framework.views import APIView
from .serializers import CreateArticleSerializer
from authors.apps.authentication.models import User
from authors.apps.articles.models import Article,Comment
from rest_framework.permissions import IsAuthenticated
Expand All @@ -10,6 +12,12 @@
from rest_framework import status
from rest_framework.response import Response
from django.shortcuts import get_object_or_404


from authors.apps.authentication.backends import JWTAuthentication

from rest_framework.response import Response
from rest_framework import status
import json

class ArticleCreateAPIView(CreateAPIView):
Expand Down Expand Up @@ -49,3 +57,69 @@ def perform_create(self, serializer):
user_data = jwt.authenticate(self.request)
slug = self.kwargs.get(self.look_url_kwarg)
serializer.save(author = user_data[0], article = get_object_or_404(Article,slug=slug))
class LikeArticleAPIView(APIView):
permission_classes = (IsAuthenticated, )
look_url_kwarg = "slug"


def post(self,*args,**kwargs):
jwt = JWTAuthentication()
user_data = jwt.authenticate(self.request)
slug = self.kwargs.get(self.look_url_kwarg)
article = get_object_or_404(Article,slug = slug)
if article.likes.filter(id=User.objects.filter(email=user_data[0])[0].id).exists():
return Response(data = {"errors":{"error":"Already liked"}},status=status.HTTP_409_CONFLICT)
article.likes.add(user_data[0])
article.save()

return Response(data = CreateArticleSerializer(article).data,status=status.HTTP_201_CREATED)

def delete(self,*args,**kwargs):
jwt = JWTAuthentication()
user_data = jwt.authenticate(self.request)
slug = self.kwargs.get(self.look_url_kwarg)
article = get_object_or_404(Article,slug = slug)
if article.likes.filter(id=User.objects.filter(email=user_data[0])[0].id).exists():
article.likes.remove(user_data[0])
article.save()
return Response(data = CreateArticleSerializer(article).data,status=status.HTTP_200_OK)
else:
return Response(data = {"errors":{"error":"Not yet liked"}},status=status.HTTP_409_CONFLICT)


class DislikeArticleAPIView(APIView):
permission_classes = (IsAuthenticated, )
look_url_kwarg = "slug"


def post(self,*args,**kwargs):
jwt = JWTAuthentication()
user_data = jwt.authenticate(self.request)
slug = self.kwargs.get(self.look_url_kwarg)
article = get_object_or_404(Article,slug = slug)
if article.dislikes.filter(id=User.objects.filter(email=user_data[0])[0].id).exists():
return Response(data = {"errors":{"error":"Already disliked"}},status=status.HTTP_409_CONFLICT)

if article.likes.filter(id=User.objects.filter(email=user_data[0])[0].id).exists():
article.likes.remove(user_data[0])

article.dislikes.add(user_data[0])
article.dislikesCount+=1
article.save()

return Response(data = CreateArticleSerializer(article).data,status=status.HTTP_201_CREATED)

def delete(self,*args,**kwargs):
jwt = JWTAuthentication()
user_data = jwt.authenticate(self.request)
slug = self.kwargs.get(self.look_url_kwarg)
article = get_object_or_404(Article,slug = slug)
if article.dislikes.filter(id=User.objects.filter(email=user_data[0])[0].id).exists():
article.dislikes.remove(user_data[0])
article.dislikesCount-=1
article.save()
return Response(data = CreateArticleSerializer(article).data,status=status.HTTP_200_OK)
else:
return Response(data = {"errors":{"error":"Not yet disliked"}},status=status.HTTP_409_CONFLICT)


0 comments on commit 9c7cb88

Please sign in to comment.