diff --git a/django_girls_tutorial/step2/jinho/djangogirls/blog/api/urls.py b/django_girls_tutorial/step2/jinho/djangogirls/blog/api/urls.py index 0cb200f..08a0e32 100644 --- a/django_girls_tutorial/step2/jinho/djangogirls/blog/api/urls.py +++ b/django_girls_tutorial/step2/jinho/djangogirls/blog/api/urls.py @@ -7,4 +7,5 @@ path("posts/", views.retrieve_post_detail, name="retrieve_post_detail"), path("posts/create", views.create_post, name="create_post"), path("posts//put/update", views.update_post_with_put, name="update_post_with_put"), + path("posts//remove", views.remove_post_with_delete, name="remove_post_with_delete"), ] diff --git a/django_girls_tutorial/step2/jinho/djangogirls/blog/api/views.py b/django_girls_tutorial/step2/jinho/djangogirls/blog/api/views.py index 015c98b..6ab6cec 100644 --- a/django_girls_tutorial/step2/jinho/djangogirls/blog/api/views.py +++ b/django_girls_tutorial/step2/jinho/djangogirls/blog/api/views.py @@ -1,8 +1,7 @@ import json -from http.client import NOT_FOUND, OK +from http.client import NOT_FOUND, OK, FORBIDDEN, NO_CONTENT -from django.contrib.auth.models import User -from django.http import JsonResponse, QueryDict +from django.http import JsonResponse from django.utils import timezone from django.views.decorators.http import require_http_methods @@ -87,3 +86,18 @@ def update_post_with_put(request, id): FYI, request.body 활용 """ + + +@require_http_methods(["DELETE"]) +def remove_post_with_delete(request, id): + body = json.loads(request.body) + try: + to_delete_post = Post.objects.get(id=id) + except Post.DoesNotExist: + return JsonResponse({"message": "post를 찾을 수 없습니다."}, status=NOT_FOUND) + + if body["author"] != to_delete_post.author_id: + return JsonResponse({"message": "권한이 없습니다."}, status=FORBIDDEN) + + to_delete_post.delete() + return JsonResponse(status=NO_CONTENT) diff --git a/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py b/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py index 7f7579f..4a67073 100644 --- a/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py +++ b/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py @@ -1,5 +1,5 @@ import json -from http.client import NOT_FOUND, OK +from http.client import NOT_FOUND, OK, NO_CONTENT, FORBIDDEN from django.contrib.auth.models import User from django.test import TestCase @@ -172,4 +172,58 @@ def test_post_update_with_error_with_post_on_404(self): self.assertEqual(post.text, "test text") response = json.loads(response.content) # And: 응답 메세지로 post를 찾을 수 없습니다. 를 리턴 해야 한다. - self.assertEqual(response["message"], "post를 찾을 수 없습니다.") \ No newline at end of file + self.assertEqual(response["message"], "post를 찾을 수 없습니다.") + +class TestPostRemove(TestPostMixin, TestCase): + def setUp(self): + super().setUp() + self.post = Post.objects.create(author=self.author, title="test title", text="test text") + + def test_post_remove_with_delete(self): + # Given: 삭제하기 위한 author를 담은 request_body를 생성 + request_body = json.dumps({"author": self.author.id}) + + # When: 1번 post에 대한 remove API를 호출한다. + response = self.client.delete(reverse("remove_post_with_delete", kwargs={"id": self.post.id}), + data=request_body) + + # Then: 상태코드는 204이고, + self.assertEqual(response.status_code, NO_CONTENT) + # And: 실제 post는 삭제된다. + self.assertEqual(Post.objects.all().count(), 0) + + def test_post_remove_with_error_about_post(self): + # Given: 유효하지 않은 post_id와 유효한 author를 생성 + request_body = json.dumps({"author": self.author.id}) + invalid_post_id = 837994 + + # When: 유효하지않은 post에 대한 remove API를 호출한다. + response = self.client.delete(reverse("remove_post_with_delete", kwargs={"id": invalid_post_id}), + data=request_body) + + # Then: 상태코드는 404이고, + self.assertEqual(response.status_code, 404) + # And: 실제 post는 삭제되지 않는다. + self.assertEqual(Post.objects.all().count(), 1) + + # And: 응답 메세지로 post를 찾을 수 없습니다. 를 리턴한다. + response = json.loads(response.content) + self.assertEqual(response["message"], "post를 찾을 수 없습니다.") + + def test_post_remove_with_error_about_author(self): + # Given: 유효하지 않은 author 생성 + invalid_author_id = 12314 + request_body = json.dumps({"author": invalid_author_id}) + + # When: 1번 post에 대한 remove API를 호출한다. + response = self.client.delete(reverse("remove_post_with_delete", kwargs={"id": self.post.id}), + data=request_body) + + # Then: 상태코드는 403이고, + self.assertEqual(response.status_code, FORBIDDEN) + # And: 실제 post는 삭제되지 않는다. + self.assertEqual(Post.objects.all().count(), 1) + + # And: 응답 메세지로 권한이 없습니다. 를 리턴한다. + response = json.loads(response.content) + self.assertEqual(response["message"], "권한이 없습니다.")