diff --git a/src/docs/asciidoc/board.adoc b/src/docs/asciidoc/board.adoc index e77ee9e8..99e2c75b 100644 --- a/src/docs/asciidoc/board.adoc +++ b/src/docs/asciidoc/board.adoc @@ -14,9 +14,9 @@ include::{snippets}/default-board-create/http-response.adoc[] ==== 3. 소개 게시글 작성하기 ===== Request -include::{snippets}/intro-post-create/http-request.adoc[] +include::{snippets}/intro-board-create/http-request.adoc[] ===== Response -include::{snippets}/intro-post-create/http-response.adoc[] +include::{snippets}/intro-board-create/http-response.adoc[] ==== 4. 게시글 리스트 조회 ( 페이징 처리 ) ===== Request diff --git a/src/docs/asciidoc/comment.adoc b/src/docs/asciidoc/comment.adoc new file mode 100644 index 00000000..15cec666 --- /dev/null +++ b/src/docs/asciidoc/comment.adoc @@ -0,0 +1,25 @@ +== Comment API + +=== 1. 게시글에 대한 댓글 리스트 조회 +===== Request +include::{snippets}/get-comment-all/http-request.adoc[] +===== Response +include::{snippets}/get-comment-all/http-response.adoc[] + +=== 2. 댓글 작성 +===== Request +include::{snippets}/comment-create/http-request.adoc[] +===== Response +include::{snippets}/comment-create/http-response.adoc[] + +=== 3. 댓글 수정 +===== Request +include::{snippets}/comment-update/http-request.adoc[] +===== Response +include::{snippets}/comment-update/http-response.adoc[] + +=== 4. 댓글 삭제 +===== Request +include::{snippets}/comment-delete/http-request.adoc[] +===== Response +include::{snippets}/comment-delete/http-response.adoc[] \ No newline at end of file diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc index 17617ba1..27e3616c 100644 --- a/src/docs/asciidoc/index.adoc +++ b/src/docs/asciidoc/index.adoc @@ -18,7 +18,8 @@ endif::[] 제작 <5do2chonri@gmail.com> + 제작일 2023-03-23 + -*해당 문서는 주말의 집을 제작하는 오도리 팀에게 있으며, 무단 배포/변형을 금지합니다.* +*해당 문서의 저작권은 주말의 집을 제작하는 오도리 팀에게 있으며, 무단 배포/변형을 금지합니다.* include::user.adoc[] include::board.adoc[] +include::comment.adoc[] \ No newline at end of file diff --git a/src/main/kotlin/com/example/jhouse_server/domain/comment/controller/CommentController.kt b/src/main/kotlin/com/example/jhouse_server/domain/comment/controller/CommentController.kt index 6b96c23e..f1c15e1c 100644 --- a/src/main/kotlin/com/example/jhouse_server/domain/comment/controller/CommentController.kt +++ b/src/main/kotlin/com/example/jhouse_server/domain/comment/controller/CommentController.kt @@ -1,21 +1,14 @@ package com.example.jhouse_server.domain.comment.controller // ktlint-disable package-name -import com.example.jhouse_server.domain.comment.dto.CommentCreateReqDto +import com.example.jhouse_server.domain.comment.dto.CommentReqDto import com.example.jhouse_server.domain.comment.dto.CommentResDto -import com.example.jhouse_server.domain.comment.dto.CommentUpdateReqDto import com.example.jhouse_server.domain.comment.service.CommentService import com.example.jhouse_server.domain.user.entity.User +import com.example.jhouse_server.global.annotation.Auth import com.example.jhouse_server.global.annotation.AuthUser import com.example.jhouse_server.global.response.ApplicationResponse import org.springframework.validation.annotation.Validated -import org.springframework.web.bind.annotation.DeleteMapping -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.PostMapping -import org.springframework.web.bind.annotation.PutMapping -import org.springframework.web.bind.annotation.RequestBody -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController +import org.springframework.web.bind.annotation.* @RestController @RequestMapping("/api/v1/comments") @@ -30,24 +23,27 @@ class CommentController( return ApplicationResponse.ok(commentService.getCommentAll(boardId)) } + @Auth @PostMapping fun createComment( - @RequestBody @Validated req: CommentCreateReqDto, + @RequestBody @Validated req: CommentReqDto, @AuthUser user: User ): ApplicationResponse { return ApplicationResponse.ok(commentService.createComment(req, user)) } + @Auth @PutMapping("/{commentId}") fun updateComment( @PathVariable commentId: Long, - @RequestBody @Validated req: CommentUpdateReqDto, + @RequestBody @Validated req: CommentReqDto, @AuthUser user: User ): ApplicationResponse { return ApplicationResponse.ok(commentService.updateComment(commentId, req, user)) } - @DeleteMapping("{/commentId}") + @Auth + @DeleteMapping("/{commentId}") fun deleteComment( @PathVariable commentId: Long, @AuthUser user: User diff --git a/src/main/kotlin/com/example/jhouse_server/domain/comment/dto/CommentResDto.kt b/src/main/kotlin/com/example/jhouse_server/domain/comment/dto/CommentResDto.kt index e7367427..c738a9d6 100644 --- a/src/main/kotlin/com/example/jhouse_server/domain/comment/dto/CommentResDto.kt +++ b/src/main/kotlin/com/example/jhouse_server/domain/comment/dto/CommentResDto.kt @@ -2,7 +2,6 @@ package com.example.jhouse_server.domain.comment.dto import com.example.jhouse_server.domain.comment.entity.Comment import java.time.format.DateTimeFormatter -import javax.validation.constraints.NotBlank import javax.validation.constraints.NotNull data class CommentResDto( @@ -12,7 +11,7 @@ data class CommentResDto( val createdAt: String, ) -data class CommentCreateReqDto( +data class CommentReqDto( @field:NotNull(message = "게시글ID 필수값입니다.") val boardId: Long? = null, @field:NotNull(message = "댓글 내용은 필수값입니다.") diff --git a/src/main/kotlin/com/example/jhouse_server/domain/comment/service/CommentService.kt b/src/main/kotlin/com/example/jhouse_server/domain/comment/service/CommentService.kt index 4906158e..87b00758 100644 --- a/src/main/kotlin/com/example/jhouse_server/domain/comment/service/CommentService.kt +++ b/src/main/kotlin/com/example/jhouse_server/domain/comment/service/CommentService.kt @@ -1,6 +1,6 @@ package com.example.jhouse_server.domain.comment.service -import com.example.jhouse_server.domain.comment.dto.CommentCreateReqDto +import com.example.jhouse_server.domain.comment.dto.CommentReqDto import com.example.jhouse_server.domain.comment.dto.CommentResDto import com.example.jhouse_server.domain.comment.dto.CommentUpdateReqDto import com.example.jhouse_server.domain.user.entity.User @@ -9,8 +9,8 @@ interface CommentService { fun getCommentAll(postId : Long) : List - fun createComment(req: CommentCreateReqDto, user: User) : Long + fun createComment(req: CommentReqDto, user: User) : Long - fun updateComment(commentId: Long, req: CommentUpdateReqDto, user: User) : Long + fun updateComment(commentId: Long, req: CommentReqDto, user: User) : Long fun deleteComment(commentId: Long, user: User) } \ No newline at end of file diff --git a/src/main/kotlin/com/example/jhouse_server/domain/comment/service/CommentServiceImpl.kt b/src/main/kotlin/com/example/jhouse_server/domain/comment/service/CommentServiceImpl.kt index 3b07a9b0..99a46e80 100644 --- a/src/main/kotlin/com/example/jhouse_server/domain/comment/service/CommentServiceImpl.kt +++ b/src/main/kotlin/com/example/jhouse_server/domain/comment/service/CommentServiceImpl.kt @@ -1,7 +1,7 @@ package com.example.jhouse_server.domain.comment.service import com.example.jhouse_server.domain.board.repository.BoardRepository -import com.example.jhouse_server.domain.comment.dto.CommentCreateReqDto +import com.example.jhouse_server.domain.comment.dto.CommentReqDto import com.example.jhouse_server.domain.comment.dto.CommentResDto import com.example.jhouse_server.domain.comment.dto.CommentUpdateReqDto import com.example.jhouse_server.domain.comment.dto.toDto @@ -25,7 +25,7 @@ class CommentServiceImpl( } @Transactional - override fun createComment(req: CommentCreateReqDto, user: User): Long { + override fun createComment(req: CommentReqDto, user: User): Long { val board = boardRepository.findByIdOrThrow(req.boardId) val comment = Comment( board, req.content!!, user @@ -34,7 +34,7 @@ class CommentServiceImpl( } @Transactional - override fun updateComment(commentId: Long, req: CommentUpdateReqDto, user: User): Long { + override fun updateComment(commentId: Long, req: CommentReqDto, user: User): Long { val comment = commentRepository.findByIdOrThrow(commentId) return if (user == comment.user) { comment.updateEntity(req.content!!).id diff --git a/src/main/resources/static/docs/board.html b/src/main/resources/static/docs/board.html index 7bb04ebb..059bfe73 100644 --- a/src/main/resources/static/docs/board.html +++ b/src/main/resources/static/docs/board.html @@ -451,7 +451,7 @@
Request
POST /api/v1/boards HTTP/1.1
 Content-Type: application/json;charset=UTF-8
-Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0X2pob3VzZV9jb20iLCJleHAiOjE2Nzk1MDQ5MDAsImF1dGgiOiJVU0VSIn0.ikNbrtvUVdD2Tl_Gg_WbsI81drZ2Tl2M4kCg9HEB41kdTP4KpbJkT9JgoJtrAtZV0rfYn44X1mcGz08d3SM6bQ
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0X2pob3VzZV9jb20iLCJleHAiOjE2Nzk1NTE0MjQsImF1dGgiOiJVU0VSIn0.ka4Labm-4PYe1i85mxhL1NG5LocGBOkjf0X69MvHtZoWrodh4UwVPovAp60dA75F6plekEJim-62DPxey1e7jA
 Accept: application/json
 Content-Length: 334
 Host: localhost:8080
@@ -478,12 +478,12 @@ 

Response

Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 63 +Content-Length: 64 { "code" : "SUCCESS", "message" : "성공", - "data" : 66 + "data" : 298 }
@@ -496,7 +496,7 @@
Request
POST /api/v1/boards HTTP/1.1
 Content-Type: application/json;charset=UTF-8
-Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0X2pob3VzZV9jb20iLCJleHAiOjE2Nzk1MDQ5MDAsImF1dGgiOiJVU0VSIn0.ikNbrtvUVdD2Tl_Gg_WbsI81drZ2Tl2M4kCg9HEB41kdTP4KpbJkT9JgoJtrAtZV0rfYn44X1mcGz08d3SM6bQ
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0X2pob3VzZV9jb20iLCJleHAiOjE2Nzk1NTE0MjQsImF1dGgiOiJVU0VSIn0.ka4Labm-4PYe1i85mxhL1NG5LocGBOkjf0X69MvHtZoWrodh4UwVPovAp60dA75F6plekEJim-62DPxey1e7jA
 Accept: application/json
 Content-Length: 330
 Host: localhost:8080
@@ -522,12 +522,12 @@ 
Response
Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 63 +Content-Length: 64 { "code" : "SUCCESS", "message" : "성공", - "data" : 64 + "data" : 296 }
@@ -541,7 +541,7 @@
Request
POST /api/v1/boards HTTP/1.1
 Content-Type: application/json;charset=UTF-8
-Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0X2pob3VzZV9jb20iLCJleHAiOjE2Nzk1MDQ4OTksImF1dGgiOiJVU0VSIn0.n-vaQmLOo6uU4eXAYL8PnOYrJQra9a7TRFPBBoq-c0zcvxnlDlQE8_sK_a1o8os96pGE7uyeOjDN2rjbPCVJlA
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0X2pob3VzZV9jb20iLCJleHAiOjE2Nzk1NTE0MjQsImF1dGgiOiJVU0VSIn0.ka4Labm-4PYe1i85mxhL1NG5LocGBOkjf0X69MvHtZoWrodh4UwVPovAp60dA75F6plekEJim-62DPxey1e7jA
 Accept: application/json
 Content-Length: 335
 Host: localhost:8080
@@ -567,12 +567,12 @@ 
Response
Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 63 +Content-Length: 64 { "code" : "SUCCESS", "message" : "성공", - "data" : 59 + "data" : 291 }
@@ -599,14 +599,14 @@
Response
Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 975 +Content-Length: 976 { "code" : "SUCCESS", "message" : "성공", "data" : { "content" : [ { - "boardId" : 60, + "boardId" : 292, "title" : "짱구는 못말려", "code" : "<body> <div> <h2>짱구는 못말려</h2> </div> <div> <i>철수</i>야 나랑 놀자 </div> </body>", "oneLineContent" : "짱구는 못말려철수야 나랑 놀자", @@ -618,26 +618,26 @@
Response
"pageable" : { "sort" : { "empty" : true, - "sorted" : false, - "unsorted" : true + "unsorted" : true, + "sorted" : false }, "offset" : 0, - "pageSize" : 20, "pageNumber" : 0, + "pageSize" : 20, "paged" : true, "unpaged" : false }, "last" : true, "totalPages" : 1, "totalElements" : 1, - "number" : 0, + "size" : 20, "sort" : { "empty" : true, - "sorted" : false, - "unsorted" : true + "unsorted" : true, + "sorted" : false }, - "size" : 20, "first" : true, + "number" : 0, "numberOfElements" : 1, "empty" : false } @@ -652,7 +652,7 @@

5. 게시글 상세 조회

Request
-
GET /api/v1/boards/61 HTTP/1.1
+
GET /api/v1/boards/293 HTTP/1.1
 Accept: application/json
 Host: localhost:8080
@@ -667,13 +667,13 @@
Response
Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 407 +Content-Length: 408 { "code" : "SUCCESS", "message" : "성공", "data" : { - "boardId" : 61, + "boardId" : 293, "title" : "짱구는 못말려", "code" : "<body> <div> <h2>짱구는 못말려</h2> </div> <div> <i>철수</i>야 나랑 놀자 </div> </body>", "nickName" : "테스트유저1", @@ -694,9 +694,9 @@

6. 게시글 수정

Request
-
PUT /api/v1/boards/62 HTTP/1.1
+
PUT /api/v1/boards/294 HTTP/1.1
 Content-Type: application/json;charset=UTF-8
-Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0X2pob3VzZV9jb20iLCJleHAiOjE2Nzk1MDQ5MDAsImF1dGgiOiJVU0VSIn0.ikNbrtvUVdD2Tl_Gg_WbsI81drZ2Tl2M4kCg9HEB41kdTP4KpbJkT9JgoJtrAtZV0rfYn44X1mcGz08d3SM6bQ
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0X2pob3VzZV9jb20iLCJleHAiOjE2Nzk1NTE0MjQsImF1dGgiOiJVU0VSIn0.ka4Labm-4PYe1i85mxhL1NG5LocGBOkjf0X69MvHtZoWrodh4UwVPovAp60dA75F6plekEJim-62DPxey1e7jA
 Accept: application/json
 Content-Length: 273
 Host: localhost:8080
@@ -722,12 +722,12 @@ 
Response
Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 63 +Content-Length: 64 { "code" : "SUCCESS", "message" : "성공", - "data" : 62 + "data" : 294 }
@@ -739,8 +739,8 @@

7. 게시글 삭제

Request
-
DELETE /api/v1/boards/57 HTTP/1.1
-Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0X2pob3VzZV9jb20iLCJleHAiOjE2Nzk1MDQ4OTksImF1dGgiOiJVU0VSIn0.n-vaQmLOo6uU4eXAYL8PnOYrJQra9a7TRFPBBoq-c0zcvxnlDlQE8_sK_a1o8os96pGE7uyeOjDN2rjbPCVJlA
+
DELETE /api/v1/boards/289 HTTP/1.1
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0X2pob3VzZV9jb20iLCJleHAiOjE2Nzk1NTE0MjMsImF1dGgiOiJVU0VSIn0.NmxPUDZxF4-QkYCMKVD6JT3K2rzPxZgJEwb_3s1ix_UdcGxz46ygqq4FNTawZCD50ZJ6MMwklIzE0nCEJoya5A
 Host: localhost:8080
@@ -808,7 +808,7 @@
Response
diff --git a/src/main/resources/static/docs/comment.html b/src/main/resources/static/docs/comment.html new file mode 100644 index 00000000..b250c966 --- /dev/null +++ b/src/main/resources/static/docs/comment.html @@ -0,0 +1,604 @@ + + + + + + + +Comment API + + + + + +
+
+

Comment API

+
+
+

1. 게시글에 대한 댓글 리스트 조회

+
+
Request
+
+
+
GET /api/v1/comments/334 HTTP/1.1
+Accept: application/json
+Host: localhost:8080
+
+
+
+
+
Response
+
+
+
HTTP/1.1 200 OK
+Vary: Origin
+Vary: Access-Control-Request-Method
+Vary: Access-Control-Request-Headers
+Content-Type: application/json;charset=UTF-8
+Content-Length: 198
+
+{
+  "code" : "SUCCESS",
+  "message" : "성공",
+  "data" : [ {
+    "commentId" : 1235,
+    "nickName" : "테스트유저1",
+    "content" : "댓글이란다.",
+    "createdAt" : "2023-03-23"
+  } ]
+}
+
+
+
+
+
+

2. 댓글 작성

+
+
Request
+
+
+
POST /api/v1/comments HTTP/1.1
+Content-Type: application/json;charset=UTF-8
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0X2pob3VzZV9jb20iLCJleHAiOjE2Nzk1NTE0MjYsImF1dGgiOiJVU0VSIn0.GfWdM7_cSTHBISTFfcZdq-6ijU0SDLi7jqwiXwk7CGrMKPtfRNxwrHakuaofgV6eHVygu3ooN5KwVqhZ_46sdw
+Accept: application/json
+Content-Length: 64
+Host: localhost:8080
+
+{
+  "boardId" : 336,
+  "content" : "짱구야, 공부 하자."
+}
+
+
+
+
+
Response
+
+
+
HTTP/1.1 200 OK
+Vary: Origin
+Vary: Access-Control-Request-Method
+Vary: Access-Control-Request-Headers
+Content-Type: application/json;charset=UTF-8
+Content-Length: 65
+
+{
+  "code" : "SUCCESS",
+  "message" : "성공",
+  "data" : 1246
+}
+
+
+
+
+
+

3. 댓글 수정

+
+
Request
+
+
+
PUT /api/v1/comments/1239 HTTP/1.1
+Content-Type: application/json;charset=UTF-8
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0X2pob3VzZV9jb20iLCJleHAiOjE2Nzk1NTE0MjYsImF1dGgiOiJVU0VSIn0.GfWdM7_cSTHBISTFfcZdq-6ijU0SDLi7jqwiXwk7CGrMKPtfRNxwrHakuaofgV6eHVygu3ooN5KwVqhZ_46sdw
+Accept: application/json
+Content-Length: 64
+Host: localhost:8080
+
+{
+  "boardId" : 335,
+  "content" : "짱구야, 공부 하자."
+}
+
+
+
+
+
Response
+
+
+
HTTP/1.1 200 OK
+Vary: Origin
+Vary: Access-Control-Request-Method
+Vary: Access-Control-Request-Headers
+Content-Type: application/json;charset=UTF-8
+Content-Length: 65
+
+{
+  "code" : "SUCCESS",
+  "message" : "성공",
+  "data" : 1239
+}
+
+
+
+
+
+

4. 댓글 삭제

+
+
Request
+
+
+
DELETE /api/v1/comments/1250 HTTP/1.1
+Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0X2pob3VzZV9jb20iLCJleHAiOjE2Nzk1NTE0MjYsImF1dGgiOiJVU0VSIn0.GfWdM7_cSTHBISTFfcZdq-6ijU0SDLi7jqwiXwk7CGrMKPtfRNxwrHakuaofgV6eHVygu3ooN5KwVqhZ_46sdw
+Host: localhost:8080
+
+
+
+
+
Response
+
+
+
HTTP/1.1 200 OK
+Vary: Origin
+Vary: Access-Control-Request-Method
+Vary: Access-Control-Request-Headers
+Content-Type: application/json;charset=UTF-8
+Content-Length: 48
+
+{
+  "code" : "SUCCESS",
+  "message" : "성공"
+}
+
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/src/test/kotlin/com/example/jhouse_server/domain/board/controller/BoardControllerTest.kt b/src/test/kotlin/com/example/jhouse_server/domain/board/controller/BoardControllerTest.kt index 0518938c..bf38510a 100644 --- a/src/test/kotlin/com/example/jhouse_server/domain/board/controller/BoardControllerTest.kt +++ b/src/test/kotlin/com/example/jhouse_server/domain/board/controller/BoardControllerTest.kt @@ -243,7 +243,7 @@ internal class BoardControllerTest @Autowired constructor( .andDo(print()) .andDo( document( - "intro-post-create", + "intro-board-create", requestFields(*createRequestFieldSnippet()), responseFields( fieldWithPath("code").description("결과 코드"), diff --git a/src/test/kotlin/com/example/jhouse_server/domain/comment/controller/CommentControllerTest.kt b/src/test/kotlin/com/example/jhouse_server/domain/comment/controller/CommentControllerTest.kt new file mode 100644 index 00000000..57f14adf --- /dev/null +++ b/src/test/kotlin/com/example/jhouse_server/domain/comment/controller/CommentControllerTest.kt @@ -0,0 +1,179 @@ +package com.example.jhouse_server.domain.comment.controller + +import com.example.jhouse_server.domain.board.repository.BoardRepository +import com.example.jhouse_server.domain.board.service.BoardService +import com.example.jhouse_server.domain.comment.repository.CommentRepository +import com.example.jhouse_server.domain.comment.service.CommentService +import com.example.jhouse_server.domain.user.repository.UserRepository +import com.example.jhouse_server.domain.user.service.UserService +import com.example.jhouse_server.global.jwt.TokenDto +import com.example.jhouse_server.global.util.ApiControllerConfig +import com.example.jhouse_server.global.util.MockEntity +import com.example.jhouse_server.global.util.findByIdOrThrow +import com.fasterxml.jackson.databind.ObjectMapper +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.HttpHeaders +import org.springframework.http.MediaType +import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation +import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders +import org.springframework.restdocs.payload.PayloadDocumentation +import org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath +import org.springframework.test.web.servlet.result.MockMvcResultHandlers +import org.springframework.test.web.servlet.result.MockMvcResultMatchers +import org.springframework.transaction.annotation.Transactional + +@Transactional +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +internal class CommentControllerTest @Autowired constructor( + val commentService: CommentService, + val commentRepository: CommentRepository, + val boardService: BoardService, + val boardRepository: BoardRepository, + val userService: UserService, + val userRepository: UserRepository +) : ApiControllerConfig("/api/v1/comments") { + private val userSignUpReqDto = MockEntity.testUserSignUpDto() + private val userSignInReqDto = MockEntity.testUserSignInDto() + private lateinit var tokenDto: TokenDto + private var board: Long = 0L + private var comment: Long = 0L + + fun `로그인`() { + if (!userRepository.existsByEmail(userSignUpReqDto.email)) { + userService.signUp(userSignUpReqDto) + } + tokenDto = userService.signIn(userSignInReqDto) + } + + @BeforeEach + @Transactional + fun `게시글 더미 데이터 생성`() { + 로그인() + val user = userRepository.findByEmail(userSignInReqDto.email).get() + board = boardService.createBoard(MockEntity.boardReqDto(), user) + val findBoard = boardRepository.findByIdOrThrow(board) + comment = commentService.createComment(MockEntity.commentReqDto(board), user) + findBoard.addComment(MockEntity.comment(findBoard, user)) + boardRepository.save(findBoard) + } + @Test + @DisplayName("게시글이 갖는 댓글 리스트 조회") + fun get_comment_all() { + // given + val uri = "$uri/{boardId}" + val boardId = board + val resultActions = mockMvc.perform( + RestDocumentationRequestBuilders + .get(uri, boardId) + .accept(MediaType.APPLICATION_JSON) + .characterEncoding("UTF-8") + ) + resultActions.andExpect(MockMvcResultMatchers.status().isOk) + .andDo(MockMvcResultHandlers.print()) + .andDo( + MockMvcRestDocumentation.document( + "get-comment-all", + PayloadDocumentation.responseFields( + fieldWithPath("code").description("결과 코드"), + fieldWithPath("message").description("결과 메세지"), + fieldWithPath("data[].commentId").description("댓글 ID"), + fieldWithPath("data[].nickName").description("댓글 작성자"), + fieldWithPath("data[].content").description("댓글 내용"), + fieldWithPath("data[].createdAt").description("댓글 생성일시"), + ) + ) + ) + } + @Test + @DisplayName("댓글 작성") + fun create_comment() { + val uri = "$uri" + val req = MockEntity.commentReqDto(board) + val resultActions = mockMvc.perform( + RestDocumentationRequestBuilders + .post(uri) + .header(HttpHeaders.AUTHORIZATION, tokenDto.accessToken) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .content(ObjectMapper().writeValueAsString(req)) + .characterEncoding("UTF-8") + ) + resultActions + .andExpect(MockMvcResultMatchers.status().isOk) + .andDo(MockMvcResultHandlers.print()) + .andDo( + MockMvcRestDocumentation.document( + "comment-create", + PayloadDocumentation.requestFields( + fieldWithPath("boardId").description("게시글 ID"), + fieldWithPath("content").description("댓글 내용") + ), + PayloadDocumentation.responseFields( + fieldWithPath("code").description("결과 코드"), + fieldWithPath("message").description("결과 메세지"), + fieldWithPath("data").description("결과 데이터") + ) + ) + ) + } + @Test + @DisplayName("댓글 수정") + fun update_comment() { + val uri = "$uri/{commentId}" + val commentId = comment + val req = MockEntity.commentReqDto(board) + val resultActions = mockMvc.perform( + RestDocumentationRequestBuilders + .put(uri, commentId) + .header(HttpHeaders.AUTHORIZATION, tokenDto.accessToken) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .content(ObjectMapper().writeValueAsString(req)) + .characterEncoding("UTF-8") + ) + resultActions + .andExpect(MockMvcResultMatchers.status().isOk) + .andDo(MockMvcResultHandlers.print()) + .andDo( + MockMvcRestDocumentation.document( + "comment-update", + PayloadDocumentation.requestFields( + fieldWithPath("boardId").description("게시글 ID"), + fieldWithPath("content").description("댓글 내용") + ), + PayloadDocumentation.responseFields( + fieldWithPath("code").description("결과 코드"), + fieldWithPath("message").description("결과 메세지"), + fieldWithPath("data").description("결과 데이터") + ) + ) + ) + } + @Test + @DisplayName("댓글 삭제") + fun delete_comment() { + val uri = "$uri/{commentId}" + val commentId = comment + val resultActions = mockMvc.perform( + RestDocumentationRequestBuilders + .delete(uri, commentId) + .header(HttpHeaders.AUTHORIZATION, tokenDto.accessToken) + ) + resultActions + .andExpect(MockMvcResultMatchers.status().isOk) + .andDo(MockMvcResultHandlers.print()) + .andDo( + MockMvcRestDocumentation.document( + "comment-delete", + PayloadDocumentation.responseFields( + fieldWithPath("code").description("결과 코드"), + fieldWithPath("message").description("결과 메세지") + ) + ) + ) + } +} \ No newline at end of file diff --git a/src/test/kotlin/com/example/jhouse_server/global/util/MockEntity.kt b/src/test/kotlin/com/example/jhouse_server/global/util/MockEntity.kt index 15d198b1..b0ec2c06 100644 --- a/src/test/kotlin/com/example/jhouse_server/global/util/MockEntity.kt +++ b/src/test/kotlin/com/example/jhouse_server/global/util/MockEntity.kt @@ -3,8 +3,10 @@ package com.example.jhouse_server.global.util import com.example.jhouse_server.domain.board.BoardReqDto import com.example.jhouse_server.domain.board.BoardUpdateReqDto import com.example.jhouse_server.domain.board.PrefixCategory +import com.example.jhouse_server.domain.board.entity.Board import com.example.jhouse_server.domain.board.entity.BoardCategory -import com.example.jhouse_server.domain.comment.dto.CommentCreateReqDto +import com.example.jhouse_server.domain.comment.dto.CommentReqDto +import com.example.jhouse_server.domain.comment.entity.Comment import com.example.jhouse_server.domain.user.* import com.example.jhouse_server.domain.user.entity.Age import com.example.jhouse_server.domain.user.entity.Authority @@ -84,7 +86,7 @@ class MockEntity { fixed = false ) - fun commentReqDto(board: Long) = CommentCreateReqDto( + fun commentReqDto(board: Long) = CommentReqDto( boardId = board, content = "짱구야, 공부 하자." ) @@ -116,5 +118,9 @@ class MockEntity { prefixCategory = PrefixCategory.ADVERTISEMENT, fixed = true ) + + fun comment(findBoard: Board, user: User): Comment { + return Comment(findBoard, "댓글이란다.", user) + } } } \ No newline at end of file