Skip to content

Commit

Permalink
feat(bookmark) create delete bookmark
Browse files Browse the repository at this point in the history
- user can create bookmark
- user can delete bookmark

[Delivers #161254679]
  • Loading branch information
Eyansky committed Nov 15, 2018
1 parent 615ace6 commit 357c836
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 5 deletions.
56 changes: 53 additions & 3 deletions authors/apps/article/likes_dislike_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
from rest_framework import status
from rest_framework.permissions import IsAuthenticated

from authors.apps.article.renderers import FavoriteJSONRenderer
from authors.apps.article.renderers import FavoriteJSONRenderer, BookmarkJSONRenderer
from authors.apps.article.serializers import FavoriteSerializer,\
ArticleSerializer
ArticleSerializer, BookmarkSerializer
from .models import (Article,
LikeDislikeArticle, Favorite)
LikeDislikeArticle, Favorite, Bookmark)


LOOKUP_FIELD = 'slug'
Expand Down Expand Up @@ -199,3 +199,53 @@ def delete(self, request, slug):
data = dict(article=article_serializer.data)
data["message"] = "unfavorited"
return Response(data, status.HTTP_200_OK)


class BookmarkAPIView(APIView):
serializer_class = BookmarkSerializer
permission_classes = (IsAuthenticated,)
queryset = Bookmark.objects.all()
renderer_classes = (BookmarkJSONRenderer,)

def post(self, request, slug):
"""Bookmark article"""
try:
article = Article.objects.get(slug=slug)
except Article.DoesNotExist:
return Response({"Message": [
"That article does not exist"
]}, status.HTTP_204_NO_CONTENT)
bookmark = dict()
bookmark["user"] = request.user.id
bookmark["article"] = article.pk
serializer = self.serializer_class(data=bookmark)
serializer.is_valid(raise_exception=True)
serializer.save()
article_serializer = ArticleSerializer(
instance=article, context={'request': request})
data = dict(article=article_serializer.data)
data["article"]["bookmarked"] = True
data["message"] = "bookmarked"
return Response(data, status.HTTP_200_OK)

def delete(self, request, slug):
"""unbookmark an article"""
try:
article = Article.objects.get(slug=slug)
except Article.DoesNotExist:
raise NotFound({"error": [
"That article does not exist"
]})
try:
bookmark = Bookmark.objects.get(
user=request.user.id, article=article.pk)
except Bookmark.DoesNotExist:
return Response(
{"Message": "You have not bookmarked this article yet"},
status.HTTP_409_CONFLICT)
bookmark.delete()
article_serializer = ArticleSerializer(
instance=article, context={'request': request})
data = dict(article=article_serializer.data)
data["message"] = "unbookmarked"
return Response(data, status.HTTP_200_OK)
12 changes: 12 additions & 0 deletions authors/apps/article/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,15 @@ class CommentHistory(models.Model):
on_delete=models.CASCADE,
db_column='original_comment')
date_created = models.DateTimeField(auto_now=True)


class Bookmark(models.Model):
"""Bookmark model"""
article = models.ForeignKey(
Article,
related_name="bookmarked",
on_delete=models.CASCADE)
user = models.ForeignKey(
User,
related_name="bookmarks",
on_delete=models.CASCADE)
9 changes: 9 additions & 0 deletions authors/apps/article/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,12 @@ def render(self, data, media_type=None, renderer_context=None):
if not status_code == status.HTTP_200_OK:
return super(FavoriteJSONRenderer, self).render(data)
return super(FavoriteJSONRenderer, self).render(data)


class BookmarkJSONRenderer(JSONRenderer):
def render(self, data, media_type=None, renderer_context=None):
if renderer_context:
status_code = renderer_context.get('response').status_code
if not status_code == status.HTTP_200_OK:
return super(BookmarkJSONRenderer, self).render(data)
return super(BookmarkJSONRenderer, self).render(data)
16 changes: 15 additions & 1 deletion authors/apps/article/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

from authors.apps.profiles.models import UserProfile

from .models import RateArticle, Comments, CommentHistory, Favorite
from .models import RateArticle, Comments, CommentHistory, Favorite, Bookmark
from authors.apps.profiles.serializers import ProfileListSerializer

TABLE = apps.get_model('article', 'Article')
Expand Down Expand Up @@ -243,3 +243,17 @@ class CommentHistorySerializer(serializers.ModelSerializer):
class Meta:
model = CommentHistory
fields = ('id', 'comment', 'date_created', 'original_comment')


class BookmarkSerializer(serializers.ModelSerializer):
"""Bookmark serializer class"""
class Meta:
model = Bookmark
fields = ('article', 'user')
validators = [
UniqueTogetherValidator(
queryset=Bookmark.objects.all(),
fields=('article', 'user'),
message="Article already bookmarked"
)
]
68 changes: 68 additions & 0 deletions authors/apps/article/tests/test_bookmark.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from rest_framework.reverse import reverse
from rest_framework import status

from .base_like_test import BaseLikeTest


class Bookmark(BaseLikeTest):

def bookmark_article(self, slug):
url = reverse('article:bookmark', args=[slug])
response = self.client.post(
url, format="json", HTTP_AUTHORIZATION="Bearer " + self.token)
return response

def test__user_can_bookmark(self):
"""test user can bookmark"""
response = self.bookmark_article(self.slug)
self.assertIn("True", str(response.data))
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test__user_cant_delete_bookmark_not_bookmarked(self):
"""test user cannot unbookmark before bookmarking"""
url = reverse('article:bookmark', args=[self.slug])
response = self.client.delete(
url, format="json", HTTP_AUTHORIZATION="Bearer " + self.token)
self.assertIn(
"You have not bookmarked this article yet", str(response.data))
self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)

def test__user_can_delete_bookmark(self):
"""test user can delete bookmark"""
self.bookmark_article(self.slug)
url = reverse('article:bookmark', args=[self.slug])
response = self.client.delete(
url, format="json", HTTP_AUTHORIZATION="Bearer " + self.token)
self.assertIn("unbookmarked", str(response.data))
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test__user_cant_bookmark_more_than_once(self):
"""test user cant bookmark twice"""
self.bookmark_article(self.slug)
response = self.bookmark_article(self.slug)
self.assertIn(
"Article already bookmarked", str(response.data))

def test__user_cant_bookmark_article_not_existing(self):
"""test user can bookmark"""
response = self.bookmark_article('collo-deos')
self.assertIn("That article does not exist", str(response.data))
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)

def test__user_cant_bookmark_article_with_no_authenticatin(self):
"""test user cant bookmark with no authentication"""
url = reverse('article:bookmark', args=[self.slug])
response = self.client.post(
url, format="json", HTTP_AUTHORIZATION="")
self.assertIn(
"Authentication credentials were not provided", str(response.data))
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

def test__user_cant_bookmark_article_with_no_authenticatin(self):
"""test user cant unbookmark with no authentication"""
url = reverse('article:bookmark', args=[self.slug])
response = self.client.post(
url, format="json", HTTP_AUTHORIZATION="")
self.assertIn(
"Authentication credentials were not provided", str(response.data))
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
7 changes: 6 additions & 1 deletion authors/apps/article/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
from .likes_dislike_views import (
Like,
Dislike,
FavoriteAPIView
FavoriteAPIView,
BookmarkAPIView
)

schema_view = get_swagger_view(title="Article Comments")
Expand Down Expand Up @@ -74,4 +75,8 @@
path('articles/<slug:slug>/history/<int:id>',
CommentHistoryAPIView.as_view(),
name='comment_history'),

path('articles/<slug>/bookmark/',
BookmarkAPIView.as_view(),
name="bookmark"),
]

0 comments on commit 357c836

Please sign in to comment.