From 8f985587b44834b8f04121151f6fd0b3630a1e1e Mon Sep 17 00:00:00 2001 From: JinHoooooou Date: Tue, 6 Jul 2021 16:32:30 +0900 Subject: [PATCH 01/10] add post_remove_with_delete test --- .../step2/jinho/djangogirls/blog/tests.py | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py b/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py index 7f7579f..2fc2062 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, UNAUTHORIZED from django.contrib.auth.models import User from django.test import TestCase @@ -172,4 +172,28 @@ 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: 상태코드는 200이고, + self.assertEqual(response.status_code, 200) + # And: 실제 post는 삭제된다. + self.assertEqual(Post.objects.all().count(), 0) + + # And: 응답 값에서 삭제한 post의 title, text를 리턴한다. + response = json.loads(response.content)["post"] + self.assertEqual(response["title"], "test title") + self.assertEqual(response["text"], "test text") + From 2c51369a50d7d710d1aa9fa757b3004e164ddcf0 Mon Sep 17 00:00:00 2001 From: JinHoooooou Date: Tue, 6 Jul 2021 16:34:55 +0900 Subject: [PATCH 02/10] add remove post url --- django_girls_tutorial/step2/jinho/djangogirls/blog/api/urls.py | 1 + 1 file changed, 1 insertion(+) 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"), ] From ec4ac0f5b1ebbc7cef3e7c3a29a51d849b2397eb Mon Sep 17 00:00:00 2001 From: JinHoooooou Date: Tue, 6 Jul 2021 16:50:29 +0900 Subject: [PATCH 03/10] add post_remove_with_error_about_post test --- .../step2/jinho/djangogirls/blog/tests.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py b/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py index 2fc2062..02f4762 100644 --- a/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py +++ b/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py @@ -197,3 +197,21 @@ def test_post_remove_with_delete(self): self.assertEqual(response["title"], "test title") self.assertEqual(response["text"], "test text") + 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를 찾을 수 없습니다.") + From f1766cfffae8375acdfe3cdbbc38dc77a30a9cf9 Mon Sep 17 00:00:00 2001 From: JinHoooooou Date: Tue, 6 Jul 2021 16:53:08 +0900 Subject: [PATCH 04/10] add post_remove_with_error_about_author test --- .../step2/jinho/djangogirls/blog/tests.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py b/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py index 02f4762..dfc11b2 100644 --- a/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py +++ b/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py @@ -215,3 +215,19 @@ def test_post_remove_with_error_about_post(self): response = json.loads(response.content) self.assertEqual(response["message"], "post를 찾을 수 없습니다.") + def test_post_remove_with_error_about_author(self): + # Given: 유효하지 않은 author 생성 + request_body = json.dumps({"author": 12314}) + + # When: 1번 post에 대한 remove API를 호출한다. + response = self.client.delete(reverse("remove_post_with_delete", kwargs={"id": self.post.id}), + data=request_body) + + # Then: 상태코드는 401이고, + self.assertEqual(response.status_code, UNAUTHORIZED) + # And: 실제 post는 삭제되지 않는다. + self.assertEqual(Post.objects.all().count(), 1) + + # And: 응답 메세지로 권한이 없습니다. 를 리턴한다. + response = json.loads(response.content) + self.assertEqual(response["message"], "권한이 없습니다.") From abe283c59c28ac8e60550c01c9e2a449b856f657 Mon Sep 17 00:00:00 2001 From: JinHoooooou Date: Tue, 6 Jul 2021 18:10:14 +0900 Subject: [PATCH 05/10] add remove_post method --- .../step2/jinho/djangogirls/blog/api/views.py | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) 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..437c3cd 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, UNAUTHORIZED -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,25 @@ 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) + posts = Post.objects.filter(id=id) + if len(posts) == 0: + return JsonResponse({"message": "post를 찾을 수 없습니다."}, status=NOT_FOUND) + + to_delete_post = posts[0] + if body["author"] != posts[0].author_id: + return JsonResponse({"message": "권한이 없습니다."}, status=UNAUTHORIZED) + + to_delete_post.delete() + return JsonResponse( + { + "post": + { + "title": to_delete_post.title, + "text": to_delete_post.text, + } + }, status=OK) From ae633e20b31d7d88640920e6acf0044404a35f3a Mon Sep 17 00:00:00 2001 From: JinHoooooou Date: Tue, 6 Jul 2021 18:29:22 +0900 Subject: [PATCH 06/10] modify remove_post_with_delete method --- .../step2/jinho/djangogirls/blog/api/views.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 437c3cd..1d8983f 100644 --- a/django_girls_tutorial/step2/jinho/djangogirls/blog/api/views.py +++ b/django_girls_tutorial/step2/jinho/djangogirls/blog/api/views.py @@ -91,12 +91,12 @@ def update_post_with_put(request, id): @require_http_methods(["DELETE"]) def remove_post_with_delete(request, id): body = json.loads(request.body) - posts = Post.objects.filter(id=id) - if len(posts) == 0: + try: + to_delete_post = Post.objects.get(id=id) + except Post.DoesNotExist: return JsonResponse({"message": "post를 찾을 수 없습니다."}, status=NOT_FOUND) - to_delete_post = posts[0] - if body["author"] != posts[0].author_id: + if body["author"] != to_delete_post.author_id: return JsonResponse({"message": "권한이 없습니다."}, status=UNAUTHORIZED) to_delete_post.delete() From 94686d409b2ab9cc88c56cc79a3a2dee510796ea Mon Sep 17 00:00:00 2001 From: JinHoooooou Date: Sun, 11 Jul 2021 15:22:27 +0900 Subject: [PATCH 07/10] modify to send only status (NO_CONTENT) when removing post successed --- .../step2/jinho/djangogirls/blog/api/views.py | 11 ++--------- .../step2/jinho/djangogirls/blog/tests.py | 11 +++-------- 2 files changed, 5 insertions(+), 17 deletions(-) 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 1d8983f..636bc67 100644 --- a/django_girls_tutorial/step2/jinho/djangogirls/blog/api/views.py +++ b/django_girls_tutorial/step2/jinho/djangogirls/blog/api/views.py @@ -1,5 +1,5 @@ import json -from http.client import NOT_FOUND, OK, UNAUTHORIZED +from http.client import NOT_FOUND, OK, FORBIDDEN, NO_CONTENT from django.http import JsonResponse from django.utils import timezone @@ -100,11 +100,4 @@ def remove_post_with_delete(request, id): return JsonResponse({"message": "권한이 없습니다."}, status=UNAUTHORIZED) to_delete_post.delete() - return JsonResponse( - { - "post": - { - "title": to_delete_post.title, - "text": to_delete_post.text, - } - }, status=OK) + 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 dfc11b2..8a9cc4f 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, UNAUTHORIZED +from http.client import NOT_FOUND, OK, NO_CONTENT, FORBIDDEN from django.contrib.auth.models import User from django.test import TestCase @@ -187,16 +187,11 @@ def test_post_remove_with_delete(self): response = self.client.delete(reverse("remove_post_with_delete", kwargs={"id": self.post.id}), data=request_body) - # Then: 상태코드는 200이고, - self.assertEqual(response.status_code, 200) + # Then: 상태코드는 204이고, + self.assertEqual(response.status_code, NO_CONTENT) # And: 실제 post는 삭제된다. self.assertEqual(Post.objects.all().count(), 0) - # And: 응답 값에서 삭제한 post의 title, text를 리턴한다. - response = json.loads(response.content)["post"] - self.assertEqual(response["title"], "test title") - self.assertEqual(response["text"], "test text") - def test_post_remove_with_error_about_post(self): # Given: 유효하지 않은 post_id와 유효한 author를 생성 request_body = json.dumps({"author": self.author.id}) From 8e7b813a8ee4ba56786016d0b585f89c4a026450 Mon Sep 17 00:00:00 2001 From: JinHoooooou Date: Sun, 11 Jul 2021 15:24:12 +0900 Subject: [PATCH 08/10] modify error status UNAUTHORIZED to FORBIDDEN --- .../step2/jinho/djangogirls/blog/api/views.py | 2 +- .../step2/jinho/djangogirls/blog/tests.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) 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 636bc67..6ab6cec 100644 --- a/django_girls_tutorial/step2/jinho/djangogirls/blog/api/views.py +++ b/django_girls_tutorial/step2/jinho/djangogirls/blog/api/views.py @@ -97,7 +97,7 @@ def remove_post_with_delete(request, id): return JsonResponse({"message": "post를 찾을 수 없습니다."}, status=NOT_FOUND) if body["author"] != to_delete_post.author_id: - return JsonResponse({"message": "권한이 없습니다."}, status=UNAUTHORIZED) + 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 8a9cc4f..4a67073 100644 --- a/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py +++ b/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py @@ -212,14 +212,15 @@ def test_post_remove_with_error_about_post(self): def test_post_remove_with_error_about_author(self): # Given: 유효하지 않은 author 생성 - request_body = json.dumps({"author": 12314}) + 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: 상태코드는 401이고, - self.assertEqual(response.status_code, UNAUTHORIZED) + # Then: 상태코드는 403이고, + self.assertEqual(response.status_code, FORBIDDEN) # And: 실제 post는 삭제되지 않는다. self.assertEqual(Post.objects.all().count(), 1) From ea35b12574493053123f3ddf0daeed60be2515b2 Mon Sep 17 00:00:00 2001 From: JinHoooooou Date: Sun, 11 Jul 2021 15:33:56 +0900 Subject: [PATCH 09/10] replace magic number with constant --- django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py b/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py index 8a9cc4f..dfebc54 100644 --- a/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py +++ b/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py @@ -212,7 +212,8 @@ def test_post_remove_with_error_about_post(self): def test_post_remove_with_error_about_author(self): # Given: 유효하지 않은 author 생성 - request_body = json.dumps({"author": 12314}) + 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}), From 6db4a1124797e28ecd025d4b3781129c048c3f41 Mon Sep 17 00:00:00 2001 From: JinHoooooou Date: Sun, 11 Jul 2021 15:35:01 +0900 Subject: [PATCH 10/10] modify UNAUTHORIZED to FORBIDDEN when user input invalid author id --- django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py b/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py index dfebc54..4a67073 100644 --- a/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py +++ b/django_girls_tutorial/step2/jinho/djangogirls/blog/tests.py @@ -219,8 +219,8 @@ def test_post_remove_with_error_about_author(self): response = self.client.delete(reverse("remove_post_with_delete", kwargs={"id": self.post.id}), data=request_body) - # Then: 상태코드는 401이고, - self.assertEqual(response.status_code, UNAUTHORIZED) + # Then: 상태코드는 403이고, + self.assertEqual(response.status_code, FORBIDDEN) # And: 실제 post는 삭제되지 않는다. self.assertEqual(Post.objects.all().count(), 1)