From 454e4aaf75f03bbc7c492aa9e620055d910a55aa Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 13 Aug 2024 11:18:46 +0900 Subject: [PATCH 01/13] =?UTF-8?q?feat:=20=EB=8C=93=EA=B8=80=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/domain/Comment.java | 111 ++++++++++++++++++ .../solidconnection/entity/Comment.java | 46 -------- 2 files changed, 111 insertions(+), 46 deletions(-) create mode 100644 src/main/java/com/example/solidconnection/comment/domain/Comment.java delete mode 100644 src/main/java/com/example/solidconnection/entity/Comment.java diff --git a/src/main/java/com/example/solidconnection/comment/domain/Comment.java b/src/main/java/com/example/solidconnection/comment/domain/Comment.java new file mode 100644 index 000000000..774c01123 --- /dev/null +++ b/src/main/java/com/example/solidconnection/comment/domain/Comment.java @@ -0,0 +1,111 @@ +package com.example.solidconnection.comment.domain; + +import com.example.solidconnection.entity.common.BaseEntity; +import com.example.solidconnection.post.domain.Post; +import com.example.solidconnection.siteuser.domain.SiteUser; +import jakarta.persistence.*; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@NoArgsConstructor +@EqualsAndHashCode(of = "id") +public class Comment extends BaseEntity { + + // for recursive query + @Transient + private int level; + + @Transient + private String path; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(length = 255) + private String content; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id") + private Post post; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "site_user_id") + private SiteUser siteUser; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "parent_id") + private Comment parentComment; + + @OneToMany(mappedBy = "parentComment", cascade = CascadeType.ALL) + private List commentList = new ArrayList<>(); + + public Comment(String content) { + this.content = content; + } + + public void setParentCommentAndPostAndSiteUser(Comment parentComment, Post post, SiteUser siteUser) { + + if (this.parentComment != null) { + this.parentComment.getCommentList().remove(this); + } + this.parentComment = parentComment; + parentComment.getCommentList().add(this); + + if (this.post != null) { + this.post.getCommentList().remove(this); + } + this.post = post; + post.getCommentList().add(this); + + if (this.siteUser != null) { + this.siteUser.getCommentList().remove(this); + } + this.siteUser = siteUser; + siteUser.getCommentList().add(this); + } + + public void setPostAndSiteUser(Post post, SiteUser siteUser) { + + if (this.post != null) { + this.post.getCommentList().remove(this); + } + this.post = post; + post.getCommentList().add(this); + + if (this.siteUser != null) { + this.siteUser.getCommentList().remove(this); + } + this.siteUser = siteUser; + siteUser.getCommentList().add(this); + } + + public void resetPostAndSiteUserAndParentComment() { + if (this.post != null) { + this.post.getCommentList().remove(this); + this.post = null; + } + if (this.siteUser != null) { + this.siteUser.getCommentList().remove(this); + this.siteUser = null; + } + if (this.parentComment != null) { + this.parentComment.getCommentList().remove(this); + this.parentComment = null; + } + } + + public void updateContent(String content) { + this.content = content; + } + + public void deprecateComment() { + this.content = null; + } +} diff --git a/src/main/java/com/example/solidconnection/entity/Comment.java b/src/main/java/com/example/solidconnection/entity/Comment.java deleted file mode 100644 index 7b4ad87d8..000000000 --- a/src/main/java/com/example/solidconnection/entity/Comment.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.example.solidconnection.entity; - -import com.example.solidconnection.entity.common.BaseEntity; -import com.example.solidconnection.post.domain.Post; -import com.example.solidconnection.siteuser.domain.SiteUser; -import jakarta.persistence.*; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.util.ArrayList; -import java.util.List; - -@Entity -@Getter -@NoArgsConstructor -public class Comment extends BaseEntity { - - // for recursive query - @Transient - private int level; - - @Transient - private String path; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(length = 255) - private String content; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "post_id") - private Post post; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "site_user_id") - private SiteUser siteUser; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "parent_id") - private Comment parentComment; - - @OneToMany(mappedBy = "parentComment", cascade = CascadeType.ALL) - private List commentList = new ArrayList<>(); -} From dfbf1376b51c907c46f6cb69dd372a18eb46293b Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 13 Aug 2024 11:22:04 +0900 Subject: [PATCH 02/13] =?UTF-8?q?refactor:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=97=94=ED=8B=B0=ED=8B=B0=20=ED=8F=B4=EB=8D=94=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solidconnection/comment/dto/PostFindCommentResponse.java | 2 +- .../java/com/example/solidconnection/post/domain/Post.java | 2 +- .../com/example/solidconnection/siteuser/domain/SiteUser.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/example/solidconnection/comment/dto/PostFindCommentResponse.java b/src/main/java/com/example/solidconnection/comment/dto/PostFindCommentResponse.java index 75414f943..8524eb95a 100644 --- a/src/main/java/com/example/solidconnection/comment/dto/PostFindCommentResponse.java +++ b/src/main/java/com/example/solidconnection/comment/dto/PostFindCommentResponse.java @@ -1,6 +1,6 @@ package com.example.solidconnection.comment.dto; -import com.example.solidconnection.entity.Comment; +import com.example.solidconnection.comment.domain.Comment; import com.example.solidconnection.siteuser.dto.PostFindSiteUserResponse; import java.time.LocalDateTime; diff --git a/src/main/java/com/example/solidconnection/post/domain/Post.java b/src/main/java/com/example/solidconnection/post/domain/Post.java index 646ac3995..12e43195f 100644 --- a/src/main/java/com/example/solidconnection/post/domain/Post.java +++ b/src/main/java/com/example/solidconnection/post/domain/Post.java @@ -1,7 +1,7 @@ package com.example.solidconnection.post.domain; import com.example.solidconnection.board.domain.Board; -import com.example.solidconnection.entity.Comment; +import com.example.solidconnection.comment.domain.Comment; import com.example.solidconnection.entity.PostImage; import com.example.solidconnection.entity.common.BaseEntity; import com.example.solidconnection.entity.mapping.PostLike; diff --git a/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java b/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java index 2cd7dc4ff..300c69492 100644 --- a/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java +++ b/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java @@ -1,6 +1,6 @@ package com.example.solidconnection.siteuser.domain; -import com.example.solidconnection.entity.Comment; +import com.example.solidconnection.comment.domain.Comment; import com.example.solidconnection.post.domain.Post; import com.example.solidconnection.entity.mapping.PostLike; import com.example.solidconnection.type.Gender; @@ -59,7 +59,7 @@ public class SiteUser { @OneToMany(mappedBy = "siteUser", cascade = CascadeType.ALL, orphanRemoval = true) private List postList = new ArrayList<>(); - @OneToMany(mappedBy = "siteUser", cascade = CascadeType.ALL, orphanRemoval = true) + @OneToMany(mappedBy = "siteUser", cascade = CascadeType.ALL) private List commentList = new ArrayList<>(); @OneToMany(mappedBy = "siteUser", cascade = CascadeType.ALL, orphanRemoval = true) From e2637bbeec4f4cd73772a1387359a12c836249dd Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 13 Aug 2024 11:22:36 +0900 Subject: [PATCH 03/13] =?UTF-8?q?feat:=20=EB=8C=93=EA=B8=80=20=EB=A0=88?= =?UTF-8?q?=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/repository/CommentRepository.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/solidconnection/comment/repository/CommentRepository.java b/src/main/java/com/example/solidconnection/comment/repository/CommentRepository.java index 0b0d7152c..b78011903 100644 --- a/src/main/java/com/example/solidconnection/comment/repository/CommentRepository.java +++ b/src/main/java/com/example/solidconnection/comment/repository/CommentRepository.java @@ -1,12 +1,14 @@ package com.example.solidconnection.comment.repository; -import com.example.solidconnection.entity.Comment; +import com.example.solidconnection.comment.domain.Comment; +import com.example.solidconnection.custom.exception.CustomException; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import java.util.List; +import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_COMMENT_ID; public interface CommentRepository extends JpaRepository { @Query(value = """ @@ -30,4 +32,8 @@ WITH RECURSIVE CommentTree AS ( """, nativeQuery = true) List findCommentTreeByPostId(@Param("postId") Long postId); + default Comment getById(Long id) { + return findById(id) + .orElseThrow(() -> new CustomException(INVALID_COMMENT_ID)); + } } From 5a85abaa05acb9bb3e03ee5b52bacc31c3a80855 Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 13 Aug 2024 11:22:58 +0900 Subject: [PATCH 04/13] =?UTF-8?q?feat:=20=EB=8C=93=EA=B8=80=20=EC=84=9C?= =?UTF-8?q?=EB=B9=84=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/service/CommentService.java | 74 ++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/example/solidconnection/comment/service/CommentService.java b/src/main/java/com/example/solidconnection/comment/service/CommentService.java index 9e32e4d32..d4f4fd9ca 100644 --- a/src/main/java/com/example/solidconnection/comment/service/CommentService.java +++ b/src/main/java/com/example/solidconnection/comment/service/CommentService.java @@ -1,29 +1,99 @@ package com.example.solidconnection.comment.service; +import com.example.solidconnection.comment.dto.*; import com.example.solidconnection.comment.repository.CommentRepository; -import com.example.solidconnection.comment.dto.PostFindCommentResponse; -import com.example.solidconnection.entity.Comment; +import com.example.solidconnection.comment.domain.Comment; +import com.example.solidconnection.custom.exception.CustomException; +import com.example.solidconnection.post.domain.Post; +import com.example.solidconnection.post.repository.PostRepository; +import com.example.solidconnection.siteuser.domain.SiteUser; +import com.example.solidconnection.siteuser.repository.SiteUserRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.stream.Collectors; +import static com.example.solidconnection.custom.exception.ErrorCode.CAN_NOT_UPDATE_DEPRECATED_COMMENT; +import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_POST_ACCESS; + @Service @RequiredArgsConstructor public class CommentService { private final CommentRepository commentRepository; + private final SiteUserRepository siteUserRepository; + private final PostRepository postRepository; private Boolean isOwner(Comment comment, String email) { return comment.getSiteUser().getEmail().equals(email); } + private void validateOwnership(Comment comment, String email) { + if (!comment.getSiteUser().getEmail().equals(email)) { + throw new CustomException(INVALID_POST_ACCESS); + } + } + private void validateDeprecated(Comment comment) { + if (comment.getContent() == null) { + throw new CustomException(CAN_NOT_UPDATE_DEPRECATED_COMMENT); + } + } + + @Transactional(readOnly = true) public List findCommentsByPostId(String email, Long postId) { return commentRepository.findCommentTreeByPostId(postId) .stream() .map(comment -> PostFindCommentResponse.from(isOwner(comment, email), comment)) .collect(Collectors.toList()); } + + @Transactional + public CommentCreateResponse createComment(String email, Long postId, CommentCreateRequest commentCreateRequest) { + + SiteUser siteUser = siteUserRepository.getByEmail(email); + Post post = postRepository.getById(postId); + + Comment parentComment = commentCreateRequest.parentId() + .map(commentRepository::getById) + .orElse(null); + Comment createdComment = commentRepository.save(commentCreateRequest.toEntity(siteUser, post, parentComment)); + + return CommentCreateResponse.from(createdComment); + } + + @Transactional + public CommentUpdateResponse updateComment(String email, Long postId, Long commentId, CommentUpdateRequest commentUpdateRequest) { + + SiteUser siteUser = siteUserRepository.getByEmail(email); + Post post = postRepository.getById(postId); + Comment comment = commentRepository.getById(commentId); + validateDeprecated(comment); + validateOwnership(comment, email); + + comment.updateContent(commentUpdateRequest.content()); + + return CommentUpdateResponse.from(comment); + } + + @Transactional + public CommentDeleteResponse deleteCommentById(String email, Long postId, Long commentId) { + SiteUser siteUser = siteUserRepository.getByEmail(email); + Post post = postRepository.getById(postId); + Comment comment = commentRepository.getById(commentId); + validateOwnership(comment, email); + + if (comment.getCommentList().isEmpty()) { + // 하위 댓글이 없다면 삭제한다. + comment.resetPostAndSiteUserAndParentComment(); + commentRepository.deleteById(commentId); + } else { + // 하위 댓글 있으면 value만 null로 수정한다. + comment.deprecateComment(); + } + + return new CommentDeleteResponse(commentId); + } } From 55173b00dc99a7632cb8afece2566ba03c132407 Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 13 Aug 2024 11:23:32 +0900 Subject: [PATCH 05/13] =?UTF-8?q?feat:=20=EB=8C=93=EA=B8=80=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/controller/CommentController.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/main/java/com/example/solidconnection/comment/controller/CommentController.java diff --git a/src/main/java/com/example/solidconnection/comment/controller/CommentController.java b/src/main/java/com/example/solidconnection/comment/controller/CommentController.java new file mode 100644 index 000000000..61bae1036 --- /dev/null +++ b/src/main/java/com/example/solidconnection/comment/controller/CommentController.java @@ -0,0 +1,62 @@ +package com.example.solidconnection.comment.controller; + +import com.example.solidconnection.comment.dto.*; +import com.example.solidconnection.comment.service.CommentService; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.security.SecurityRequirements; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.security.Principal; + +import static com.example.solidconnection.config.swagger.SwaggerConfig.ACCESS_TOKEN; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/posts") +@SecurityRequirements +@SecurityRequirement(name = ACCESS_TOKEN) +public class CommentController { + + private final CommentService commentService; + + @PostMapping("/{post_id}/comments") + public ResponseEntity createComment( + Principal principal, + @PathVariable("post_id") Long postId, + @Valid @RequestBody CommentCreateRequest commentCreateRequest + ) { + + CommentCreateResponse commentCreateResponse = commentService.createComment( + principal.getName(), postId, commentCreateRequest); + return ResponseEntity.ok().body(commentCreateResponse); + } + + @PatchMapping("/{post_id}/comments/{comment_id}") + public ResponseEntity updateComment( + Principal principal, + @PathVariable("post_id") Long postId, + @PathVariable("comment_id") Long commentId, + @Valid @RequestBody CommentUpdateRequest commentUpdateRequest + ) { + + CommentUpdateResponse commentUpdateResponse = commentService.updateComment( + principal.getName(), postId, commentId, commentUpdateRequest + ); + return ResponseEntity.ok().body(commentUpdateResponse); + } + + @DeleteMapping("/{post_id}/comments/{comment_id}") + public ResponseEntity deleteCommentById( + Principal principal, + @PathVariable("post_id") Long postId, + @PathVariable("comment_id") Long commentId + ) { + + CommentDeleteResponse commentDeleteResponse = commentService.deleteCommentById(principal.getName(), postId, commentId); + return ResponseEntity.ok().body(commentDeleteResponse); + } + +} From 5703acea811c31a89961f0d1404232962154dbba Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 13 Aug 2024 11:24:24 +0900 Subject: [PATCH 06/13] =?UTF-8?q?feat:=20=EB=8C=93=EA=B8=80=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20DTO=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/dto/CommentCreateRequest.java | 30 +++++++++++++++++++ .../comment/dto/CommentCreateResponse.java | 14 +++++++++ .../comment/dto/CommentDeleteResponse.java | 6 ++++ .../comment/dto/CommentUpdateRequest.java | 12 ++++++++ .../comment/dto/CommentUpdateResponse.java | 14 +++++++++ 5 files changed, 76 insertions(+) create mode 100644 src/main/java/com/example/solidconnection/comment/dto/CommentCreateRequest.java create mode 100644 src/main/java/com/example/solidconnection/comment/dto/CommentCreateResponse.java create mode 100644 src/main/java/com/example/solidconnection/comment/dto/CommentDeleteResponse.java create mode 100644 src/main/java/com/example/solidconnection/comment/dto/CommentUpdateRequest.java create mode 100644 src/main/java/com/example/solidconnection/comment/dto/CommentUpdateResponse.java diff --git a/src/main/java/com/example/solidconnection/comment/dto/CommentCreateRequest.java b/src/main/java/com/example/solidconnection/comment/dto/CommentCreateRequest.java new file mode 100644 index 000000000..43942a9b1 --- /dev/null +++ b/src/main/java/com/example/solidconnection/comment/dto/CommentCreateRequest.java @@ -0,0 +1,30 @@ +package com.example.solidconnection.comment.dto; + +import com.example.solidconnection.comment.domain.Comment; +import com.example.solidconnection.post.domain.Post; +import com.example.solidconnection.siteuser.domain.SiteUser; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; + +import java.util.Optional; + +public record CommentCreateRequest( + @NotBlank(message = "댓글 내용은 빈 값일 수 없습니다.") + @Size(min = 1, max = 255, message = "댓글 내용은 최소 1자 이상, 최대 255자 이하여야 합니다.") + String content, + Optional parentId // https://www.baeldung.com/java-record-optional-param +) { + public Comment toEntity(SiteUser siteUser, Post post, Comment parentComment) { + + Comment comment = new Comment( + this.content + ); + + if (parentComment == null) { + comment.setPostAndSiteUser(post, siteUser); + } else { + comment.setParentCommentAndPostAndSiteUser(parentComment, post, siteUser); + } + return comment; + } +} diff --git a/src/main/java/com/example/solidconnection/comment/dto/CommentCreateResponse.java b/src/main/java/com/example/solidconnection/comment/dto/CommentCreateResponse.java new file mode 100644 index 000000000..60d7529c2 --- /dev/null +++ b/src/main/java/com/example/solidconnection/comment/dto/CommentCreateResponse.java @@ -0,0 +1,14 @@ +package com.example.solidconnection.comment.dto; + +import com.example.solidconnection.comment.domain.Comment; + +public record CommentCreateResponse( + Long id +) { + + public static CommentCreateResponse from(Comment comment) { + return new CommentCreateResponse( + comment.getId() + ); + } +} diff --git a/src/main/java/com/example/solidconnection/comment/dto/CommentDeleteResponse.java b/src/main/java/com/example/solidconnection/comment/dto/CommentDeleteResponse.java new file mode 100644 index 000000000..393e4fe8b --- /dev/null +++ b/src/main/java/com/example/solidconnection/comment/dto/CommentDeleteResponse.java @@ -0,0 +1,6 @@ +package com.example.solidconnection.comment.dto; + +public record CommentDeleteResponse( + Long id +) { +} diff --git a/src/main/java/com/example/solidconnection/comment/dto/CommentUpdateRequest.java b/src/main/java/com/example/solidconnection/comment/dto/CommentUpdateRequest.java new file mode 100644 index 000000000..23ae16118 --- /dev/null +++ b/src/main/java/com/example/solidconnection/comment/dto/CommentUpdateRequest.java @@ -0,0 +1,12 @@ +package com.example.solidconnection.comment.dto; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; + +public record CommentUpdateRequest( + @NotBlank(message = "댓글 내용은 빈 값일 수 없습니다.") + @Size(min = 1, max = 255, message = "댓글 내용은 최소 1자 이상, 최대 255자 이하여야 합니다.") + String content +) { + +} diff --git a/src/main/java/com/example/solidconnection/comment/dto/CommentUpdateResponse.java b/src/main/java/com/example/solidconnection/comment/dto/CommentUpdateResponse.java new file mode 100644 index 000000000..b621ab111 --- /dev/null +++ b/src/main/java/com/example/solidconnection/comment/dto/CommentUpdateResponse.java @@ -0,0 +1,14 @@ +package com.example.solidconnection.comment.dto; + +import com.example.solidconnection.comment.domain.Comment; + +public record CommentUpdateResponse( + Long id +) { + + public static CommentUpdateResponse from(Comment comment) { + return new CommentUpdateResponse( + comment.getId() + ); + } +} From 4697d9c22dd99ea46d168900c4cb86480e2ed4f6 Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 13 Aug 2024 11:24:42 +0900 Subject: [PATCH 07/13] =?UTF-8?q?feat:=20=EB=8C=93=EA=B8=80=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=98=88=EC=99=B8=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/solidconnection/custom/exception/ErrorCode.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java index 6caf9edc2..0a9df0b61 100644 --- a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java +++ b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java @@ -58,6 +58,9 @@ public enum ErrorCode { INVALID_POST_ACCESS(HttpStatus.BAD_REQUEST.value(), "자신의 게시글만 제어할 수 있습니다."), CAN_NOT_DELETE_OR_UPDATE_QUESTION(HttpStatus.BAD_REQUEST.value(), "질문글은 수정이나 삭제할 수 없습니다."), CAN_NOT_UPLOAD_MORE_THAN_FIVE_IMAGES(HttpStatus.BAD_REQUEST.value(), "5개 이상의 파일을 업로드할 수 없습니다."), + INVALID_COMMENT_ID(HttpStatus.BAD_REQUEST.value(), "존재하지 않는 댓글입니다."), + INVALID_COMMENT_ACCESS(HttpStatus.BAD_REQUEST.value(), "자신의 댓글만 제어할 수 있습니다."), + CAN_NOT_UPDATE_DEPRECATED_COMMENT(HttpStatus.BAD_REQUEST.value(),"이미 삭제된 댓글을 수정할 수 없습니다."), // general JSON_PARSING_FAILED(HttpStatus.BAD_REQUEST.value(), "JSON 파싱을 할 수 없습니다."), From 5a8c0c1549409db563d503b61615eeae41d9fdc2 Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 13 Aug 2024 11:25:21 +0900 Subject: [PATCH 08/13] =?UTF-8?q?test:=20=EB=8C=93=EA=B8=80=20=EB=A0=88?= =?UTF-8?q?=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/CommentRepositoryTest.java | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 src/test/java/com/example/solidconnection/unit/repository/CommentRepositoryTest.java diff --git a/src/test/java/com/example/solidconnection/unit/repository/CommentRepositoryTest.java b/src/test/java/com/example/solidconnection/unit/repository/CommentRepositoryTest.java new file mode 100644 index 000000000..def0710a0 --- /dev/null +++ b/src/test/java/com/example/solidconnection/unit/repository/CommentRepositoryTest.java @@ -0,0 +1,156 @@ +package com.example.solidconnection.unit.repository; + +import com.example.solidconnection.board.domain.Board; +import com.example.solidconnection.board.repository.BoardRepository; +import com.example.solidconnection.comment.domain.Comment; +import com.example.solidconnection.comment.repository.CommentRepository; +import com.example.solidconnection.custom.exception.CustomException; +import com.example.solidconnection.post.domain.Post; +import com.example.solidconnection.post.repository.PostRepository; +import com.example.solidconnection.siteuser.domain.SiteUser; +import com.example.solidconnection.siteuser.repository.SiteUserRepository; +import com.example.solidconnection.type.Gender; +import com.example.solidconnection.type.PostCategory; +import com.example.solidconnection.type.PreparationStatus; +import com.example.solidconnection.type.Role; +import jakarta.persistence.EntityManager; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_COMMENT_ID; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + + +@SpringBootTest +@ActiveProfiles("local") +@DisplayName("댓글 레포지토리 테스트") +public class CommentRepositoryTest { + @Autowired + private PostRepository postRepository; + @Autowired + private BoardRepository boardRepository; + @Autowired + private SiteUserRepository siteUserRepository; + @Autowired + private EntityManager entityManager; + @Autowired + private CommentRepository commentRepository; + + private Board board; + private SiteUser siteUser; + private Post post; + private Comment parentComment; + private Comment childComment; + + @BeforeEach + public void setUp() { + board = createBoard(); + boardRepository.save(board); + + siteUser = createSiteUser(); + siteUserRepository.save(siteUser); + + post = createPost(board, siteUser); + post = postRepository.save(post); + + parentComment = createParentComment(); + childComment = createChildComment(); + commentRepository.save(parentComment); + commentRepository.save(childComment); + + entityManager.flush(); + entityManager.clear(); + } + + private Board createBoard() { + return new Board( + "FREE", "자유게시판"); + } + + private SiteUser createSiteUser() { + return new SiteUser( + "test@example.com", + "nickname", + "profileImageUrl", + "1999-01-01", + PreparationStatus.CONSIDERING, + Role.MENTEE, + Gender.MALE + ); + } + + private Post createPost(Board board, SiteUser siteUser) { + Post post = new Post( + "title", + "content", + false, + 0L, + 0L, + PostCategory.valueOf("자유") + ); + post.setBoardAndSiteUser(board, siteUser); + return post; + } + + private Comment createParentComment() { + Comment comment = new Comment( + "parent" + ); + comment.setPostAndSiteUser(post, siteUser); + return comment; + } + + private Comment createChildComment() { + Comment comment = new Comment( + "child" + ); + comment.setParentCommentAndPostAndSiteUser(parentComment, post, siteUser); + return comment; + } + + @Test + @Transactional + public void 재귀쿼리로_댓글트리를_조회한다() { + // when + List commentTreeByPostId = commentRepository.findCommentTreeByPostId(post.getId()); + + // then + List expectedResponse = List.of(parentComment, childComment); + assertEquals(commentTreeByPostId, expectedResponse); + } + + @Test + @Transactional + public void 댓글을_조회한다() { + // when + Comment foundComment = commentRepository.getById(parentComment.getId()); + + // then + assertEquals(parentComment, foundComment); + } + + @Test + @Transactional + public void 댓글을_조회할_때_유효한_댓글이_아니라면_예외_응답을_반환한다() { + // given + Long invalidId = -1L; + + // when, then + CustomException exception = assertThrows(CustomException.class, () -> { + commentRepository.getById(invalidId); + }); + assertThat(exception.getMessage()) + .isEqualTo(INVALID_COMMENT_ID.getMessage()); + assertThat(exception.getCode()) + .isEqualTo(INVALID_COMMENT_ID.getCode()); + } +} From 831616726525ceafa03ee442cea0080de8b0e39a Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 13 Aug 2024 11:25:33 +0900 Subject: [PATCH 09/13] =?UTF-8?q?test:=20=EB=8C=93=EA=B8=80=20=EC=84=9C?= =?UTF-8?q?=EB=B9=84=EC=8A=A4=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unit/service/CommentServiceTest.java | 428 ++++++++++++++++++ 1 file changed, 428 insertions(+) create mode 100644 src/test/java/com/example/solidconnection/unit/service/CommentServiceTest.java diff --git a/src/test/java/com/example/solidconnection/unit/service/CommentServiceTest.java b/src/test/java/com/example/solidconnection/unit/service/CommentServiceTest.java new file mode 100644 index 000000000..5cab31efb --- /dev/null +++ b/src/test/java/com/example/solidconnection/unit/service/CommentServiceTest.java @@ -0,0 +1,428 @@ +package com.example.solidconnection.unit.service; + +import com.example.solidconnection.board.domain.Board; +import com.example.solidconnection.comment.domain.Comment; +import com.example.solidconnection.comment.dto.*; +import com.example.solidconnection.comment.repository.CommentRepository; +import com.example.solidconnection.comment.service.CommentService; +import com.example.solidconnection.custom.exception.CustomException; +import com.example.solidconnection.post.domain.Post; +import com.example.solidconnection.post.repository.PostRepository; +import com.example.solidconnection.siteuser.domain.SiteUser; +import com.example.solidconnection.siteuser.repository.SiteUserRepository; +import com.example.solidconnection.type.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static com.example.solidconnection.custom.exception.ErrorCode.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +@DisplayName("댓글 서비스 테스트") +public class CommentServiceTest { + @InjectMocks + CommentService commentService; + @Mock + PostRepository postRepository; + @Mock + SiteUserRepository siteUserRepository; + @Mock + CommentRepository commentRepository; + + private SiteUser siteUser; + private Board board; + private Post post; + private Comment parentComment_1; + private Comment parentComment_2; + private Comment p1s_childComment; + + + @BeforeEach + void setUp() { + siteUser = createSiteUser(); + board = createBoard(); + post = createPost(board, siteUser); + parentComment_1 = createParentComment(); + parentComment_2 = createParentComment(); + p1s_childComment = createChildComment(); + } + + private SiteUser createSiteUser() { + return new SiteUser( + "test@example.com", + "nickname", + "profileImageUrl", + "1999-01-01", + PreparationStatus.CONSIDERING, + Role.MENTEE, + Gender.MALE + ); + } + + private Board createBoard() { + return new Board( + "FREE", "자유게시판"); + } + + private Post createPost(Board board, SiteUser siteUser) { + Post post = new Post( + "title", + "content", + false, + 0L, + 0L, + PostCategory.valueOf("자유") + ); + post.setBoardAndSiteUser(board, siteUser); + return post; + } + + private Comment createParentComment() { + Comment comment = new Comment( + "parent" + ); + comment.setPostAndSiteUser(post, siteUser); + return comment; + } + + private Comment createChildComment() { + Comment comment = new Comment( + "child" + ); + comment.setParentCommentAndPostAndSiteUser(parentComment_1, post, siteUser); + return comment; + } + + /** + * 댓글 조회 + */ + + @Test + void 특정_게시글의_댓글들을_조회한다() { + // Given + List commentList = List.of(parentComment_1, p1s_childComment, parentComment_2); + when(commentRepository.findCommentTreeByPostId(post.getId())).thenReturn(commentList); + + // When + List postFindCommentResponses = commentService.findCommentsByPostId( + siteUser.getEmail(), post.getId()); + + // Then + List expectedResponse = commentList.stream() + .map(comment -> PostFindCommentResponse.from(isOwner(comment, siteUser.getEmail()), comment)) + .collect(Collectors.toList()); + assertEquals(postFindCommentResponses, expectedResponse); + } + + private Boolean isOwner(Comment comment, String email) { + return comment.getSiteUser().getEmail().equals(email); + } + + /** + * 댓글 등록 + */ + @Test + void 부모_댓글을_등록한다() { + // Given + CommentCreateRequest commentCreateRequest = new CommentCreateRequest( + "parent", + Optional.empty() + ); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(postRepository.getById(post.getId())).thenReturn(post); + when(commentRepository.save(any(Comment.class))).thenReturn(parentComment_1); + + // When + CommentCreateResponse commentCreateResponse = commentService.createComment( + siteUser.getEmail(), post.getId(), commentCreateRequest); + + // Then + assertEquals(commentCreateResponse, CommentCreateResponse.from(parentComment_1)); + verify(commentRepository,times(0)) + .getById(any(Long.class)); + verify(commentRepository,times(1)) + .save(commentCreateRequest.toEntity(siteUser,post, parentComment_1)); + } + + @Test + void 자식_댓글을_등록한다() { + // Given + Long parentCommentId = 1L; + CommentCreateRequest commentCreateRequest = new CommentCreateRequest( + "child", + Optional.of(parentCommentId) + ); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(postRepository.getById(post.getId())).thenReturn(post); + when(commentRepository.getById(parentCommentId)).thenReturn(parentComment_1); + when(commentRepository.save(any(Comment.class))).thenReturn(p1s_childComment); + + // When + CommentCreateResponse commentCreateResponse = commentService.createComment( + siteUser.getEmail(), post.getId(), commentCreateRequest); + + // Then + assertEquals(commentCreateResponse, CommentCreateResponse.from(p1s_childComment)); + verify(commentRepository,times(1)) + .getById(parentCommentId); + verify(commentRepository,times(1)) + .save(commentCreateRequest.toEntity(siteUser,post, parentComment_1)); + } + + + @Test + void 댓글을_등록할_때_유효한_게시글이_아니라면_예외_응답을_반환한다() { + // Given + Long invalidPostId = -1L; + CommentCreateRequest commentCreateRequest = new CommentCreateRequest( + "child", + Optional.empty() + ); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(postRepository.getById(invalidPostId)).thenThrow(new CustomException(INVALID_POST_ID)); + + // When & Then + CustomException exception = assertThrows(CustomException.class, () -> + commentService.createComment(siteUser.getEmail(), invalidPostId, commentCreateRequest) + ); + assertThat(exception.getMessage()) + .isEqualTo(INVALID_POST_ID.getMessage()); + assertThat(exception.getCode()) + .isEqualTo(INVALID_POST_ID.getCode()); + verify(commentRepository,times(0)) + .save(any(Comment.class)); + } + + @Test + void 댓글을_등록할_때_유효한_부모_댓글이_아니라면_예외_응답을_반환한다() { + // Given + Long invalidParentCommentId = -1L; + CommentCreateRequest commentCreateRequest = new CommentCreateRequest( + "child", + Optional.of(invalidParentCommentId) + ); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(postRepository.getById(post.getId())).thenReturn(post); + when(commentRepository.getById(invalidParentCommentId)).thenThrow(new CustomException(INVALID_COMMENT_ID)); + + // When & Then + CustomException exception = assertThrows(CustomException.class, () -> + commentService.createComment(siteUser.getEmail(), post.getId(), commentCreateRequest) + ); + assertThat(exception.getMessage()) + .isEqualTo(INVALID_COMMENT_ID.getMessage()); + assertThat(exception.getCode()) + .isEqualTo(INVALID_COMMENT_ID.getCode()); + verify(commentRepository,times(0)) + .save(any(Comment.class)); + } + + /** + * 댓글 수정 + */ + @Test + void 댓글을_수정한다() { + // Given + CommentUpdateRequest commentUpdateRequest = new CommentUpdateRequest( + "update" + ); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(postRepository.getById(post.getId())).thenReturn(post); + when(commentRepository.getById(any())).thenReturn(parentComment_1); + + // When + CommentUpdateResponse commentUpdateResponse = commentService.updateComment( + siteUser.getEmail(), post.getId(), parentComment_1.getId(), commentUpdateRequest); + + // Then + assertEquals(commentUpdateResponse.id(), parentComment_1.getId()); + } + + @Test + void 댓글을_수정할_때_유효한_게시글이_아니라면_예외_응답을_반환한다() { + // Given + Long invalidPostId = -1L; + CommentUpdateRequest commentUpdateRequest = new CommentUpdateRequest( + "update" + ); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(postRepository.getById(invalidPostId)).thenThrow(new CustomException(INVALID_POST_ID)); + + // When & Then + CustomException exception = assertThrows(CustomException.class, () -> + commentService.updateComment(siteUser.getEmail(), invalidPostId, parentComment_1.getId(), commentUpdateRequest) + ); + assertThat(exception.getMessage()) + .isEqualTo(INVALID_POST_ID.getMessage()); + assertThat(exception.getCode()) + .isEqualTo(INVALID_POST_ID.getCode()); + } + + @Test + void 댓글을_수정할_때_유효한_댓글이_아니라면_예외_응답을_반환한다() { + // Given + Long invalidCommentId = -1L; + CommentUpdateRequest commentUpdateRequest = new CommentUpdateRequest( + "update" + ); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(postRepository.getById(post.getId())).thenReturn(post); + when(commentRepository.getById(invalidCommentId)).thenThrow(new CustomException(INVALID_COMMENT_ID)); + + // When & Then + CustomException exception = assertThrows(CustomException.class, () -> + commentService.updateComment(siteUser.getEmail(), post.getId(), invalidCommentId, commentUpdateRequest) + ); + assertThat(exception.getMessage()) + .isEqualTo(INVALID_COMMENT_ID.getMessage()); + assertThat(exception.getCode()) + .isEqualTo(INVALID_COMMENT_ID.getCode()); + } + + @Test + void 댓글을_수정할_때_이미_삭제된_댓글이라면_예외_응답을_반환한다() { + // Given + parentComment_1.deprecateComment(); + CommentUpdateRequest commentUpdateRequest = new CommentUpdateRequest( + "update" + ); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(postRepository.getById(post.getId())).thenReturn(post); + when(commentRepository.getById(any())).thenReturn(parentComment_1); + + // When & Then + CustomException exception = assertThrows(CustomException.class, () -> + commentService.updateComment(siteUser.getEmail(), post.getId(), parentComment_1.getId(), commentUpdateRequest) + ); + assertThat(exception.getMessage()) + .isEqualTo(CAN_NOT_UPDATE_DEPRECATED_COMMENT.getMessage()); + assertThat(exception.getCode()) + .isEqualTo(CAN_NOT_UPDATE_DEPRECATED_COMMENT.getCode()); + } + + @Test + void 댓글을_수정할_때_자신의_댓글이_아니라면_예외_응답을_반환한다() { + // Given + String invalidEmail = "invalidEmail@test.com"; + CommentUpdateRequest commentUpdateRequest = new CommentUpdateRequest( + "update" + ); + when(siteUserRepository.getByEmail(invalidEmail)).thenReturn(siteUser); + when(postRepository.getById(post.getId())).thenReturn(post); + when(commentRepository.getById(any())).thenReturn(parentComment_1); + + // When & Then + CustomException exception = assertThrows(CustomException.class, () -> + commentService.updateComment(invalidEmail, post.getId(), parentComment_1.getId(), commentUpdateRequest) + ); + assertThat(exception.getMessage()) + .isEqualTo(INVALID_POST_ACCESS.getMessage()); + assertThat(exception.getCode()) + .isEqualTo(INVALID_POST_ACCESS.getCode()); + } + + /** + * 댓글 삭제 + */ + + @Test + void 댓글을_삭제한다_자식댓글_있음() { + // Given + Long parentCommentId = 1L; + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(postRepository.getById(post.getId())).thenReturn(post); + when(commentRepository.getById(any())).thenReturn(parentComment_1); + + // When + CommentDeleteResponse commentDeleteResponse = commentService.deleteCommentById( + siteUser.getEmail(), post.getId(), parentCommentId); + + // Then + assertEquals(parentComment_1.getContent(), null); + assertEquals(commentDeleteResponse.id(), parentCommentId); + verify(commentRepository, times(0)).deleteById(parentCommentId); + } + + @Test + void 댓글을_삭제한다_자식댓글_없음() { + // Given + Long childCommentId = 1L; + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(postRepository.getById(post.getId())).thenReturn(post); + when(commentRepository.getById(any())).thenReturn(p1s_childComment); + + // When + CommentDeleteResponse commentDeleteResponse = commentService.deleteCommentById( + siteUser.getEmail(), post.getId(), childCommentId); + + // Then + assertEquals(commentDeleteResponse.id(), childCommentId); + verify(commentRepository, times(1)).deleteById(childCommentId); + } + + @Test + void 댓글을_삭제할_때_유효한_게시글이_아니라면_예외_응답을_반환한다() { + // Given + Long invalidPostId = -1L; + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(postRepository.getById(invalidPostId)).thenThrow(new CustomException(INVALID_POST_ID)); + + // When & Then + CustomException exception = assertThrows(CustomException.class, () -> + commentService.deleteCommentById(siteUser.getEmail(), invalidPostId, parentComment_1.getId()) + ); + assertThat(exception.getMessage()) + .isEqualTo(INVALID_POST_ID.getMessage()); + assertThat(exception.getCode()) + .isEqualTo(INVALID_POST_ID.getCode()); + } + + @Test + void 댓글을_삭제할_때_유효한_댓글이_아니라면_예외_응답을_반환한다() { + // Given + Long invalidCommentId = -1L; + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(postRepository.getById(post.getId())).thenReturn(post); + when(commentRepository.getById(invalidCommentId)).thenThrow(new CustomException(INVALID_COMMENT_ID)); + + // When & Then + CustomException exception = assertThrows(CustomException.class, () -> + commentService.deleteCommentById(siteUser.getEmail(), post.getId(), invalidCommentId) + ); + assertThat(exception.getMessage()) + .isEqualTo(INVALID_COMMENT_ID.getMessage()); + assertThat(exception.getCode()) + .isEqualTo(INVALID_COMMENT_ID.getCode()); + } + + @Test + void 댓글을_삭제할_때_자신의_댓글이_아니라면_예외_응답을_반환한다() { + // Given + String invalidEmail = "invalidEmail@test.com"; + when(siteUserRepository.getByEmail(invalidEmail)).thenReturn(siteUser); + when(postRepository.getById(post.getId())).thenReturn(post); + when(commentRepository.getById(any())).thenReturn(parentComment_1); + + // When & Then + CustomException exception = assertThrows(CustomException.class, () -> + commentService.deleteCommentById(invalidEmail, post.getId(), parentComment_1.getId()) + ); + assertThat(exception.getMessage()) + .isEqualTo(INVALID_POST_ACCESS.getMessage()); + assertThat(exception.getCode()) + .isEqualTo(INVALID_POST_ACCESS.getCode()); + } +} From ef42470d4f290614b6738636cb03919433ecd855 Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 13 Aug 2024 11:26:37 +0900 Subject: [PATCH 10/13] =?UTF-8?q?feat:=20=EA=B2=8C=EC=8B=9C=EA=B8=80=20API?= =?UTF-8?q?=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../board/service/BoardService.java | 12 +++++++----- .../post/controller/PostController.java | 5 +++-- .../post/dto/PostCreateRequest.java | 9 +++++++++ .../post/dto/PostUpdateRequest.java | 9 +++++++++ .../post/service/PostService.java | 11 ++++++++++- .../unit/service/PostServiceTest.java | 16 ++++++++++++++++ 6 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/example/solidconnection/board/service/BoardService.java b/src/main/java/com/example/solidconnection/board/service/BoardService.java index 3a74b919c..1ec5ac8b0 100644 --- a/src/main/java/com/example/solidconnection/board/service/BoardService.java +++ b/src/main/java/com/example/solidconnection/board/service/BoardService.java @@ -9,12 +9,15 @@ import com.example.solidconnection.type.BoardCode; import com.example.solidconnection.type.PostCategory; import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.EnumUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.stream.Collectors; +import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_POST_CATEGORY; + @Service @RequiredArgsConstructor public class BoardService { @@ -28,12 +31,11 @@ private String validateCode(String code) { } } - private PostCategory validatePostCategory(String postCategory) { - try { - return PostCategory.valueOf(postCategory); - } catch (IllegalArgumentException ex) { - throw new CustomException(ErrorCode.INVALID_POST_CATEGORY); + private PostCategory validatePostCategory(String category){ + if(!EnumUtils.isValidEnum(PostCategory.class, category)){ + throw new CustomException(INVALID_POST_CATEGORY); } + return PostCategory.valueOf(category); } @Transactional(readOnly = true) diff --git a/src/main/java/com/example/solidconnection/post/controller/PostController.java b/src/main/java/com/example/solidconnection/post/controller/PostController.java index 022ca8b61..fd452af8a 100644 --- a/src/main/java/com/example/solidconnection/post/controller/PostController.java +++ b/src/main/java/com/example/solidconnection/post/controller/PostController.java @@ -4,6 +4,7 @@ import com.example.solidconnection.post.service.PostService; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.security.SecurityRequirements; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -28,7 +29,7 @@ public class PostController { public ResponseEntity createPost( Principal principal, @PathVariable("code") String code, - @RequestPart("postCreateRequest") PostCreateRequest postCreateRequest, + @Valid @RequestPart("postCreateRequest") PostCreateRequest postCreateRequest, @RequestParam(value = "file", required = false) List imageFile) { if (imageFile == null) { @@ -44,7 +45,7 @@ public ResponseEntity updatePost( Principal principal, @PathVariable("code") String code, @PathVariable("post_id") Long postId, - @RequestPart("postUpdateRequest") PostUpdateRequest postUpdateRequest, + @Valid @RequestPart("postUpdateRequest") PostUpdateRequest postUpdateRequest, @RequestParam(value = "file", required = false) List imageFile) { if (imageFile == null) { diff --git a/src/main/java/com/example/solidconnection/post/dto/PostCreateRequest.java b/src/main/java/com/example/solidconnection/post/dto/PostCreateRequest.java index 13cd6469b..03ab79686 100644 --- a/src/main/java/com/example/solidconnection/post/dto/PostCreateRequest.java +++ b/src/main/java/com/example/solidconnection/post/dto/PostCreateRequest.java @@ -4,11 +4,20 @@ import com.example.solidconnection.post.domain.Post; import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.type.PostCategory; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; public record PostCreateRequest( + @NotNull(message = "게시글 카테고리를 설정해주세요.") String postCategory, + @NotBlank(message = "게시글 제목은 빈 값일 수 없습니다.") + @Size(min = 1, max = 255, message = "댓글 내용은 최소 1자 이상, 최대 255자 이하여야 합니다.") String title, + @NotBlank(message = "게시글 내용은 빈 값일 수 없습니다.") + @Size(min = 1, max = 1000, message = "댓글 내용은 최소 1자 이상, 최대 255자 이하여야 합니다.") String content, + @NotNull(message = "게시글 질문여부를 설정해주세요.") Boolean isQuestion ) { diff --git a/src/main/java/com/example/solidconnection/post/dto/PostUpdateRequest.java b/src/main/java/com/example/solidconnection/post/dto/PostUpdateRequest.java index 9394932d7..b82b73685 100644 --- a/src/main/java/com/example/solidconnection/post/dto/PostUpdateRequest.java +++ b/src/main/java/com/example/solidconnection/post/dto/PostUpdateRequest.java @@ -1,8 +1,17 @@ package com.example.solidconnection.post.dto; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + public record PostUpdateRequest( + @NotNull(message = "게시글 카테고리를 설정해주세요.") String postCategory, + @NotBlank(message = "게시글 제목은 빈 값일 수 없습니다.") + @Size(min = 1, max = 255, message = "댓글 내용은 최소 1자 이상, 최대 255자 이하여야 합니다.") String title, + @NotBlank(message = "게시글 내용은 빈 값일 수 없습니다.") + @Size(min = 1, max = 1000, message = "댓글 내용은 최소 1자 이상, 최대 255자 이하여야 합니다.") String content ) { } diff --git a/src/main/java/com/example/solidconnection/post/service/PostService.java b/src/main/java/com/example/solidconnection/post/service/PostService.java index 52bd22310..d4ed3c081 100644 --- a/src/main/java/com/example/solidconnection/post/service/PostService.java +++ b/src/main/java/com/example/solidconnection/post/service/PostService.java @@ -19,8 +19,10 @@ import com.example.solidconnection.siteuser.repository.SiteUserRepository; import com.example.solidconnection.type.BoardCode; import com.example.solidconnection.type.ImgType; +import com.example.solidconnection.type.PostCategory; import com.example.solidconnection.util.RedisUtils; import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.EnumUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -69,6 +71,12 @@ private void validateQuestion(Post post) { } } + private void validatePostCategory(String category){ + if(!EnumUtils.isValidEnum(PostCategory.class, category)){ + throw new CustomException(INVALID_POST_CATEGORY); + } + } + private Boolean getIsOwner(Post post, String email) { return post.getSiteUser().getEmail().equals(email); } @@ -79,6 +87,7 @@ public PostCreateResponse createPost(String email, String code, PostCreateReques // 유효성 검증 String boardCode = validateCode(code); + validatePostCategory(postCreateRequest.postCategory()); validateFileSize(imageFile); // 객체 생성 @@ -146,7 +155,7 @@ public PostFindResponse findPostById(String email, String code, Long postId) { // caching && 어뷰징 방지 if (redisService.isPresent(redisUtils.getValidatePostViewCountRedisKey(email,postId))) { - redisService.increaseViewCountSync(redisUtils.getPostViewCountRedisKey(postId)); + redisService.increaseViewCount(redisUtils.getPostViewCountRedisKey(postId)); } return PostFindResponse.from( diff --git a/src/test/java/com/example/solidconnection/unit/service/PostServiceTest.java b/src/test/java/com/example/solidconnection/unit/service/PostServiceTest.java index c04c1485a..0901c2aa6 100644 --- a/src/test/java/com/example/solidconnection/unit/service/PostServiceTest.java +++ b/src/test/java/com/example/solidconnection/unit/service/PostServiceTest.java @@ -241,6 +241,22 @@ private List createMockImageFilesWithMoreThanFiveFiles() { .isEqualTo(INVALID_BOARD_CODE.getCode()); } + @Test + void 게시글을_등록할_때_유효한_카테고리가_아니라면_예외_응답을_반환한다() { + // Given + String invalidPostCategory = "invalidPostCategory"; + PostCreateRequest postCreateRequest = new PostCreateRequest( + invalidPostCategory, "title", "content", false); + + // When & Then + CustomException exception = assertThrows(CustomException.class, () -> postService + .createPost(siteUser.getEmail(), board.getCode(), postCreateRequest, Collections.emptyList())); + assertThat(exception.getMessage()) + .isEqualTo(INVALID_POST_CATEGORY.getMessage()); + assertThat(exception.getCode()) + .isEqualTo(INVALID_POST_CATEGORY.getCode()); + } + @Test void 게시글을_등록할_때_파일_수가_5개를_넘는다면_예외_응답을_반환한다() { // Given From 306ec01b80ed5933ed04150762a8526205d2659e Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 13 Aug 2024 11:27:24 +0900 Subject: [PATCH 11/13] =?UTF-8?q?refactor:=20=EC=A1=B0=ED=9A=8C=EC=88=98?= =?UTF-8?q?=20=EA=B0=B1=EC=8B=A0=20=ED=95=A8=EC=88=98=20=ED=95=A8=EC=88=98?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solidconnection/service/RedisService.java | 2 +- .../concurrency/PostViewCountConcurrencyTest.java | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/example/solidconnection/service/RedisService.java b/src/main/java/com/example/solidconnection/service/RedisService.java index 4776f1692..9816a264e 100644 --- a/src/main/java/com/example/solidconnection/service/RedisService.java +++ b/src/main/java/com/example/solidconnection/service/RedisService.java @@ -24,7 +24,7 @@ public RedisService(RedisTemplate redisTemplate, } // incr & set ttl -> lua - public void increaseViewCountSync(String key) { + public void increaseViewCount(String key) { redisTemplate.execute(incrViewCountLuaScript, Collections.singletonList(key), VIEW_COUNT_TTL.getValue()); } diff --git a/src/test/java/com/example/solidconnection/concurrency/PostViewCountConcurrencyTest.java b/src/test/java/com/example/solidconnection/concurrency/PostViewCountConcurrencyTest.java index 9eb936301..c2213993d 100644 --- a/src/test/java/com/example/solidconnection/concurrency/PostViewCountConcurrencyTest.java +++ b/src/test/java/com/example/solidconnection/concurrency/PostViewCountConcurrencyTest.java @@ -98,13 +98,15 @@ private Post createPost(Board board, SiteUser siteUser) { @Test public void 게시글을_조회할_때_조회수_동시성_문제를_해결한다() throws InterruptedException { + redisService.deleteKey(redisUtils.getValidatePostViewCountRedisKey(siteUser.getEmail(), post.getId())); + ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE); CountDownLatch doneSignal = new CountDownLatch(THREAD_NUMS); for (int i = 0; i < THREAD_NUMS; i++) { executorService.submit(() -> { try { - redisService.increaseViewCountSync(redisUtils.getPostViewCountRedisKey(post.getId())); + redisService.increaseViewCount(redisUtils.getPostViewCountRedisKey(post.getId())); } finally { doneSignal.countDown(); } @@ -118,7 +120,7 @@ private Post createPost(Board board, SiteUser siteUser) { System.err.println("ExecutorService did not terminate in the expected time."); } - Thread.sleep(SCHEDULING_DELAY_MS); + Thread.sleep(SCHEDULING_DELAY_MS+1000); assertEquals(THREAD_NUMS, postRepository.getById(post.getId()).getViewCount()); } @@ -136,7 +138,7 @@ private Post createPost(Board board, SiteUser siteUser) { try { boolean isFirstTime = redisService.isPresent(redisUtils.getValidatePostViewCountRedisKey(siteUser.getEmail(), post.getId())); if (isFirstTime) { - redisService.increaseViewCountSync(redisUtils.getPostViewCountRedisKey(post.getId())); + redisService.increaseViewCount(redisUtils.getPostViewCountRedisKey(post.getId())); } } finally { doneSignal.countDown(); @@ -149,7 +151,7 @@ private Post createPost(Board board, SiteUser siteUser) { try { boolean isFirstTime = redisService.isPresent(redisUtils.getValidatePostViewCountRedisKey(siteUser.getEmail(), post.getId())); if (isFirstTime) { - redisService.increaseViewCountSync(redisUtils.getPostViewCountRedisKey(post.getId())); + redisService.increaseViewCount(redisUtils.getPostViewCountRedisKey(post.getId())); } } finally { doneSignal.countDown(); @@ -164,7 +166,7 @@ private Post createPost(Board board, SiteUser siteUser) { System.err.println("ExecutorService did not terminate in the expected time."); } - Thread.sleep(SCHEDULING_DELAY_MS); + Thread.sleep(SCHEDULING_DELAY_MS+1000); assertEquals(2L, postRepository.getById(post.getId()).getViewCount()); } From 807246ba2f38dfd1981c276c609bcafec6c6f9b0 Mon Sep 17 00:00:00 2001 From: sewon Date: Wed, 14 Aug 2024 15:10:58 +0900 Subject: [PATCH 12/13] =?UTF-8?q?refactor:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=A0=91=EA=B7=BC=EC=A0=9C?= =?UTF-8?q?=ED=95=9C=EC=9E=90=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solidconnection/unit/repository/BoardRepositoryTest.java | 2 +- .../solidconnection/unit/repository/CommentRepositoryTest.java | 2 +- .../solidconnection/unit/repository/PostRepositoryTest.java | 2 +- .../example/solidconnection/unit/service/BoardServiceTest.java | 2 +- .../solidconnection/unit/service/CommentServiceTest.java | 2 +- .../example/solidconnection/unit/service/PostServiceTest.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/example/solidconnection/unit/repository/BoardRepositoryTest.java b/src/test/java/com/example/solidconnection/unit/repository/BoardRepositoryTest.java index c540954b1..9ea7ee0d9 100644 --- a/src/test/java/com/example/solidconnection/unit/repository/BoardRepositoryTest.java +++ b/src/test/java/com/example/solidconnection/unit/repository/BoardRepositoryTest.java @@ -27,7 +27,7 @@ @DataJpaTest @ActiveProfiles("test") @DisplayName("게시판 레포지토리 테스트") -public class BoardRepositoryTest { +class BoardRepositoryTest { @Autowired private PostRepository postRepository; @Autowired diff --git a/src/test/java/com/example/solidconnection/unit/repository/CommentRepositoryTest.java b/src/test/java/com/example/solidconnection/unit/repository/CommentRepositoryTest.java index def0710a0..7029dead9 100644 --- a/src/test/java/com/example/solidconnection/unit/repository/CommentRepositoryTest.java +++ b/src/test/java/com/example/solidconnection/unit/repository/CommentRepositoryTest.java @@ -33,7 +33,7 @@ @SpringBootTest @ActiveProfiles("local") @DisplayName("댓글 레포지토리 테스트") -public class CommentRepositoryTest { +class CommentRepositoryTest { @Autowired private PostRepository postRepository; @Autowired diff --git a/src/test/java/com/example/solidconnection/unit/repository/PostRepositoryTest.java b/src/test/java/com/example/solidconnection/unit/repository/PostRepositoryTest.java index b81ee952c..5fa873d06 100644 --- a/src/test/java/com/example/solidconnection/unit/repository/PostRepositoryTest.java +++ b/src/test/java/com/example/solidconnection/unit/repository/PostRepositoryTest.java @@ -31,7 +31,7 @@ @DataJpaTest @ActiveProfiles("test") @DisplayName("게시글 레포지토리 테스트") -public class PostRepositoryTest { +class PostRepositoryTest { @Autowired private PostRepository postRepository; @Autowired diff --git a/src/test/java/com/example/solidconnection/unit/service/BoardServiceTest.java b/src/test/java/com/example/solidconnection/unit/service/BoardServiceTest.java index 710546c9b..18c37b807 100644 --- a/src/test/java/com/example/solidconnection/unit/service/BoardServiceTest.java +++ b/src/test/java/com/example/solidconnection/unit/service/BoardServiceTest.java @@ -27,7 +27,7 @@ @ExtendWith(MockitoExtension.class) @DisplayName("게시판 서비스 테스트") -public class BoardServiceTest { +class BoardServiceTest { @InjectMocks BoardService boardService; @Mock diff --git a/src/test/java/com/example/solidconnection/unit/service/CommentServiceTest.java b/src/test/java/com/example/solidconnection/unit/service/CommentServiceTest.java index 5cab31efb..cb914288b 100644 --- a/src/test/java/com/example/solidconnection/unit/service/CommentServiceTest.java +++ b/src/test/java/com/example/solidconnection/unit/service/CommentServiceTest.java @@ -32,7 +32,7 @@ @ExtendWith(MockitoExtension.class) @DisplayName("댓글 서비스 테스트") -public class CommentServiceTest { +class CommentServiceTest { @InjectMocks CommentService commentService; @Mock diff --git a/src/test/java/com/example/solidconnection/unit/service/PostServiceTest.java b/src/test/java/com/example/solidconnection/unit/service/PostServiceTest.java index 0901c2aa6..7f19707b7 100644 --- a/src/test/java/com/example/solidconnection/unit/service/PostServiceTest.java +++ b/src/test/java/com/example/solidconnection/unit/service/PostServiceTest.java @@ -43,7 +43,7 @@ @ExtendWith(MockitoExtension.class) @DisplayName("게시글 서비스 테스트") -public class PostServiceTest { +class PostServiceTest { @InjectMocks PostService postService; @Mock From f40d658cdb9937edd2c4409862b5b364db4b74a7 Mon Sep 17 00:00:00 2001 From: sewon Date: Wed, 14 Aug 2024 23:26:10 +0900 Subject: [PATCH 13/13] =?UTF-8?q?refactor:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=8B=9C=20parentId=20=ED=8C=8C=EB=9D=BC?= =?UTF-8?q?=EB=AF=B8=ED=84=B0=20null=20=ED=97=88=EC=9A=A9=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20record=EB=A5=BC=20class=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/dto/CommentCreateRequest.java | 23 ++++++++++----- .../comment/service/CommentService.java | 3 +- .../unit/service/CommentServiceTest.java | 29 ++++++++----------- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/example/solidconnection/comment/dto/CommentCreateRequest.java b/src/main/java/com/example/solidconnection/comment/dto/CommentCreateRequest.java index 43942a9b1..c16c77323 100644 --- a/src/main/java/com/example/solidconnection/comment/dto/CommentCreateRequest.java +++ b/src/main/java/com/example/solidconnection/comment/dto/CommentCreateRequest.java @@ -3,17 +3,26 @@ import com.example.solidconnection.comment.domain.Comment; import com.example.solidconnection.post.domain.Post; import com.example.solidconnection.siteuser.domain.SiteUser; +import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Size; +import lombok.Getter; -import java.util.Optional; +@Getter +public class CommentCreateRequest { + + @NotBlank(message = "댓글 내용은 빈 값일 수 없습니다.") + @Size(min = 1, max = 255, message = "댓글 내용은 최소 1자 이상, 최대 255자 이하여야 합니다.") + String content; + + @Nullable + Long parentId; + + public CommentCreateRequest(String content, @Nullable Long parentId) { + this.content = content; + this.parentId = parentId; + } -public record CommentCreateRequest( - @NotBlank(message = "댓글 내용은 빈 값일 수 없습니다.") - @Size(min = 1, max = 255, message = "댓글 내용은 최소 1자 이상, 최대 255자 이하여야 합니다.") - String content, - Optional parentId // https://www.baeldung.com/java-record-optional-param -) { public Comment toEntity(SiteUser siteUser, Post post, Comment parentComment) { Comment comment = new Comment( diff --git a/src/main/java/com/example/solidconnection/comment/service/CommentService.java b/src/main/java/com/example/solidconnection/comment/service/CommentService.java index d4f4fd9ca..4fde0c1cf 100644 --- a/src/main/java/com/example/solidconnection/comment/service/CommentService.java +++ b/src/main/java/com/example/solidconnection/comment/service/CommentService.java @@ -13,6 +13,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import static com.example.solidconnection.custom.exception.ErrorCode.CAN_NOT_UPDATE_DEPRECATED_COMMENT; @@ -56,7 +57,7 @@ public CommentCreateResponse createComment(String email, Long postId, CommentCre SiteUser siteUser = siteUserRepository.getByEmail(email); Post post = postRepository.getById(postId); - Comment parentComment = commentCreateRequest.parentId() + Comment parentComment = Optional.ofNullable(commentCreateRequest.getParentId()) .map(commentRepository::getById) .orElse(null); Comment createdComment = commentRepository.save(commentCreateRequest.toEntity(siteUser, post, parentComment)); diff --git a/src/test/java/com/example/solidconnection/unit/service/CommentServiceTest.java b/src/test/java/com/example/solidconnection/unit/service/CommentServiceTest.java index cb914288b..8a90b275b 100644 --- a/src/test/java/com/example/solidconnection/unit/service/CommentServiceTest.java +++ b/src/test/java/com/example/solidconnection/unit/service/CommentServiceTest.java @@ -20,7 +20,6 @@ import org.mockito.junit.jupiter.MockitoExtension; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; import static com.example.solidconnection.custom.exception.ErrorCode.*; @@ -138,8 +137,7 @@ private Boolean isOwner(Comment comment, String email) { void 부모_댓글을_등록한다() { // Given CommentCreateRequest commentCreateRequest = new CommentCreateRequest( - "parent", - Optional.empty() + "parent", null ); when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); when(postRepository.getById(post.getId())).thenReturn(post); @@ -151,10 +149,10 @@ private Boolean isOwner(Comment comment, String email) { // Then assertEquals(commentCreateResponse, CommentCreateResponse.from(parentComment_1)); - verify(commentRepository,times(0)) + verify(commentRepository, times(0)) .getById(any(Long.class)); - verify(commentRepository,times(1)) - .save(commentCreateRequest.toEntity(siteUser,post, parentComment_1)); + verify(commentRepository, times(1)) + .save(commentCreateRequest.toEntity(siteUser, post, parentComment_1)); } @Test @@ -162,8 +160,7 @@ private Boolean isOwner(Comment comment, String email) { // Given Long parentCommentId = 1L; CommentCreateRequest commentCreateRequest = new CommentCreateRequest( - "child", - Optional.of(parentCommentId) + "child", parentCommentId ); when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); when(postRepository.getById(post.getId())).thenReturn(post); @@ -176,10 +173,10 @@ private Boolean isOwner(Comment comment, String email) { // Then assertEquals(commentCreateResponse, CommentCreateResponse.from(p1s_childComment)); - verify(commentRepository,times(1)) + verify(commentRepository, times(1)) .getById(parentCommentId); - verify(commentRepository,times(1)) - .save(commentCreateRequest.toEntity(siteUser,post, parentComment_1)); + verify(commentRepository, times(1)) + .save(commentCreateRequest.toEntity(siteUser, post, parentComment_1)); } @@ -188,8 +185,7 @@ private Boolean isOwner(Comment comment, String email) { // Given Long invalidPostId = -1L; CommentCreateRequest commentCreateRequest = new CommentCreateRequest( - "child", - Optional.empty() + "child", null ); when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); when(postRepository.getById(invalidPostId)).thenThrow(new CustomException(INVALID_POST_ID)); @@ -202,7 +198,7 @@ private Boolean isOwner(Comment comment, String email) { .isEqualTo(INVALID_POST_ID.getMessage()); assertThat(exception.getCode()) .isEqualTo(INVALID_POST_ID.getCode()); - verify(commentRepository,times(0)) + verify(commentRepository, times(0)) .save(any(Comment.class)); } @@ -211,8 +207,7 @@ private Boolean isOwner(Comment comment, String email) { // Given Long invalidParentCommentId = -1L; CommentCreateRequest commentCreateRequest = new CommentCreateRequest( - "child", - Optional.of(invalidParentCommentId) + "child", invalidParentCommentId ); when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); when(postRepository.getById(post.getId())).thenReturn(post); @@ -226,7 +221,7 @@ private Boolean isOwner(Comment comment, String email) { .isEqualTo(INVALID_COMMENT_ID.getMessage()); assertThat(exception.getCode()) .isEqualTo(INVALID_COMMENT_ID.getCode()); - verify(commentRepository,times(0)) + verify(commentRepository, times(0)) .save(any(Comment.class)); }