Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions v2/src/ctrlfbe/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ class NoteCreateRequestBodySerializer(serializers.Serializer):
content = serializers.CharField()


class TopicUpdateRequestBodySerializer(serializers.Serializer):
title = serializers.CharField()


class NoteListQuerySerializer(serializers.Serializer):
cursor = serializers.IntegerField()

Expand All @@ -64,6 +68,11 @@ class Meta:
fields = "__all__"
read_only_fields = ["id", "created_at"]

def update(self, instance, validated_data):
instance.title = validated_data.get("title", instance.title)
instance.save()
return instance


class PageSerializer(serializers.ModelSerializer):
class Meta:
Expand Down
8 changes: 8 additions & 0 deletions v2/src/ctrlfbe/swagger.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
NoteSerializer,
PageSerializer,
TopicSerializer,
TopicUpdateRequestBodySerializer,
)

SWAGGER_PAGE_LIST_VIEW = {
Expand Down Expand Up @@ -48,6 +49,13 @@
"tags": ["디테일 화면"],
}

SWAGGER_TOPIC_UPDATE_VIEW = {
"operation_summary": "Topic Update API",
"operation_description": "topic_id에 해당하는 Topic의 제목을 수정합니다.",
"request_body": TopicUpdateRequestBodySerializer,
"tags": ["디테일 화면"],
}

SWAGGER_PAGE_DETAIL_VIEW = {
"responses": {200: PageSerializer()},
"operation_summary": "Page Detail API",
Expand Down
1 change: 1 addition & 0 deletions v2/src/ctrlfbe/topic_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
urlpatterns = [
path("<int:topic_id>/pages", PageListView.as_view(), name="page_list"),
path("<int:topic_id>", TopicDetailUpdateDeleteView.as_view(), name="topic_detail"),
path("<int:topic_id>", TopicDetailUpdateDeleteView.as_view(), name="topic_update"),
]
17 changes: 16 additions & 1 deletion v2/src/ctrlfbe/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
SWAGGER_PAGE_LIST_VIEW,
SWAGGER_TOPIC_DETAIL_VIEW,
SWAGGER_TOPIC_LIST_VIEW,
SWAGGER_TOPIC_UPDATE_VIEW,
)
from django.db.models import Model
from drf_yasg.utils import swagger_auto_schema
Expand Down Expand Up @@ -108,14 +109,28 @@ def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)


class TopicDetailUpdateDeleteView(BaseContentView):
class TopicDetailUpdateDeleteView(CtrlfAuthenticationMixin, BaseContentView):
parent_model = Topic
serializer = TopicSerializer

@swagger_auto_schema(**SWAGGER_TOPIC_DETAIL_VIEW)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)

@swagger_auto_schema(**SWAGGER_TOPIC_UPDATE_VIEW)
def put(self, request, *args, **kwargs):
ctrlf_user = self._ctrlf_authentication(request)
topic = Topic.objects.get(id=kwargs["topic_id"])

if not topic.owners.filter(id=ctrlf_user.id).exists():
return Response(data={"message": "권한이 없습니다."}, status=status.HTTP_401_UNAUTHORIZED)

serializer = TopicSerializer(topic, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()

return Response(data={"message": "수정되었습니다."}, status=status.HTTP_200_OK)


class PageListView(BaseContentView):
parent_model = Topic
Expand Down
79 changes: 79 additions & 0 deletions v2/src/tests/test_topic_update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from ctrlf_auth.models import CtrlfUser
from ctrlf_auth.serializers import LoginSerializer
from ctrlfbe.models import Note, Topic
from django.test import Client, TestCase
from django.urls import reverse
from rest_framework import status


class TestTopicUpdate(TestCase):
def setUp(self) -> None:
self.client = Client()
self.topic_owner_data = {
"email": "test@test.com",
"password": "12345",
}
self.another_user_data = {
"email": "test22@test.com",
"password": "54321",
}
self.topic_owner = CtrlfUser.objects.create_user(**self.topic_owner_data)
CtrlfUser.objects.create_user(**self.another_user_data)

def _create_topic(self, owner):
self.note = Note.objects.create(title="test note title")
self.note.owners.add(owner)
self.topic = Topic.objects.create(note=self.note, title="test topic title")
self.topic.owners.add(owner)

def _login(self, user_data):
serializer = LoginSerializer()
return serializer.validate(user_data)["token"]

def _call_api(self, request_body, token=None):
if token:
header = {"HTTP_AUTHORIZATION": f"Bearer {token}"}
else:
header = {}
return self.client.put(
reverse("topics:topic_update", kwargs={"topic_id": self.topic.id}),
data=request_body,
content_type="application/json",
**header,
)

def test_should_return_200_when_topic_owner_approve_update(self):
# Given: update topic title이 주어진다.
request_body = {"title": "update topic title"}
# And: topic을 생성한다.
self._create_topic(self.topic_owner)
# And: topic 생성한 계정으로 로그인 해서 token을 발급 받는다.
topic_owner_token = self._login(user_data=self.topic_owner_data)

# When: update topic api를 호출한다.
response = self._call_api(request_body, topic_owner_token)

# Then: status code는 200을 리턴한다.
self.assertEqual(response.status_code, status.HTTP_200_OK)
# And: message는 "수정되었습니다."를 리턴한다.
self.assertEqual(response.data["message"], "수정되었습니다.")
# And: 기존 topic의 title은 "update topic title"로 변경된다.
self.assertEqual(Topic.objects.get(id=1).title, "update topic title")

def test_should_return_401_when_another_user_approve_update(self):
# Given: update topic title이 주어진다
request_body = {"title": "update topic title"}
# And: topic을 생성한다.
self._create_topic(self.topic_owner)
# And: topic을 생성한 계정과 다른 계정으로 로그인하여 token을 발급받는다.
another_user_token = self._login(user_data=self.another_user_data)

# When: update topic api를 호출한다.
response = self._call_api(request_body, another_user_token)

# Then: status code는 401을 리턴한다.
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
# And: message는 "권한이 없습니다."를 리턴한다.
self.assertEqual(response.data["message"], "권한이 없습니다.")
# And: 기존 topic title은 그대로 "test topic title"이다.
self.assertEqual(Topic.objects.get(id=1).title, "test topic title")