diff --git a/config/urls.py b/config/urls.py index 56ee833..36e5ba4 100644 --- a/config/urls.py +++ b/config/urls.py @@ -27,6 +27,8 @@ path("api/common/", include("common.urls")), # Swagger path("swagger/docs/", schema_view.with_ui("swagger", cache_timeout=0), name="schema-swagger-ui"), + # Likes + path("api/likes/", include("likes.urls")), ] urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/likes/serializers.py b/likes/serializers.py new file mode 100644 index 0000000..14f2d7b --- /dev/null +++ b/likes/serializers.py @@ -0,0 +1,9 @@ +from rest_framework.serializers import ModelSerializer + +from posts.models import Post + + +class PostLikeIncrementSerializer(ModelSerializer): + class Meta: + model = Post + fields = ("like_count",) diff --git a/likes/tests.py b/likes/tests.py index a39b155..cab7496 100644 --- a/likes/tests.py +++ b/likes/tests.py @@ -1 +1,49 @@ -# Create your tests here. +from django.urls import reverse +from rest_framework.test import APIClient, APITestCase + +from posts.models import Post +from users.models import User + + +class LikeAPITestCase(APITestCase): + client = APIClient(enforce_csrf_checks=True) + viewname = "likes" + + def setUp(self): + self.user = User.objects.create(email="user") + + self.post = Post.objects.create(title="title", post_type="facebook", content="content") + + def test_post_without_auth(self): + """logout and post like""" + + self.client.logout() + + response = self.client.post( + path=reverse( + viewname=self.viewname, + kwargs={ + "content_id": self.post.content_id, + }, + ), + ) + + self.assertEqual(response.status_code, 401) + + def test_post_with_auth(self): + """login and post like""" + + # self.client.force_login(self.user) + self.client.force_authenticate(user=self.user) + + response = self.client.post( + path=reverse( + viewname=self.viewname, + kwargs={ + "content_id": self.post.content_id, + }, + ), + ) + + self.assertEqual(response.status_code, 200) + self.assertEqual(self.post.like_count, Post.objects.first().like_count - 1) diff --git a/likes/urls.py b/likes/urls.py new file mode 100644 index 0000000..69c972d --- /dev/null +++ b/likes/urls.py @@ -0,0 +1,7 @@ +from django.urls import path + +from likes import views + +urlpatterns = [ + path("/", views.LikesAPIView.as_view(), name="likes"), +] diff --git a/likes/views.py b/likes/views.py index 60f00ef..18492c2 100644 --- a/likes/views.py +++ b/likes/views.py @@ -1 +1,35 @@ -# Create your views here. +from django.shortcuts import get_object_or_404 +from drf_yasg import openapi +from drf_yasg.utils import swagger_auto_schema +from rest_framework.permissions import IsAuthenticatedOrReadOnly +from rest_framework.response import Response +from rest_framework.status import HTTP_200_OK, HTTP_401_UNAUTHORIZED +from rest_framework.views import APIView + +from likes.serializers import PostLikeIncrementSerializer +from posts.models import Post + + +class LikesAPIView(APIView): + permission_classes = [IsAuthenticatedOrReadOnly] + + @swagger_auto_schema( + operation_summary="게시물에 좋아요", + responses={ + HTTP_200_OK: openapi.Response(description="ok"), + HTTP_401_UNAUTHORIZED: openapi.Response(description="unauthorized"), + }, + ) + def post(self, request, content_id): + post = get_object_or_404(Post, content_id=content_id) + + serializer = PostLikeIncrementSerializer( + post, + data={"like_count": post.like_count + 1}, + partial=True, + ) + + serializer.is_valid(raise_exception=True) + serializer.save() + + return Response(status=200) diff --git a/posts/migrations/0002_post_content_id.py b/posts/migrations/0002_post_content_id.py index af399f1..bd36b80 100644 --- a/posts/migrations/0002_post_content_id.py +++ b/posts/migrations/0002_post_content_id.py @@ -1,5 +1,7 @@ # Generated by Django 4.2.6 on 2023-10-27 23:19 + + from django.db import migrations, models import uuid