From dfe608df80d2c2c2627dd4acdf932363c67ce8d1 Mon Sep 17 00:00:00 2001 From: youKeon Date: Tue, 15 Aug 2023 01:22:09 +0900 Subject: [PATCH 1/9] =?UTF-8?q?refactor=20:=20Comment=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/Dockerfile | 8 -- .../comment/controller/CommentController.java | 25 +++--- .../domain/comment/dto/CommentDto.java | 79 ------------------- .../dto/request/CreateCommentRequest.java | 36 +++++++++ .../dto/request/UpdateCommentRequest.java | 17 ++++ .../dto/response/CreateCommentResponse.java | 14 ++++ .../GetCommentWithMaskingResponse.java | 20 +++++ .../dto/response/GetReplyListResponse.java | 29 +++++++ .../repository/CommentCustomRepository.java | 7 +- .../CommentCustomRepositoryImpl.java | 19 ++--- .../comment/repository/CommentRepository.java | 3 - .../comment/service/CommentService.java | 28 ++++--- .../domain/project/dto/ProjectDto.java | 2 +- .../domain/project/mapper/ProjectMapper.java | 2 +- .../project/service/ProjectService.java | 7 +- .../controller/CommentControllerTest.java | 50 ++---------- .../comment/service/CommentServiceTest.java | 15 ++-- 17 files changed, 178 insertions(+), 183 deletions(-) delete mode 100644 backend/Dockerfile delete mode 100644 backend/src/main/java/com/graphy/backend/domain/comment/dto/CommentDto.java create mode 100644 backend/src/main/java/com/graphy/backend/domain/comment/dto/request/CreateCommentRequest.java create mode 100644 backend/src/main/java/com/graphy/backend/domain/comment/dto/request/UpdateCommentRequest.java create mode 100644 backend/src/main/java/com/graphy/backend/domain/comment/dto/response/CreateCommentResponse.java create mode 100644 backend/src/main/java/com/graphy/backend/domain/comment/dto/response/GetCommentWithMaskingResponse.java create mode 100644 backend/src/main/java/com/graphy/backend/domain/comment/dto/response/GetReplyListResponse.java diff --git a/backend/Dockerfile b/backend/Dockerfile deleted file mode 100644 index 99a92327..00000000 --- a/backend/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM openjdk:11-jre-slim-buster -VOLUME /tmp - -ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.9.0/wait /wait -RUN chmod +x /wait - -COPY ./build/libs/backend-0.0.1-SNAPSHOT.jar app.jar -CMD /wait && java -jar /app.jar \ No newline at end of file diff --git a/backend/src/main/java/com/graphy/backend/domain/comment/controller/CommentController.java b/backend/src/main/java/com/graphy/backend/domain/comment/controller/CommentController.java index d40d4432..417b45cf 100644 --- a/backend/src/main/java/com/graphy/backend/domain/comment/controller/CommentController.java +++ b/backend/src/main/java/com/graphy/backend/domain/comment/controller/CommentController.java @@ -1,5 +1,9 @@ package com.graphy.backend.domain.comment.controller; +import com.graphy.backend.domain.comment.dto.request.CreateCommentRequest; +import com.graphy.backend.domain.comment.dto.request.UpdateCommentRequest; +import com.graphy.backend.domain.comment.dto.response.CreateCommentResponse; +import com.graphy.backend.domain.comment.dto.response.GetReplyListResponse; import com.graphy.backend.domain.comment.service.CommentService; import com.graphy.backend.domain.member.domain.Member; import com.graphy.backend.global.auth.jwt.annotation.CurrentUser; @@ -16,7 +20,6 @@ import java.util.List; -import static com.graphy.backend.domain.comment.dto.CommentDto.*; @Tag(name = "CommentController", description = "댓글 관련 API") @RestController @@ -27,17 +30,19 @@ public class CommentController { @Operation(summary = "createComment", description = "댓글 생성") @PostMapping - public ResponseEntity createComment(@Validated @RequestBody CreateCommentRequest dto, @CurrentUser Member loginUser) { - CreateCommentResponse response = commentService.createComment(dto, loginUser); + public ResponseEntity commentAdd(@Validated @RequestBody CreateCommentRequest dto, + @CurrentUser Member loginUser) { + commentService.addComment(dto, loginUser); return ResponseEntity.status(HttpStatus.CREATED) - .body(ResultResponse.of(ResultCode.COMMENT_CREATE_SUCCESS, response)); + .body(ResultResponse.of(ResultCode.COMMENT_CREATE_SUCCESS)); } @Operation(summary = "updateComment", description = "댓글 수정") @PutMapping("/{commentId}") - public ResponseEntity updateComment(@Validated @RequestBody UpdateCommentRequest dto, @PathVariable Long commentId, @CurrentUser Member loginUser) { - commentService.updateComment(commentId, dto); + public ResponseEntity commentUpdate(@Validated @RequestBody UpdateCommentRequest dto, + @PathVariable Long commentId) { + commentService.modifyComment(commentId, dto); return ResponseEntity.status(HttpStatus.OK) .body(ResultResponse.of(ResultCode.COMMENT_UPDATE_SUCCESS)); @@ -45,7 +50,7 @@ public ResponseEntity updateComment(@Validated @RequestBody Upda @Operation(summary = "deleteComment", description = "댓글 삭제") @DeleteMapping("/{id}") - public ResponseEntity deleteComment(@PathVariable Long id, @CurrentUser Member loginUser) { + public ResponseEntity commentDelete(@PathVariable Long id) { commentService.deleteComment(id); return ResponseEntity.status(HttpStatus.OK) .body(ResultResponse.of(ResultCode.COMMENT_DELETE_SUCCESS)); @@ -53,9 +58,9 @@ public ResponseEntity deleteComment(@PathVariable Long id, @Curr @Operation(summary = "getReComment", description = "답글 조회") @GetMapping("/{commentId}") - public ResponseEntity getReComment(@PathVariable Long commentId) { - List replyList = commentService.getReplyList(commentId); + public ResponseEntity commentDetails(@PathVariable Long commentId) { + List result = commentService.findCommentList(commentId); return ResponseEntity.status(HttpStatus.OK) - .body(ResultResponse.of(ResultCode.RECOMMENT_GET_SUCCESS, replyList)); + .body(ResultResponse.of(ResultCode.RECOMMENT_GET_SUCCESS, result)); } } diff --git a/backend/src/main/java/com/graphy/backend/domain/comment/dto/CommentDto.java b/backend/src/main/java/com/graphy/backend/domain/comment/dto/CommentDto.java deleted file mode 100644 index 15e640b3..00000000 --- a/backend/src/main/java/com/graphy/backend/domain/comment/dto/CommentDto.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.graphy.backend.domain.comment.dto; - -import com.graphy.backend.domain.comment.domain.Comment; -import com.graphy.backend.domain.member.domain.Member; -import com.graphy.backend.domain.project.domain.Project; -import lombok.*; - -import javax.validation.constraints.NotBlank; -import java.time.LocalDateTime; - -public class CommentDto { - - @Getter - @AllArgsConstructor - @NoArgsConstructor - public static class CreateCommentRequest { - - @NotBlank - private String content; - - private Long projectId; - - private Long parentId; - - public static Comment to(CreateCommentRequest createCommentRequest, Project project, Comment parentComment, Member member) { - return Comment.builder() - .member(member) - .content(createCommentRequest.getContent()) - .parent(parentComment) - .project(project) - .build(); - } - } - - @Getter - @NoArgsConstructor - @AllArgsConstructor - public static class UpdateCommentRequest { - @NotBlank - private String content; - } - - - @Getter - @AllArgsConstructor - @NoArgsConstructor - public static class CreateCommentResponse { - private Long commentId; - } - - @Getter - @AllArgsConstructor - @NoArgsConstructor - public static class GetCommentWithMaskingResponse { - private String content; - private Long commentId; - private LocalDateTime createdAt; - private String nickname; - private Long childCount; - } - - @Getter - @AllArgsConstructor - @NoArgsConstructor - public static class GetReplyListResponse { - private String nickname; - private String content; - private Long commentId; - private LocalDateTime createdAt; - - - public GetReplyListResponse(String content, Long commentId, LocalDateTime createdAt, String nickname) { - this.nickname = nickname; - this.content = content; - this.commentId = commentId; - this.createdAt = createdAt; - } - } -} \ No newline at end of file diff --git a/backend/src/main/java/com/graphy/backend/domain/comment/dto/request/CreateCommentRequest.java b/backend/src/main/java/com/graphy/backend/domain/comment/dto/request/CreateCommentRequest.java new file mode 100644 index 00000000..0e3b66b0 --- /dev/null +++ b/backend/src/main/java/com/graphy/backend/domain/comment/dto/request/CreateCommentRequest.java @@ -0,0 +1,36 @@ +package com.graphy.backend.domain.comment.dto.request; + +import com.graphy.backend.domain.comment.domain.Comment; +import com.graphy.backend.domain.member.domain.Member; +import com.graphy.backend.domain.project.domain.Project; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class CreateCommentRequest { + + @NotBlank + private String content; + + private Long projectId; + + private Long parentId; + + public Comment toEntity(Project project, + Comment parentComment, + Member member) { + return Comment.builder() + .member(member) + .content(content) + .parent(parentComment) + .project(project) + .build(); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/graphy/backend/domain/comment/dto/request/UpdateCommentRequest.java b/backend/src/main/java/com/graphy/backend/domain/comment/dto/request/UpdateCommentRequest.java new file mode 100644 index 00000000..70b424ee --- /dev/null +++ b/backend/src/main/java/com/graphy/backend/domain/comment/dto/request/UpdateCommentRequest.java @@ -0,0 +1,17 @@ +package com.graphy.backend.domain.comment.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class UpdateCommentRequest { + @NotBlank + private String content; +} \ No newline at end of file diff --git a/backend/src/main/java/com/graphy/backend/domain/comment/dto/response/CreateCommentResponse.java b/backend/src/main/java/com/graphy/backend/domain/comment/dto/response/CreateCommentResponse.java new file mode 100644 index 00000000..a4ccb1c1 --- /dev/null +++ b/backend/src/main/java/com/graphy/backend/domain/comment/dto/response/CreateCommentResponse.java @@ -0,0 +1,14 @@ +package com.graphy.backend.domain.comment.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class CreateCommentResponse { + private Long commentId; +} diff --git a/backend/src/main/java/com/graphy/backend/domain/comment/dto/response/GetCommentWithMaskingResponse.java b/backend/src/main/java/com/graphy/backend/domain/comment/dto/response/GetCommentWithMaskingResponse.java new file mode 100644 index 00000000..10bedd83 --- /dev/null +++ b/backend/src/main/java/com/graphy/backend/domain/comment/dto/response/GetCommentWithMaskingResponse.java @@ -0,0 +1,20 @@ +package com.graphy.backend.domain.comment.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class GetCommentWithMaskingResponse { + private String content; + private Long commentId; + private LocalDateTime createdAt; + private String nickname; + private Long childCount; +} \ No newline at end of file diff --git a/backend/src/main/java/com/graphy/backend/domain/comment/dto/response/GetReplyListResponse.java b/backend/src/main/java/com/graphy/backend/domain/comment/dto/response/GetReplyListResponse.java new file mode 100644 index 00000000..863fd75c --- /dev/null +++ b/backend/src/main/java/com/graphy/backend/domain/comment/dto/response/GetReplyListResponse.java @@ -0,0 +1,29 @@ +package com.graphy.backend.domain.comment.dto.response; + +import com.graphy.backend.domain.comment.domain.Comment; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class GetReplyListResponse { + private String nickname; + private String content; + private Long commentId; + private LocalDateTime createdAt; + + public static GetReplyListResponse from(Comment comment) { + return GetReplyListResponse.builder() + .nickname(comment.getMember().getNickname()) + .content(comment.getContent()) + .commentId(comment.getId()) + .createdAt(comment.getCreatedAt()) + .build(); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/graphy/backend/domain/comment/repository/CommentCustomRepository.java b/backend/src/main/java/com/graphy/backend/domain/comment/repository/CommentCustomRepository.java index b422275a..923962c7 100644 --- a/backend/src/main/java/com/graphy/backend/domain/comment/repository/CommentCustomRepository.java +++ b/backend/src/main/java/com/graphy/backend/domain/comment/repository/CommentCustomRepository.java @@ -1,12 +1,13 @@ package com.graphy.backend.domain.comment.repository; +import com.graphy.backend.domain.comment.domain.Comment; +import com.graphy.backend.domain.comment.dto.response.GetCommentWithMaskingResponse; +import com.graphy.backend.domain.comment.dto.response.GetReplyListResponse; import java.util.List; -import static com.graphy.backend.domain.comment.dto.CommentDto.*; - public interface CommentCustomRepository { List findCommentsWithMasking(Long id); - List findReplyList(Long parentId); + List findReplyList(Long parentId); } diff --git a/backend/src/main/java/com/graphy/backend/domain/comment/repository/CommentCustomRepositoryImpl.java b/backend/src/main/java/com/graphy/backend/domain/comment/repository/CommentCustomRepositoryImpl.java index 9de0af02..d7ffa53d 100644 --- a/backend/src/main/java/com/graphy/backend/domain/comment/repository/CommentCustomRepositoryImpl.java +++ b/backend/src/main/java/com/graphy/backend/domain/comment/repository/CommentCustomRepositoryImpl.java @@ -1,15 +1,18 @@ package com.graphy.backend.domain.comment.repository; +import com.graphy.backend.domain.comment.domain.Comment; import com.graphy.backend.domain.comment.domain.QComment; +import com.graphy.backend.domain.comment.dto.response.GetCommentWithMaskingResponse; +import com.graphy.backend.domain.comment.dto.response.GetReplyListResponse; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.CaseBuilder; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; + import java.util.List; import static com.graphy.backend.domain.comment.domain.QComment.comment; -import static com.graphy.backend.domain.comment.dto.CommentDto.*; import static com.graphy.backend.domain.member.domain.QMember.member; @RequiredArgsConstructor @@ -41,18 +44,10 @@ public List findCommentsWithMasking(Long id) { } @Override - public List findReplyList(Long parentId) { + public List findReplyList(Long parentId) { return jpaQueryFactory - .select(Projections.constructor(GetReplyListResponse.class, - new CaseBuilder() - .when(comment.isDeleted.isTrue()).then("삭제된 댓글입니다.") - .otherwise(comment.content), - comment.id, - comment.createdAt, - member.nickname - )) - .from(comment) - .join(comment.member, member) + .selectFrom(comment) + .join(comment.member, member).fetchJoin() .where(comment.parent.id.eq(parentId)) .orderBy(comment.createdAt.asc()) .fetch(); diff --git a/backend/src/main/java/com/graphy/backend/domain/comment/repository/CommentRepository.java b/backend/src/main/java/com/graphy/backend/domain/comment/repository/CommentRepository.java index 35b495e0..0b80e184 100644 --- a/backend/src/main/java/com/graphy/backend/domain/comment/repository/CommentRepository.java +++ b/backend/src/main/java/com/graphy/backend/domain/comment/repository/CommentRepository.java @@ -2,10 +2,7 @@ import com.graphy.backend.domain.comment.domain.Comment; 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; public interface CommentRepository extends JpaRepository, CommentCustomRepository { diff --git a/backend/src/main/java/com/graphy/backend/domain/comment/service/CommentService.java b/backend/src/main/java/com/graphy/backend/domain/comment/service/CommentService.java index 61f5d267..c4963219 100644 --- a/backend/src/main/java/com/graphy/backend/domain/comment/service/CommentService.java +++ b/backend/src/main/java/com/graphy/backend/domain/comment/service/CommentService.java @@ -1,11 +1,13 @@ package com.graphy.backend.domain.comment.service; import com.graphy.backend.domain.comment.domain.Comment; +import com.graphy.backend.domain.comment.dto.request.CreateCommentRequest; +import com.graphy.backend.domain.comment.dto.request.UpdateCommentRequest; +import com.graphy.backend.domain.comment.dto.response.GetReplyListResponse; import com.graphy.backend.domain.comment.repository.CommentRepository; import com.graphy.backend.domain.member.domain.Member; import com.graphy.backend.domain.project.domain.Project; import com.graphy.backend.domain.project.repository.ProjectRepository; -import com.graphy.backend.global.auth.jwt.CustomUserDetailsService; import com.graphy.backend.global.error.ErrorCode; import com.graphy.backend.global.error.exception.EmptyResultException; import lombok.RequiredArgsConstructor; @@ -13,19 +15,18 @@ import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.stream.Collectors; -import static com.graphy.backend.domain.comment.dto.CommentDto.*; @Service +@Transactional @RequiredArgsConstructor public class CommentService { private final CommentRepository commentRepository; - private final CustomUserDetailsService customUserDetailsService; private final ProjectRepository projectRepository; - public CreateCommentResponse createComment(CreateCommentRequest dto, Member loginUser) { - + public void addComment(CreateCommentRequest dto, Member loginUser) { Project project = projectRepository.findById(dto.getProjectId()) .orElseThrow(() -> new EmptyResultException(ErrorCode.PROJECT_DELETED_OR_NOT_EXIST)); @@ -35,20 +36,17 @@ public CreateCommentResponse createComment(CreateCommentRequest dto, Member logi .orElseThrow(() -> new EmptyResultException(ErrorCode.COMMENT_DELETED_OR_NOT_EXIST)); } - Comment entity = CreateCommentRequest.to(dto, project, parentComment, loginUser); - return new CreateCommentResponse(commentRepository.save(entity).getId()); + Comment comment = dto.toEntity(project, parentComment, loginUser); + commentRepository.save(comment); } - @Transactional - public Long updateComment(Long commentId, UpdateCommentRequest dto) { + public void modifyComment(Long commentId, UpdateCommentRequest dto) { Comment comment = commentRepository.findById(commentId) .orElseThrow(() -> new EmptyResultException(ErrorCode.COMMENT_DELETED_OR_NOT_EXIST)); comment.updateContent(dto.getContent()); - return comment.getId(); } - @Transactional public void deleteComment(Long id) { Comment comment = commentRepository.findById(id) .orElseThrow(() -> new EmptyResultException(ErrorCode.PROJECT_DELETED_OR_NOT_EXIST)); @@ -56,7 +54,11 @@ public void deleteComment(Long id) { comment.delete(); } - public List getReplyList(Long commentId) { - return commentRepository.findReplyList(commentId); + public List findCommentList(Long commentId) { + List commentList = commentRepository.findReplyList(commentId); + return commentList.stream() + .map(GetReplyListResponse::from) + .collect(Collectors.toList()); + } } diff --git a/backend/src/main/java/com/graphy/backend/domain/project/dto/ProjectDto.java b/backend/src/main/java/com/graphy/backend/domain/project/dto/ProjectDto.java index 1258582a..0c8ffe7a 100644 --- a/backend/src/main/java/com/graphy/backend/domain/project/dto/ProjectDto.java +++ b/backend/src/main/java/com/graphy/backend/domain/project/dto/ProjectDto.java @@ -1,5 +1,6 @@ package com.graphy.backend.domain.project.dto; +import com.graphy.backend.domain.comment.dto.response.GetCommentWithMaskingResponse; import com.graphy.backend.domain.member.dto.MemberDto; import lombok.*; @@ -8,7 +9,6 @@ import java.time.LocalDateTime; import java.util.List; -import static com.graphy.backend.domain.comment.dto.CommentDto.*; public class ProjectDto { diff --git a/backend/src/main/java/com/graphy/backend/domain/project/mapper/ProjectMapper.java b/backend/src/main/java/com/graphy/backend/domain/project/mapper/ProjectMapper.java index 101c00c7..d2be8b53 100644 --- a/backend/src/main/java/com/graphy/backend/domain/project/mapper/ProjectMapper.java +++ b/backend/src/main/java/com/graphy/backend/domain/project/mapper/ProjectMapper.java @@ -1,5 +1,6 @@ package com.graphy.backend.domain.project.mapper; +import com.graphy.backend.domain.comment.dto.response.GetCommentWithMaskingResponse; import com.graphy.backend.domain.member.domain.Member; import com.graphy.backend.domain.member.dto.MemberDto; import com.graphy.backend.domain.project.domain.Project; @@ -10,7 +11,6 @@ import java.util.List; -import static com.graphy.backend.domain.comment.dto.CommentDto.*; import static com.graphy.backend.domain.project.dto.ProjectDto.*; @Component diff --git a/backend/src/main/java/com/graphy/backend/domain/project/service/ProjectService.java b/backend/src/main/java/com/graphy/backend/domain/project/service/ProjectService.java index 40f0ca7f..4f99c746 100644 --- a/backend/src/main/java/com/graphy/backend/domain/project/service/ProjectService.java +++ b/backend/src/main/java/com/graphy/backend/domain/project/service/ProjectService.java @@ -1,5 +1,6 @@ package com.graphy.backend.domain.project.service; +import com.graphy.backend.domain.comment.dto.response.GetCommentWithMaskingResponse; import com.graphy.backend.domain.comment.repository.CommentRepository; import com.graphy.backend.domain.member.domain.Member; import com.graphy.backend.domain.project.domain.Project; @@ -18,6 +19,7 @@ import com.graphy.backend.global.error.exception.LongRequestException; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; +import org.springframework.core.io.ClassPathResource; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -25,12 +27,15 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import javax.annotation.PostConstruct; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; import java.util.stream.Collectors; -import static com.graphy.backend.domain.comment.dto.CommentDto.*; import static com.graphy.backend.domain.project.dto.ProjectDto.*; import static com.graphy.backend.global.config.ChatGPTConfig.MAX_REQUEST_TOKEN; diff --git a/backend/src/test/java/com/graphy/backend/domain/comment/controller/CommentControllerTest.java b/backend/src/test/java/com/graphy/backend/domain/comment/controller/CommentControllerTest.java index c1b435b1..ea684f92 100644 --- a/backend/src/test/java/com/graphy/backend/domain/comment/controller/CommentControllerTest.java +++ b/backend/src/test/java/com/graphy/backend/domain/comment/controller/CommentControllerTest.java @@ -1,13 +1,14 @@ package com.graphy.backend.domain.comment.controller; import com.graphy.backend.domain.comment.domain.Comment; -import com.graphy.backend.domain.comment.dto.CommentDto; -import com.graphy.backend.domain.comment.dto.ReplyListDto; +import com.graphy.backend.domain.comment.dto.request.CreateCommentRequest; +import com.graphy.backend.domain.comment.dto.request.UpdateCommentRequest; +import com.graphy.backend.domain.comment.dto.response.GetReplyListResponse; import com.graphy.backend.domain.comment.service.CommentService; -import com.graphy.backend.domain.project.service.ProjectService; import com.graphy.backend.global.auth.jwt.TokenProvider; import com.graphy.backend.global.auth.redis.repository.RefreshTokenRepository; import com.graphy.backend.test.MockApiTest; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -60,11 +61,11 @@ public void setup(RestDocumentationContextProvider provider) { @DisplayName("댓글 생성 API 테스트") void createCommentTest() throws Exception { // given - CommentDto.CreateCommentRequest dto = new CommentDto.CreateCommentRequest("test", 1L, null); + CreateCommentRequest dto = new CreateCommentRequest("test", 1L, null); // when String body = objectMapper.writeValueAsString(dto); - when(commentService.createComment(dto)).thenReturn(any()); + when(commentService.addComment(dto)).thenReturn(any()); mvc.perform(post("/api/v1/comments") .content(body) .contentType(MediaType.APPLICATION_JSON)) @@ -80,9 +81,9 @@ void updateCommentTest() throws Exception { String updatedContent = "수정된 내용"; - CommentDto.UpdateCommentRequest commentRequest = new CommentDto.UpdateCommentRequest(updatedContent); + UpdateCommentRequest commentRequest = new UpdateCommentRequest(updatedContent); - given(commentService.updateComment(commentId, commentRequest)).willReturn(commentId); + given(commentService.modifyComment(commentId, commentRequest)).willReturn(commentId); // when String body = objectMapper.writeValueAsString(commentRequest); @@ -112,39 +113,4 @@ void deleteCommentTest() throws Exception { preprocessResponse(prettyPrint())) ); } - - @Test - @DisplayName("답글 조회 API 테스트") - public void getReplyList() throws Exception { - //given - List dtoList = Arrays.asList(new ReplyListDto() { - @Override - public String getNickname() { - return null; - } - - @Override - public String getContent() { - return "test"; - } - - @Override - public Long getCommentId() { - return 1L; - } - - @Override - public LocalDateTime getCreatedAt() { - return LocalDateTime.now(); - } - }); - - given(commentService.getReplyList(any())).willReturn(dtoList); - - //then - mvc.perform(get("/api/v1/comments/{commentId}", 1L)) - .andExpect(status().isOk()) - .andDo(print()) - .andDo(document("reply-get", preprocessResponse(prettyPrint()))); - } } \ No newline at end of file diff --git a/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java b/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java index a0412b18..2fe24752 100644 --- a/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java +++ b/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java @@ -16,12 +16,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.security.test.context.support.WithMockUser; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.InvalidMarkException; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -66,7 +61,7 @@ void createCommentTest() { .willReturn(member); //when - CreateCommentResponse response = commentService.createComment(dto); + CreateCommentResponse response = commentService.addComment(dto); //then Comment findComment = commentRepository.findById(response.getCommentId()).get(); @@ -97,7 +92,7 @@ void createCommentTest2() { //when - CreateCommentResponse response = commentService.createComment(dto); + CreateCommentResponse response = commentService.addComment(dto); //then Comment findComment = commentRepository.findById(response.getCommentId()).get(); @@ -137,7 +132,7 @@ public void updateComment() throws Exception { //then assertTrue(comment.getContent().equals("수정 후")); - Long result = commentService.updateComment(1L, commentRequest); + Long result = commentService.modifyComment(1L, commentRequest); assertTrue(result==1L); } @@ -195,7 +190,7 @@ public LocalDateTime getCreatedAt() { // when when(commentRepository.findReplyList(1L)).thenReturn(list); - List result = commentService.getReplyList(1L); + List result = commentService.findCommentList(1L); //then assertTrue(result.get(0).getContent().equals("comment1")); @@ -223,7 +218,7 @@ void updateCommentTest() { //then assertThrows(EmptyResultDataAccessException.class, () -> { - commentService.updateComment(1L, commentRequest); + commentService.modifyComment(1L, commentRequest); }); } } \ No newline at end of file From 649546e0289d287e9ddb7209cf67732fb1e88edd Mon Sep 17 00:00:00 2001 From: youKeon Date: Wed, 16 Aug 2023 02:33:15 +0900 Subject: [PATCH 2/9] =?UTF-8?q?test=20:=20Comment=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EA=B3=84?= =?UTF-8?q?=EC=B8=B5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=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 --- .../controller/CommentControllerTest.java | 281 +++++++++++++++--- .../comment/service/CommentServiceTest.java | 129 -------- .../controller/MemberControllerTest.java | 3 +- .../controller/ProjectControllerTest.java | 41 +-- .../project/service/ProjectServiceTest.java | 19 +- .../com/graphy/backend/test/MockApiTest.java | 10 +- 6 files changed, 247 insertions(+), 236 deletions(-) diff --git a/backend/src/test/java/com/graphy/backend/domain/comment/controller/CommentControllerTest.java b/backend/src/test/java/com/graphy/backend/domain/comment/controller/CommentControllerTest.java index ea684f92..62e0b67b 100644 --- a/backend/src/test/java/com/graphy/backend/domain/comment/controller/CommentControllerTest.java +++ b/backend/src/test/java/com/graphy/backend/domain/comment/controller/CommentControllerTest.java @@ -5,10 +5,10 @@ import com.graphy.backend.domain.comment.dto.request.UpdateCommentRequest; import com.graphy.backend.domain.comment.dto.response.GetReplyListResponse; import com.graphy.backend.domain.comment.service.CommentService; -import com.graphy.backend.global.auth.jwt.TokenProvider; -import com.graphy.backend.global.auth.redis.repository.RefreshTokenRepository; +import com.graphy.backend.domain.member.domain.Member; +import com.graphy.backend.domain.member.domain.Role; +import com.graphy.backend.domain.project.domain.Project; import com.graphy.backend.test.MockApiTest; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -19,22 +19,21 @@ import org.springframework.http.MediaType; import org.springframework.restdocs.RestDocumentationContextProvider; import org.springframework.restdocs.RestDocumentationExtension; -import org.springframework.test.web.servlet.ResultActions; +import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.web.context.WebApplicationContext; -import java.time.LocalDateTime; -import java.util.Arrays; + +import java.util.ArrayList; import java.util.List; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.when; +import static org.mockito.BDDMockito.*; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(CommentController.class) @@ -45,72 +44,258 @@ class CommentControllerTest extends MockApiTest { private WebApplicationContext context; @MockBean private CommentService commentService; - @MockBean - private TokenProvider tokenProvider; - @MockBean - private RefreshTokenRepository refreshTokenRepository; + private Member member; + private Project project; + private Comment parentComment; + private String BASE_URL = "/api/v1/comments"; @BeforeEach public void setup(RestDocumentationContextProvider provider) { + member = Member.builder() + .id(1L) + .email("graphy@gmail.com") + .nickname("name") + .role(Role.ROLE_USER) + .build(); + + project = Project.builder() + .id(1L) + .member(member) + .build(); + + parentComment = Comment.builder() + .id(1L) + .content("parentComment") + .member(member) + .project(project) + .build(); + this.mvc = buildMockMvc(context, provider); } @Test - @DisplayName("댓글 생성 API 테스트") - void createCommentTest() throws Exception { + @DisplayName("댓글을 생성한다") + void addCommentTest() throws Exception { // given - CreateCommentRequest dto = new CreateCommentRequest("test", 1L, null); + CreateCommentRequest request = new CreateCommentRequest("content", project.getId(), null); - // when - String body = objectMapper.writeValueAsString(dto); - when(commentService.addComment(dto)).thenReturn(any()); - mvc.perform(post("/api/v1/comments") - .content(body) - .contentType(MediaType.APPLICATION_JSON)) + // when, then + mvc.perform(post(BASE_URL) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) .andExpect(status().isCreated()) - .andDo(document("create-comment", preprocessResponse(prettyPrint()))); + .andDo(print()) + .andDo(document("comments/add/success", + requestFields( + fieldWithPath("content").description("내용"), + fieldWithPath("projectId").description("프로젝트 ID"), + fieldWithPath("parentId").description("댓글 ID").optional() + ), + responseFields( + fieldWithPath("code").description("상태 코드"), + fieldWithPath("message").description("응답 메시지"), + fieldWithPath("data").description("응답 데이터") + ))); } @Test - @DisplayName("댓글 수정 API 테스트") - void updateCommentTest() throws Exception { + @DisplayName("댓글 생성 시 내용이 없으면 예외가 발생한다") + void addCommentEmptyContentExceptionTest() throws Exception { // given - Long commentId = 1L; + CreateCommentRequest request = new CreateCommentRequest("", project.getId(), null); - String updatedContent = "수정된 내용"; - UpdateCommentRequest commentRequest = new UpdateCommentRequest(updatedContent); + // when, then + mvc.perform(post(BASE_URL) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request)) + .principal(new TestingAuthenticationToken(member.getEmail(), member.getPassword()))) + .andExpect(status().isBadRequest()) + .andDo(print()) + .andDo(document("comments/add/fail/emptyContent", + requestFields( + fieldWithPath("content").description("내용"), + fieldWithPath("projectId").description("프로젝트 ID"), + fieldWithPath("parentId").description("댓글 ID").optional() + ), + responseFields( + fieldWithPath("code").description("상태 코드"), + fieldWithPath("message").description("응답 메시지"), + fieldWithPath("errors").description("에러 설명"), + fieldWithPath("errors[].field").description("에러가 발생시킨 필드"), + fieldWithPath("errors[].value").description("에러를 발생시킨 필드 값"), + fieldWithPath("errors[].reason").description("에러가 발생한 원인") + ))); + } + + @Test + @DisplayName("댓글 생성 시 프로젝트 아이디가 없으면 예외가 발생한다") + void addCommentEmptyProjectIdExceptionTest() throws Exception { + // given + CreateCommentRequest request = new CreateCommentRequest("content", null, null); - given(commentService.modifyComment(commentId, commentRequest)).willReturn(commentId); - // when - String body = objectMapper.writeValueAsString(commentRequest); - ResultActions resultActions = mvc.perform(put("/api/v1/comments/{commentId}", 1L).content(body).contentType(MediaType.APPLICATION_JSON)); + // when, then + mvc.perform(post(BASE_URL) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request)) + .principal(new TestingAuthenticationToken(member.getEmail(), member.getPassword()))) + .andExpect(status().isBadRequest()) + .andDo(print()) + .andDo(document("comments/add/fail/emptyProjectId", + requestFields( + fieldWithPath("content").description("내용"), + fieldWithPath("projectId").description("프로젝트 ID"), + fieldWithPath("parentId").description("댓글 ID").optional() + ), + responseFields( + fieldWithPath("code").description("상태 코드"), + fieldWithPath("message").description("응답 메시지"), + fieldWithPath("errors").description("에러 설명"), + fieldWithPath("errors[].field").description("에러가 발생시킨 필드"), + fieldWithPath("errors[].value").description("에러를 발생시킨 필드 값"), + fieldWithPath("errors[].reason").description("에러가 발생한 원인") + ))); + } + @Test + @DisplayName("답글을 생성한다") + void addReCommentTest() throws Exception { + // given + CreateCommentRequest request = new CreateCommentRequest("content", project.getId(), parentComment.getId()); - // then - resultActions.andExpect((status().isOk())); + // when, then + mvc.perform(post(BASE_URL) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isCreated()) + .andDo(print()) + .andDo(document("comments/reComment/add/success", + requestFields( + fieldWithPath("content").description("내용"), + fieldWithPath("projectId").description("프로젝트 ID"), + fieldWithPath("parentId").description("댓글 ID").optional() + ), + responseFields( + fieldWithPath("code").description("상태 코드"), + fieldWithPath("message").description("응답 메시지"), + fieldWithPath("data").description("응답 데이터") + ))); } @Test - @DisplayName("댓글 삭제 API 테스트") - void deleteCommentTest() throws Exception { + @DisplayName("답글을 조회한다") + void findReCommentListTest() throws Exception { // given - Comment comment = Comment.builder().id(1L).content("TEST").build(); + GetReplyListResponse response1 = GetReplyListResponse.builder().commentId(1L).content("content1").build(); + GetReplyListResponse response2 = GetReplyListResponse.builder().commentId(2L).content("content2").build(); + GetReplyListResponse response3 = GetReplyListResponse.builder().commentId(3L).content("content3").build(); + List responseList = new ArrayList<>(List.of(response1, response2, response3)); // when - ResultActions resultActions = mvc.perform(delete("/api/v1/comments/{commentId}", 1L) - .contentType(MediaType.APPLICATION_JSON)); - + when(commentService.findCommentList(parentComment.getId())).thenReturn(responseList); // then - resultActions.andExpect((status().isOk())) + mvc.perform(get(BASE_URL + "/{commentId}", parentComment.getId())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value("C001")) + .andExpect(jsonPath("$.message").value("답글 조회 성공")) + .andExpect(jsonPath("$.data[0].content").value(response1.getContent())) + .andExpect(jsonPath("$.data[0].commentId").value(response1.getCommentId())) + .andExpect(jsonPath("$.data[1].content").value(response2.getContent())) + .andExpect(jsonPath("$.data[1].commentId").value(response2.getCommentId())) + .andExpect(jsonPath("$.data[2].content").value(response3.getContent())) + .andExpect(jsonPath("$.data[2].commentId").value(response3.getCommentId())) + .andDo(print()) + .andDo(document("comments/findAll/success", + pathParameters( + parameterWithName("commentId").description("댓글 ID") + ), + responseFields( + fieldWithPath("code").description("상태 코드"), + fieldWithPath("message").description("응답 메시지"), + fieldWithPath("data").description("응답 데이터"), + fieldWithPath("data[].nickname").description("답글 작성자의 닉네임"), + fieldWithPath("data[].content").description("답글 내용"), + fieldWithPath("data[].commentId").description("답글 ID"), + fieldWithPath("data[].createdAt").description("답글 생성 시간") + ))); + } + + @Test + @DisplayName("댓글을 수정한다") + void modifyCommentTest() throws Exception { + // given + UpdateCommentRequest request = new UpdateCommentRequest("updateContent"); + + // when, then + mvc.perform(put(BASE_URL + "/{commentId}", parentComment.getId()) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isOk()) + .andDo(print()) + .andDo(document("comments/modify/success", + pathParameters( + parameterWithName("commentId").description("댓글 ID") + ), + requestFields( + fieldWithPath("content").description("내용") + ), + responseFields( + fieldWithPath("code").description("상태 코드"), + fieldWithPath("message").description("응답 메시지"), + fieldWithPath("data").description("응답 데이터") + ))); + } + + @Test + @DisplayName("댓글을 수정 시 내용이 공백이면 예외가 발생한다") + void modifyCommentEmptyContentTest() throws Exception { + // given + UpdateCommentRequest request = new UpdateCommentRequest(""); + + // when, then + mvc.perform(put(BASE_URL + "/{commentId}", parentComment.getId()) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()) + .andDo(print()) + .andDo(document("comments/modify/fail/emptyContent", + pathParameters( + parameterWithName("commentId").description("댓글 ID") + ), + requestFields( + fieldWithPath("content").description("내용") + ), + responseFields( + fieldWithPath("code").description("상태 코드"), + fieldWithPath("message").description("응답 메시지"), + fieldWithPath("errors").description("에러 설명"), + fieldWithPath("errors[].field").description("에러가 발생시킨 필드"), + fieldWithPath("errors[].value").description("에러를 발생시킨 필드 값"), + fieldWithPath("errors[].reason").description("에러가 발생한 원인") + ))); + } + + @Test + @DisplayName("댓글을 삭제한다") + void removeCommentTest() throws Exception { + + // given, when, then + mvc.perform(delete(BASE_URL + "/{commentId}", parentComment.getId())) + .andExpect(status().isOk()) .andDo(print()) - .andDo(document("comment-delete", - preprocessResponse(prettyPrint())) - ); + .andDo(document("comments/remove/success", + pathParameters( + parameterWithName("commentId").description("댓글 ID") + ), + responseFields( + fieldWithPath("code").description("상태 코드"), + fieldWithPath("message").description("응답 메시지"), + fieldWithPath("data").description("응답 데이터") + ))); } } \ No newline at end of file diff --git a/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java b/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java index 2fe24752..d822d2f6 100644 --- a/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java +++ b/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java @@ -1,8 +1,6 @@ package com.graphy.backend.domain.comment.service; import com.graphy.backend.domain.comment.domain.Comment; -import com.graphy.backend.domain.comment.dto.CommentDto; -import com.graphy.backend.domain.comment.dto.ReplyListDto; import com.graphy.backend.domain.comment.repository.CommentRepository; import com.graphy.backend.domain.member.domain.Member; import com.graphy.backend.domain.project.domain.Project; @@ -19,11 +17,8 @@ import java.time.LocalDateTime; import java.util.ArrayList; -import java.util.List; import java.util.Optional; -import static com.graphy.backend.domain.comment.dto.CommentDto.CreateCommentRequest; -import static com.graphy.backend.domain.comment.dto.CommentDto.CreateCommentResponse; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.BDDMockito.*; @@ -45,27 +40,12 @@ class CommentServiceTest extends MockTest { void createCommentTest() { //given - CreateCommentRequest dto = new CreateCommentRequest("내용", 1L, null); - Project project = Project.builder().id(1L).content("테스트 프로젝트").description("테스트 프로젝트 한 줄 소개").projectName("테스트").build(); - Comment comment = Comment.builder().id(1L).content("내용").project(project).parent(null).build(); - Member member = Member.builder().email("youKeon").build(); // mocking - given(commentRepository.save(any())) - .willReturn(comment); - given(projectRepository.findById(1L)) - .willReturn(Optional.ofNullable(project)); - given(commentRepository.findById(1L)) - .willReturn(Optional.ofNullable(comment)); - given(customUserDetailsService.getLoginUser()) - .willReturn(member); //when - CreateCommentResponse response = commentService.addComment(dto); //then - Comment findComment = commentRepository.findById(response.getCommentId()).get(); - assertEquals(dto.getContent(), findComment.getContent()); } @Test @@ -73,31 +53,6 @@ void createCommentTest() { void createCommentTest2() { //given - CreateCommentRequest dto = new CreateCommentRequest("내용", 1L, 1L); - Project project = Project.builder().id(1L).content("테스트 프로젝트").description("테스트 프로젝트 한 줄 소개").projectName("테스트").build(); - - Comment parentComment = Comment.builder().id(1L).content("내용").project(project).parent(null).build(); - Comment comment = Comment.builder().id(2L).content("내용").project(project).parent(parentComment).build(); - - // mocking - given(commentRepository.save(any())) - .willReturn(comment); - - given(projectRepository.findById(1L)) - .willReturn(Optional.of(project)); - given(commentRepository.findById(1L)) - .willReturn(Optional.of(parentComment)); - given(commentRepository.findById(2L)) - .willReturn(Optional.of(comment)); - - - //when - CreateCommentResponse response = commentService.addComment(dto); - - //then - Comment findComment = commentRepository.findById(response.getCommentId()).get(); - assertEquals(parentComment, findComment.getParent()); - assertEquals(dto.getContent(), findComment.getContent()); } @Test @@ -123,81 +78,12 @@ public void deleteComment() throws Exception { @DisplayName("댓글 수정") public void updateComment() throws Exception { //given - Comment comment = Comment.builder().id(1L).content("수정 전").build(); - CommentDto.UpdateCommentRequest commentRequest = new CommentDto.UpdateCommentRequest("수정 후"); - - // when - comment.updateContent(commentRequest.getContent()); - when(commentRepository.findById(1L)).thenReturn(Optional.of(comment)); - - //then - assertTrue(comment.getContent().equals("수정 후")); - Long result = commentService.modifyComment(1L, commentRequest); - assertTrue(result==1L); } @Test @DisplayName("답글 조회") public void getReplyList() throws Exception { - List list = new ArrayList<>(); - ReplyListDto dto1 = new ReplyListDto() { - @Override - public String getNickname() { - return null; - } - - @Override - public String getContent() { - return "comment1"; - } - - @Override - public Long getCommentId() { - return 1L; - } - - @Override - public LocalDateTime getCreatedAt() { - return null; - } - }; - - ReplyListDto dto2 = new ReplyListDto() { - @Override - public String getNickname() { - return null; - } - - @Override - public String getContent() { - return "comment2"; - } - - @Override - public Long getCommentId() { - return 2L; - } - - @Override - public LocalDateTime getCreatedAt() { - return null; - } - }; - - list.add(dto1); - list.add(dto2); - - // when - when(commentRepository.findReplyList(1L)).thenReturn(list); - List result = commentService.findCommentList(1L); - - //then - assertTrue(result.get(0).getContent().equals("comment1")); - assertTrue(result.get(1).getContent().equals("comment2")); - - assertTrue(result.get(0).getCommentId() == 1L); - assertTrue(result.get(1).getCommentId() == 2L); } @Test @@ -205,20 +91,5 @@ public LocalDateTime getCreatedAt() { void updateCommentTest() { //given - Long commentId = 1L; - - String updatedContent = "수정된 내용"; - - CommentDto.UpdateCommentRequest commentRequest = new CommentDto.UpdateCommentRequest(updatedContent); - - // mocking - given(commentRepository.findById(1L)) - .willReturn(Optional.empty()); - //when - - //then - assertThrows(EmptyResultDataAccessException.class, () -> { - commentService.modifyComment(1L, commentRequest); - }); } } \ No newline at end of file diff --git a/backend/src/test/java/com/graphy/backend/domain/member/controller/MemberControllerTest.java b/backend/src/test/java/com/graphy/backend/domain/member/controller/MemberControllerTest.java index 269bce44..b929bf6e 100644 --- a/backend/src/test/java/com/graphy/backend/domain/member/controller/MemberControllerTest.java +++ b/backend/src/test/java/com/graphy/backend/domain/member/controller/MemberControllerTest.java @@ -1,5 +1,6 @@ package com.graphy.backend.domain.member.controller; +import com.graphy.backend.domain.member.domain.Member; import com.graphy.backend.domain.member.service.MemberService; import com.graphy.backend.global.auth.jwt.TokenProvider; import com.graphy.backend.global.auth.redis.repository.RefreshTokenRepository; @@ -173,7 +174,7 @@ public void getMyPageTest() throws Exception { .build(); // when - when(memberService.myPage()).thenReturn(result); + when(memberService.myPage(new Member())).thenReturn(result); // then mvc.perform(get(baseUrl + "/myPage")) diff --git a/backend/src/test/java/com/graphy/backend/domain/project/controller/ProjectControllerTest.java b/backend/src/test/java/com/graphy/backend/domain/project/controller/ProjectControllerTest.java index bad8136b..332c7fb1 100644 --- a/backend/src/test/java/com/graphy/backend/domain/project/controller/ProjectControllerTest.java +++ b/backend/src/test/java/com/graphy/backend/domain/project/controller/ProjectControllerTest.java @@ -1,7 +1,7 @@ package com.graphy.backend.domain.project.controller; -import com.graphy.backend.domain.comment.dto.CommentWithMaskingDto; import com.graphy.backend.domain.comment.service.CommentService; +import com.graphy.backend.domain.member.domain.Member; import com.graphy.backend.domain.project.service.ProjectService; import com.graphy.backend.global.auth.jwt.TokenProvider; import com.graphy.backend.global.auth.redis.repository.RefreshTokenRepository; @@ -84,45 +84,8 @@ public void setup(RestDocumentationContextProvider provider) { void getProjectWithComments() throws Exception { //given - CommentWithMaskingDto dto = new CommentWithMaskingDto() { - @Override - public String getContent() { - return "testComment"; - } - - @Override - public String getNickname() { - return null; - } - - @Override - public Long getCommentId() { - return null; - } - - @Override - public Integer getChildCount() { - return null; - } - - @Override - public LocalDateTime getCreatedAt() { - return LocalDateTime.now(); - } - }; - List list = new ArrayList<>(); - list.add(dto); - - given(projectService.getProjectById(1L)) - .willReturn(GetProjectDetailResponse.builder() - .projectName("project") - .commentsList(list).build()); - - //then - ResultActions result = mvc.perform(get(baseUrl + "/{projectId}", 1L)); - result.andExpect(status().isOk()); } @Test @@ -138,7 +101,7 @@ public void createProject() throws Exception { CreateProjectResponse response = CreateProjectResponse.builder().projectId(1L).build(); //when - when(projectService.createProject(request)).thenReturn(response); + when(projectService.createProject(request, new Member())).thenReturn(response); //then mvc.perform(post(baseUrl) diff --git a/backend/src/test/java/com/graphy/backend/domain/project/service/ProjectServiceTest.java b/backend/src/test/java/com/graphy/backend/domain/project/service/ProjectServiceTest.java index 3988166b..f5a73e4d 100644 --- a/backend/src/test/java/com/graphy/backend/domain/project/service/ProjectServiceTest.java +++ b/backend/src/test/java/com/graphy/backend/domain/project/service/ProjectServiceTest.java @@ -1,6 +1,5 @@ package com.graphy.backend.domain.project.service; -import com.graphy.backend.domain.comment.dto.CommentWithMaskingDto; import com.graphy.backend.domain.comment.repository.CommentRepository; import com.graphy.backend.domain.member.domain.Member; import com.graphy.backend.domain.project.domain.*; @@ -145,7 +144,7 @@ public void createProject() throws Exception { when(tagRepository.findTagByTech(anyString())).thenReturn(tag1, tag2); when(mapper.toCreateProjectDto(project.getId())).thenReturn(response); when(customUserDetailsService.getLoginUser()).thenReturn(member); - CreateProjectResponse result = projectService.createProject(request); + CreateProjectResponse result = projectService.createProject(request, member); //then assertThat(result.getProjectId()).isEqualTo(1L); @@ -195,27 +194,11 @@ public void getProjects() throws Exception { @DisplayName("프로젝트 상세 조회") public void getProjectById() throws Exception { //given - Project project = Project.builder() - .id(1L) - .projectName("project").build(); - - List comments = new ArrayList<>(); - GetProjectDetailResponse response = GetProjectDetailResponse.builder() - .id(project.getId()) - .projectName(project.getProjectName()) - .build(); //when - when(projectRepository.findById(project.getId())).thenReturn(Optional.of(project)); - when(commentRepository.findCommentsWithMasking(project.getId())).thenReturn(comments); - when(mapper.toGetProjectDetailDto(project, comments)).thenReturn(response); - - GetProjectDetailResponse result = projectService.getProjectById(1L); //then - assertThat(response.getId()).isEqualTo(result.getId()); - assertThat(response.getProjectName()).isEqualTo(result.getProjectName()); } @Test diff --git a/backend/src/test/java/com/graphy/backend/test/MockApiTest.java b/backend/src/test/java/com/graphy/backend/test/MockApiTest.java index d4a6e47b..5636373c 100644 --- a/backend/src/test/java/com/graphy/backend/test/MockApiTest.java +++ b/backend/src/test/java/com/graphy/backend/test/MockApiTest.java @@ -3,9 +3,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.graphy.backend.BackendApplication; +import com.graphy.backend.global.auth.jwt.TokenProvider; +import com.graphy.backend.global.auth.redis.repository.RefreshTokenRepository; import com.graphy.backend.test.config.TestProfile; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.restdocs.RestDocumentationContextProvider; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; @@ -20,11 +23,16 @@ @ContextConfiguration(classes = BackendApplication.class) @ActiveProfiles(TestProfile.TEST) @Disabled -public class MockApiTest { +public abstract class MockApiTest { protected MockMvc mvc; protected ObjectMapper objectMapper = buildObjectMapper(); + @MockBean + protected TokenProvider tokenProvider; + @MockBean + protected RefreshTokenRepository refreshTokenRepository; + public MockMvc buildMockMvc(WebApplicationContext context, RestDocumentationContextProvider provider) { return MockMvcBuilders.webAppContextSetup(context) From 3ef3425c880adbbc2a3041d9fc71a51e521b8f8a Mon Sep 17 00:00:00 2001 From: youKeon Date: Wed, 16 Aug 2023 02:33:30 +0900 Subject: [PATCH 3/9] =?UTF-8?q?refactor=20:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20API=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=82=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/comment/dto/request/CreateCommentRequest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/src/main/java/com/graphy/backend/domain/comment/dto/request/CreateCommentRequest.java b/backend/src/main/java/com/graphy/backend/domain/comment/dto/request/CreateCommentRequest.java index 0e3b66b0..a5fe5d3b 100644 --- a/backend/src/main/java/com/graphy/backend/domain/comment/dto/request/CreateCommentRequest.java +++ b/backend/src/main/java/com/graphy/backend/domain/comment/dto/request/CreateCommentRequest.java @@ -9,6 +9,7 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; @Getter @Builder @@ -19,6 +20,7 @@ public class CreateCommentRequest { @NotBlank private String content; + @NotNull private Long projectId; private Long parentId; From 5efc3bec3be7e7f85c6917d5b5e05379fd2e4960 Mon Sep 17 00:00:00 2001 From: youKeon Date: Wed, 16 Aug 2023 15:09:16 +0900 Subject: [PATCH 4/9] =?UTF-8?q?refactor=20:=20=EB=8B=B5=EA=B8=80=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/domain/comment/service/CommentService.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/com/graphy/backend/domain/comment/service/CommentService.java b/backend/src/main/java/com/graphy/backend/domain/comment/service/CommentService.java index c4963219..29561fd2 100644 --- a/backend/src/main/java/com/graphy/backend/domain/comment/service/CommentService.java +++ b/backend/src/main/java/com/graphy/backend/domain/comment/service/CommentService.java @@ -49,13 +49,16 @@ public void modifyComment(Long commentId, UpdateCommentRequest dto) { public void deleteComment(Long id) { Comment comment = commentRepository.findById(id) - .orElseThrow(() -> new EmptyResultException(ErrorCode.PROJECT_DELETED_OR_NOT_EXIST)); + .orElseThrow(() -> new EmptyResultException(ErrorCode.COMMENT_DELETED_OR_NOT_EXIST)); comment.delete(); } public List findCommentList(Long commentId) { List commentList = commentRepository.findReplyList(commentId); + + if (commentList.size() == 0) throw new EmptyResultException(ErrorCode.COMMENT_DELETED_OR_NOT_EXIST); + return commentList.stream() .map(GetReplyListResponse::from) .collect(Collectors.toList()); From 1ad3d5d7a332d6f715b68c9b4fcbe5dd1c324fb2 Mon Sep 17 00:00:00 2001 From: youKeon Date: Wed, 16 Aug 2023 15:09:32 +0900 Subject: [PATCH 5/9] =?UTF-8?q?test=20:=20Comment=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EA=B3=84=EC=B8=B5=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/service/CommentServiceTest.java | 202 +++++++++++++++--- 1 file changed, 170 insertions(+), 32 deletions(-) diff --git a/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java b/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java index d822d2f6..95a83235 100644 --- a/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java +++ b/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java @@ -1,24 +1,27 @@ package com.graphy.backend.domain.comment.service; import com.graphy.backend.domain.comment.domain.Comment; +import com.graphy.backend.domain.comment.dto.request.CreateCommentRequest; +import com.graphy.backend.domain.comment.dto.request.UpdateCommentRequest; +import com.graphy.backend.domain.comment.dto.response.GetReplyListResponse; import com.graphy.backend.domain.comment.repository.CommentRepository; import com.graphy.backend.domain.member.domain.Member; +import com.graphy.backend.domain.member.domain.Role; import com.graphy.backend.domain.project.domain.Project; import com.graphy.backend.domain.project.repository.ProjectRepository; -import com.graphy.backend.global.auth.jwt.CustomUserDetailsService; +import com.graphy.backend.global.error.exception.EmptyResultException; import com.graphy.backend.test.MockTest; +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 org.springframework.dao.EmptyResultDataAccessException; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Optional; +import java.util.*; +import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.BDDMockito.*; @@ -32,64 +35,199 @@ class CommentServiceTest extends MockTest { private CommentRepository commentRepository; @Mock private ProjectRepository projectRepository; - @Mock - private CustomUserDetailsService customUserDetailsService; + + private Member member; + private Project project; + private Comment parentComment; + @BeforeEach + public void setup() { + member = Member.builder() + .id(1L) + .email("graphy@gmail.com") + .nickname("name") + .role(Role.ROLE_USER) + .build(); + + project = Project.builder() + .id(1L) + .member(member) + .build(); + + parentComment = Comment.builder() + .id(1L) + .content("parentComment") + .member(member) + .project(project) + .build(); + + } @Test @DisplayName("댓글이 생성된다") void createCommentTest() { - //given - - // mocking + CreateCommentRequest request = new CreateCommentRequest("content", project.getId(), null); //when + when(projectRepository.findById(project.getId())).thenReturn(Optional.ofNullable(project)); //then + assertDoesNotThrow(() -> commentService.addComment(request, member)); } @Test - @DisplayName("대댓글이 생성된다") - void createCommentTest2() { - - //given + @DisplayName("댓글 생성 시 프로젝트가 존재하지 않으면 예외가 발생한다") + void createCommentNotExistProjectExceptionTest() { + // given + Long 존재하지_않는_프로젝트_ID = 0L; + CreateCommentRequest request = new CreateCommentRequest("content", 존재하지_않는_프로젝트_ID, null); + + // when, then + assertThatThrownBy( + () -> commentService.addComment(request, member)) + .isInstanceOf(EmptyResultException.class) + .hasMessageContaining("이미 삭제되거나 존재하지 않는 프로젝트"); } @Test - @DisplayName("댓글과 답글 상관없이 삭제") - public void deleteComment() throws Exception { + @DisplayName("답글이 생성된다") + void addReCommentTest() { //given - Comment comment = Comment.builder().id(1L).content("댓글").build(); - Comment reComment = Comment.builder().id(2L).content("대댓글").parent(comment).build(); + CreateCommentRequest request = new CreateCommentRequest("content", project.getId(), parentComment.getId()); + + //when + when(projectRepository.findById(request.getProjectId())).thenReturn(Optional.ofNullable(project)); + when(commentRepository.findById(request.getParentId())).thenReturn(Optional.ofNullable(parentComment)); - given(commentRepository.findById(1L)).willReturn(Optional.of(comment)); - given(commentRepository.findById(2L)).willReturn(Optional.of(reComment)); + //then + assertDoesNotThrow(() -> commentService.addComment(request, member)); + } + + @Test + @DisplayName("답글 생성 시 댓글이 존재하지 않으면 예외가 발생한다") + void addReCommentNotExistParentCommentExceptionTest() { + // given + Long 존재하지_않는_댓글_ID = 0L; + CreateCommentRequest request = new CreateCommentRequest("content", project.getId(), 존재하지_않는_댓글_ID); // when - commentService.deleteComment(1L); - commentService.deleteComment(2L); + when(projectRepository.findById(request.getProjectId())).thenReturn(Optional.ofNullable(project)); - //then - assertTrue(comment.isDeleted()); - assertTrue(reComment.isDeleted()); + // then + assertThatThrownBy( + () -> commentService.addComment(request, member)) + .isInstanceOf(EmptyResultException.class) + .hasMessageContaining("이미 삭제되거나 존재하지 않는 댓글"); } @Test - @DisplayName("댓글 수정") - public void updateComment() throws Exception { + @DisplayName("댓글을 수정한다") + void modifyCommentTest() { //given + UpdateCommentRequest request = new UpdateCommentRequest("updateContent"); + + //when + when(commentRepository.findById(parentComment.getId())).thenReturn(Optional.ofNullable(parentComment)); + commentService.modifyComment(parentComment.getId(), request); + + //then + assertThat(parentComment.getContent()).isEqualTo(request.getContent()); } @Test - @DisplayName("답글 조회") - public void getReplyList() throws Exception { + @DisplayName("답글 수정 시 댓글이 존재하지 않으면 예외가 발생한다") + void modifyReCommentNotExistParentCommentExceptionTest() { + // given + Long 존재하지_않는_댓글_ID = 0L; + UpdateCommentRequest request = new UpdateCommentRequest("updateContent"); + + // when, then + assertThatThrownBy( + () -> commentService.modifyComment(존재하지_않는_댓글_ID, request)) + .isInstanceOf(EmptyResultException.class) + .hasMessageContaining("이미 삭제되거나 존재하지 않는 댓글"); + } + @Test + @DisplayName("댓글을 삭제한다") + void removeCommentTest() { + //when + when(commentRepository.findById(parentComment.getId())).thenReturn(Optional.ofNullable(parentComment)); + commentService.deleteComment(parentComment.getId()); + + //then + assertThat(parentComment.isDeleted()).isTrue(); } @Test - @DisplayName("삭제되거나 없는 댓글 수정시 오류가 발생한다") - void updateCommentTest() { + @DisplayName("답글 삭제 시 댓글이 존재하지 않으면 예외가 발생한다") + void removeReCommentNotExistParentCommentExceptionTest() { + // given + Long 존재하지_않는_댓글_ID = 0L; + + // when, then + assertThatThrownBy( + () -> commentService.deleteComment(존재하지_않는_댓글_ID)) + .isInstanceOf(EmptyResultException.class) + .hasMessageContaining("이미 삭제되거나 존재하지 않는 댓글"); + } + @Test + @DisplayName("답글 목록을 조회한다") + void findReCommentListTest() { //given + Comment reComment1 = Comment.builder() + .id(2L) + .content("reComment1") + .parent(parentComment) + .member(member) + .build(); + + Comment reComment2 = Comment.builder() + .id(3L) + .content("reComment2") + .parent(parentComment).member(member) + .build(); + + Comment reComment3 = Comment.builder() + .id(4L) + .content("reComment3") + .parent(parentComment) + .member(member) + .build(); + + List commentList = new LinkedList<>(List.of(reComment1, reComment2, reComment3)); + + //when + when(commentRepository.findReplyList(parentComment.getId())).thenReturn(commentList); + List actual = commentService.findCommentList(parentComment.getId()); + + //then + assertThat(actual.size()).isEqualTo(commentList.size()); + + assertThat(actual.get(0).getCommentId()).isEqualTo(reComment1.getId()); + assertThat(actual.get(0).getContent()).isEqualTo(reComment1.getContent()); + + assertThat(actual.get(1).getCommentId()).isEqualTo(reComment2.getId()); + assertThat(actual.get(1).getContent()).isEqualTo(reComment2.getContent()); + + assertThat(actual.get(2).getCommentId()).isEqualTo(reComment3.getId()); + assertThat(actual.get(2).getContent()).isEqualTo(reComment3.getContent()); + } + + @Test + @DisplayName("답글 목록 조회 시 목록이 없으면 예외가 발생한다") + void findReCommentListEmptyListExceptionTest() { + // given + Long 답글이_존재하지_않는_댓글_ID = 0L; + + //when + when(commentRepository.findReplyList(답글이_존재하지_않는_댓글_ID)).thenReturn(Collections.emptyList()); + + // then + assertThatThrownBy( + () -> commentService.findCommentList(답글이_존재하지_않는_댓글_ID)) + .isInstanceOf(EmptyResultException.class) + .hasMessageContaining("이미 삭제되거나 존재하지 않는 댓글"); } } \ No newline at end of file From 6d57f49b1984cd9d812867686b892dd338c167b2 Mon Sep 17 00:00:00 2001 From: youKeon Date: Wed, 16 Aug 2023 16:53:55 +0900 Subject: [PATCH 6/9] =?UTF-8?q?test=20:=20Comment=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EB=A6=AC=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20?= =?UTF-8?q?=EA=B3=84=EC=B8=B5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/CommentRepositoryTest.java | 189 ++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 backend/src/test/java/com/graphy/backend/domain/comment/repository/CommentRepositoryTest.java diff --git a/backend/src/test/java/com/graphy/backend/domain/comment/repository/CommentRepositoryTest.java b/backend/src/test/java/com/graphy/backend/domain/comment/repository/CommentRepositoryTest.java new file mode 100644 index 00000000..ea45ccd3 --- /dev/null +++ b/backend/src/test/java/com/graphy/backend/domain/comment/repository/CommentRepositoryTest.java @@ -0,0 +1,189 @@ +package com.graphy.backend.domain.comment.repository; + +import com.graphy.backend.domain.comment.domain.Comment; +import com.graphy.backend.domain.comment.dto.response.GetCommentWithMaskingResponse; +import com.graphy.backend.domain.member.domain.Member; +import com.graphy.backend.domain.member.domain.Role; +import com.graphy.backend.domain.member.repository.MemberRepository; +import com.graphy.backend.domain.project.domain.Project; +import com.graphy.backend.domain.project.repository.ProjectRepository; +import com.graphy.backend.global.config.JpaAuditingConfig; +import com.graphy.backend.global.config.QueryDslConfig; +import org.assertj.core.api.Assertions; +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.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@Import({ + JpaAuditingConfig.class, + QueryDslConfig.class +}) +@ActiveProfiles("test") +public class CommentRepositoryTest { + @Autowired + CommentRepository commentRepository; + + @Autowired + MemberRepository memberRepository; + + @Autowired + ProjectRepository projectRepository; + + @PersistenceContext + private EntityManager entityManager; + private Member member; + private Project project; + private Comment parentComment; + private Comment comment1; + private Comment comment2; + private Comment comment3; + + @BeforeEach + public void setup() { + member = memberRepository.save( + Member.builder() + .email("graphy@gmail.com") + .role(Role.ROLE_USER) + .followerCount(0) + .followingCount(0) + .introduction("introduce") + .password("password") + .nickname("name") + .role(Role.ROLE_USER) + .build() + ); + + project = projectRepository.save( + Project.builder() + .projectName("name") + .member(member) + .build() + ); + + parentComment = commentRepository.save(Comment.builder() + .content("parentComment") + .member(member) + .project(project) + .build() + ); + + comment1 = commentRepository.save(Comment.builder() + .content("comment1-1") + .member(member) + .parent(parentComment) + .project(project) + .build() + ); + + comment2 = commentRepository.save(Comment.builder() + .content("comment1-2") + .member(member) + .parent(parentComment) + .project(project) + .build() + ); + + comment3 = commentRepository.save(Comment.builder() + .content("comment1-3") + .member(member) + .parent(parentComment) + .project(project) + .build() + ); + } + + @Test + @DisplayName("프로젝트 ID를 입력 받으면 마스킹을 적용한 댓글 목록을 조회한다") + public void findCommentWithMakingTest() throws Exception { + // given + Comment parentComment2 = commentRepository.save(Comment.builder() + .content("comment1") + .member(member) + .project(project) + .build() + ); + parentComment2.delete(); + + + // when + List actual = commentRepository.findCommentsWithMasking(project.getId()); + + // then + Assertions.assertThat(actual.size()).isEqualTo(2); + + + Assertions.assertThat(actual.get(0).getCommentId()).isEqualTo(parentComment.getId()); + Assertions.assertThat(actual.get(0).getContent()).isEqualTo(parentComment.getContent()); + Assertions.assertThat(actual.get(0).getNickname()).isEqualTo(parentComment.getMember().getNickname()); + Assertions.assertThat(actual.get(0).getChildCount()).isEqualTo(3); + + Assertions.assertThat(actual.get(1).getContent()).isEqualTo("삭제된 댓글입니다."); + } + + @Test + @DisplayName("댓글 목록 조회 시 댓글이 없으면 빈 리스트가 반환된다") + public void findCommentWithMakingEmptyListTest() throws Exception { + // given + clearRepository(); + + // when + List actual = commentRepository.findCommentsWithMasking(project.getId()); + + // then + assertThat(actual.size()).isEqualTo(0); + } + + @Test + @DisplayName("댓글 ID를 입력 받아 답글 목록을 조회한다") + public void findReCommentListTest() throws Exception { + // when + List actual = commentRepository.findReplyList(parentComment.getId()); + + // then + assertThat(actual.size()).isEqualTo(3); + + assertThat(actual.get(0).getId()).isEqualTo(comment1.getId()); + assertThat(actual.get(0).getContent()).isEqualTo(comment1.getContent()); + assertThat(actual.get(0).getParent()).isEqualTo(comment1.getParent()); + assertThat(actual.get(0).getProject()).isEqualTo(comment1.getProject()); + + assertThat(actual.get(1).getId()).isEqualTo(comment2.getId()); + assertThat(actual.get(1).getContent()).isEqualTo(comment2.getContent()); + assertThat(actual.get(1).getParent()).isEqualTo(comment2.getParent()); + assertThat(actual.get(1).getProject()).isEqualTo(comment2.getProject()); + + assertThat(actual.get(2).getId()).isEqualTo(comment3.getId()); + assertThat(actual.get(2).getContent()).isEqualTo(comment3.getContent()); + assertThat(actual.get(2).getParent()).isEqualTo(comment3.getParent()); + assertThat(actual.get(2).getProject()).isEqualTo(comment3.getProject()); + } + + @Test + @DisplayName("답글 목록 조회 시 답글이 없으면 빈 리스트가 반환된다") + public void findReCommentListEmptyListTest() throws Exception { + // given + clearRepository(); + Long 답글이_존재하지_않는_댓글_ID = 0L; + + // when + List actual = commentRepository.findReplyList(답글이_존재하지_않는_댓글_ID); + + // then + assertThat(actual.size()).isEqualTo(0); + } + + private void clearRepository() { + entityManager.createNativeQuery("DELETE FROM comment").executeUpdate(); + } +} From efc72f74a91f71e5faa2c128e0e8fe065de3da0e Mon Sep 17 00:00:00 2001 From: youKeon Date: Wed, 16 Aug 2023 16:54:13 +0900 Subject: [PATCH 7/9] =?UTF-8?q?test=20:=20CommentServiceTest=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EB=A9=94=EC=86=8C?= =?UTF-8?q?=EB=93=9C=20=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 --- .../backend/domain/comment/service/CommentServiceTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java b/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java index 95a83235..b9c5e84c 100644 --- a/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java +++ b/backend/src/test/java/com/graphy/backend/domain/comment/service/CommentServiceTest.java @@ -64,7 +64,7 @@ public void setup() { @Test @DisplayName("댓글이 생성된다") - void createCommentTest() { + void addCommentTest() { //given CreateCommentRequest request = new CreateCommentRequest("content", project.getId(), null); @@ -77,7 +77,7 @@ void createCommentTest() { @Test @DisplayName("댓글 생성 시 프로젝트가 존재하지 않으면 예외가 발생한다") - void createCommentNotExistProjectExceptionTest() { + void addCommentNotExistProjectExceptionTest() { // given Long 존재하지_않는_프로젝트_ID = 0L; CreateCommentRequest request = new CreateCommentRequest("content", 존재하지_않는_프로젝트_ID, null); From 78250fd984678cde35656af494e040379d15dece Mon Sep 17 00:00:00 2001 From: youKeon Date: Wed, 16 Aug 2023 20:13:19 +0900 Subject: [PATCH 8/9] =?UTF-8?q?test=20:=20CommentRepository=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/domain/comment/repository/CommentRepositoryTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/test/java/com/graphy/backend/domain/comment/repository/CommentRepositoryTest.java b/backend/src/test/java/com/graphy/backend/domain/comment/repository/CommentRepositoryTest.java index ea45ccd3..ddc3a513 100644 --- a/backend/src/test/java/com/graphy/backend/domain/comment/repository/CommentRepositoryTest.java +++ b/backend/src/test/java/com/graphy/backend/domain/comment/repository/CommentRepositoryTest.java @@ -173,7 +173,6 @@ public void findReCommentListTest() throws Exception { @DisplayName("답글 목록 조회 시 답글이 없으면 빈 리스트가 반환된다") public void findReCommentListEmptyListTest() throws Exception { // given - clearRepository(); Long 답글이_존재하지_않는_댓글_ID = 0L; // when From 9610c160a7800179746552d4c7afe489ad18810b Mon Sep 17 00:00:00 2001 From: youKeon Date: Thu, 17 Aug 2023 23:42:22 +0900 Subject: [PATCH 9/9] =?UTF-8?q?refactor=20:=20GetProjectDetailResponse=20D?= =?UTF-8?q?TO=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/controller/CommentController.java | 6 ++- .../project/controller/ProjectController.java | 1 + .../domain/project/domain/Project.java | 2 +- .../domain/project/dto/ProjectDto.java | 16 ------- .../response/GetProjectDetailResponse.java | 43 +++++++++++++++++++ .../domain/project/mapper/ProjectMapper.java | 15 ------- .../project/service/ProjectService.java | 4 +- .../controller/ProjectControllerTest.java | 1 - 8 files changed, 51 insertions(+), 37 deletions(-) create mode 100644 backend/src/main/java/com/graphy/backend/domain/project/dto/response/GetProjectDetailResponse.java diff --git a/backend/src/main/java/com/graphy/backend/domain/comment/controller/CommentController.java b/backend/src/main/java/com/graphy/backend/domain/comment/controller/CommentController.java index 417b45cf..6c206864 100644 --- a/backend/src/main/java/com/graphy/backend/domain/comment/controller/CommentController.java +++ b/backend/src/main/java/com/graphy/backend/domain/comment/controller/CommentController.java @@ -41,7 +41,8 @@ public ResponseEntity commentAdd(@Validated @RequestBody CreateC @Operation(summary = "updateComment", description = "댓글 수정") @PutMapping("/{commentId}") public ResponseEntity commentUpdate(@Validated @RequestBody UpdateCommentRequest dto, - @PathVariable Long commentId) { + @PathVariable Long commentId, + @CurrentUser Member loginUser) { commentService.modifyComment(commentId, dto); return ResponseEntity.status(HttpStatus.OK) @@ -50,7 +51,8 @@ public ResponseEntity commentUpdate(@Validated @RequestBody Upda @Operation(summary = "deleteComment", description = "댓글 삭제") @DeleteMapping("/{id}") - public ResponseEntity commentDelete(@PathVariable Long id) { + public ResponseEntity commentDelete(@PathVariable Long id, + @CurrentUser Member loginUser) { commentService.deleteComment(id); return ResponseEntity.status(HttpStatus.OK) .body(ResultResponse.of(ResultCode.COMMENT_DELETE_SUCCESS)); diff --git a/backend/src/main/java/com/graphy/backend/domain/project/controller/ProjectController.java b/backend/src/main/java/com/graphy/backend/domain/project/controller/ProjectController.java index 27d811ad..26efca35 100644 --- a/backend/src/main/java/com/graphy/backend/domain/project/controller/ProjectController.java +++ b/backend/src/main/java/com/graphy/backend/domain/project/controller/ProjectController.java @@ -1,6 +1,7 @@ package com.graphy.backend.domain.project.controller; import com.graphy.backend.domain.member.domain.Member; +import com.graphy.backend.domain.project.dto.response.GetProjectDetailResponse; import com.graphy.backend.domain.project.service.ProjectService; import com.graphy.backend.global.auth.jwt.annotation.CurrentUser; import com.graphy.backend.global.common.PageRequest; diff --git a/backend/src/main/java/com/graphy/backend/domain/project/domain/Project.java b/backend/src/main/java/com/graphy/backend/domain/project/domain/Project.java index 93adbc0a..8c49d88d 100644 --- a/backend/src/main/java/com/graphy/backend/domain/project/domain/Project.java +++ b/backend/src/main/java/com/graphy/backend/domain/project/domain/Project.java @@ -24,7 +24,7 @@ public class Project extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "project_id") private Long id; diff --git a/backend/src/main/java/com/graphy/backend/domain/project/dto/ProjectDto.java b/backend/src/main/java/com/graphy/backend/domain/project/dto/ProjectDto.java index 0c8ffe7a..2e1bc663 100644 --- a/backend/src/main/java/com/graphy/backend/domain/project/dto/ProjectDto.java +++ b/backend/src/main/java/com/graphy/backend/domain/project/dto/ProjectDto.java @@ -113,22 +113,6 @@ public static class GetProjectResponse { private List techTags; } - @Getter - @Builder - @NoArgsConstructor - @AllArgsConstructor(access = AccessLevel.PRIVATE) - public static class GetProjectDetailResponse { - private Long id; - private String projectName; - private String content; - private String description; - private String thumbNail; - private List commentsList; - private LocalDateTime createdAt; - private List techTags; - - private MemberDto.GetMemberResponse member; - } @Getter @Builder @NoArgsConstructor diff --git a/backend/src/main/java/com/graphy/backend/domain/project/dto/response/GetProjectDetailResponse.java b/backend/src/main/java/com/graphy/backend/domain/project/dto/response/GetProjectDetailResponse.java new file mode 100644 index 00000000..98947197 --- /dev/null +++ b/backend/src/main/java/com/graphy/backend/domain/project/dto/response/GetProjectDetailResponse.java @@ -0,0 +1,43 @@ +package com.graphy.backend.domain.project.dto.response; + +import com.graphy.backend.domain.comment.dto.response.GetCommentWithMaskingResponse; +import com.graphy.backend.domain.member.dto.MemberDto; +import com.graphy.backend.domain.project.domain.Project; +import lombok.*; + +import java.time.LocalDateTime; +import java.util.List; + +import static com.graphy.backend.domain.member.dto.MemberDto.GetMemberResponse.*; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class GetProjectDetailResponse { + private Long id; + private String projectName; + private String content; + private String description; + private String thumbNail; + private List commentsList; + private LocalDateTime createdAt; + private List techTags; + + private MemberDto.GetMemberResponse member; + public static GetProjectDetailResponse of(Project project, + List comments) { + + return GetProjectDetailResponse.builder() + .id(project.getId()) + .projectName(project.getProjectName()) + .description(project.getDescription()) + .createdAt(project.getCreatedAt()) + .techTags(project.getTagNames()) + .content(project.getContent()) + .commentsList(comments) + .member(toDto(project.getMember())) + .thumbNail(project.getThumbNail()) + .build(); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/graphy/backend/domain/project/mapper/ProjectMapper.java b/backend/src/main/java/com/graphy/backend/domain/project/mapper/ProjectMapper.java index d2be8b53..6d6696ea 100644 --- a/backend/src/main/java/com/graphy/backend/domain/project/mapper/ProjectMapper.java +++ b/backend/src/main/java/com/graphy/backend/domain/project/mapper/ProjectMapper.java @@ -52,21 +52,6 @@ public GetProjectResponse toGetProjectDto(Project project) { .build(); } - public GetProjectDetailResponse toGetProjectDetailDto(Project project, - List comments) { - - return GetProjectDetailResponse.builder() - .id(project.getId()) - .projectName(project.getProjectName()) - .description(project.getDescription()) - .createdAt(project.getCreatedAt()) - .techTags(project.getTagNames()) - .content(project.getContent()) - .commentsList(comments) - .member(MemberDto.GetMemberResponse.toDto(project.getMember())) - .thumbNail(project.getThumbNail()) - .build(); - } public GetProjectInfoResponse toProjectInfoDto(Project project) { return GetProjectInfoResponse.builder() diff --git a/backend/src/main/java/com/graphy/backend/domain/project/service/ProjectService.java b/backend/src/main/java/com/graphy/backend/domain/project/service/ProjectService.java index 4f99c746..90d709b3 100644 --- a/backend/src/main/java/com/graphy/backend/domain/project/service/ProjectService.java +++ b/backend/src/main/java/com/graphy/backend/domain/project/service/ProjectService.java @@ -6,6 +6,7 @@ import com.graphy.backend.domain.project.domain.Project; import com.graphy.backend.domain.project.domain.Tag; import com.graphy.backend.domain.project.domain.Tags; +import com.graphy.backend.domain.project.dto.response.GetProjectDetailResponse; import com.graphy.backend.domain.project.mapper.ProjectMapper; import com.graphy.backend.domain.project.repository.ProjectRepository; import com.graphy.backend.domain.project.repository.ProjectTagRepository; @@ -19,7 +20,6 @@ import com.graphy.backend.global.error.exception.LongRequestException; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; -import org.springframework.core.io.ClassPathResource; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -102,7 +102,7 @@ public GetProjectDetailResponse getProjectById(Long projectId) { List comments = commentRepository.findCommentsWithMasking(projectId); - return mapper.toGetProjectDetailDto(project, comments); + return GetProjectDetailResponse.of(project, comments); } public Tags getTagsWithName(List techStacks) { diff --git a/backend/src/test/java/com/graphy/backend/domain/project/controller/ProjectControllerTest.java b/backend/src/test/java/com/graphy/backend/domain/project/controller/ProjectControllerTest.java index 332c7fb1..58f557ec 100644 --- a/backend/src/test/java/com/graphy/backend/domain/project/controller/ProjectControllerTest.java +++ b/backend/src/test/java/com/graphy/backend/domain/project/controller/ProjectControllerTest.java @@ -33,7 +33,6 @@ import java.util.concurrent.CompletableFuture; import static com.graphy.backend.domain.project.dto.ProjectDto.*; -import static com.graphy.backend.domain.project.dto.ProjectDto.GetProjectDetailResponse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given;