From 27d1153796cc6cafe581dd0432e509bbcaac79c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=99=A9=EC=A2=85=ED=9B=88?= Date: Thu, 1 Jul 2021 22:56:59 +0900 Subject: [PATCH 1/9] =?UTF-8?q?Test=20:=20=EB=8C=93=EA=B8=80=20Service=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=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../retrospect/domain/BaseTimeEntity.java | 4 +- .../domain/post/PostRepository.java | 4 +- .../yapp18/retrospect/domain/user/User.java | 2 +- .../retrospect/service/CommentService.java | 29 +-- .../retrospect/service/PostService.java | 10 +- .../web/controller/CommentController.java | 22 +- .../retrospect/common/EntityCreator.java | 2 +- .../service/CommentServiceTest.java | 216 ++++++++++++++++++ .../controller}/CommentControllerTest.java | 26 ++- 9 files changed, 257 insertions(+), 58 deletions(-) create mode 100644 src/test/java/com/yapp18/retrospect/service/CommentServiceTest.java rename src/test/java/com/yapp18/retrospect/{api/comment/web => web/controller}/CommentControllerTest.java (73%) diff --git a/src/main/java/com/yapp18/retrospect/domain/BaseTimeEntity.java b/src/main/java/com/yapp18/retrospect/domain/BaseTimeEntity.java index 622d158..67c734f 100644 --- a/src/main/java/com/yapp18/retrospect/domain/BaseTimeEntity.java +++ b/src/main/java/com/yapp18/retrospect/domain/BaseTimeEntity.java @@ -18,10 +18,10 @@ public abstract class BaseTimeEntity { @CreatedDate// Entity가 생성되어 저장될 때 시간이 자동 저장됩니다. @Column(name ="created_at") - private LocalDateTime createdAt; + protected LocalDateTime createdAt; @LastModifiedDate// 조회한 Entity의 값을 변경할 때 시간이 자동 저장됩니다. @Column(name = "modified_at") - private LocalDateTime modifiedAt; + protected LocalDateTime modifiedAt; } diff --git a/src/main/java/com/yapp18/retrospect/domain/post/PostRepository.java b/src/main/java/com/yapp18/retrospect/domain/post/PostRepository.java index c52caca..f58bb24 100644 --- a/src/main/java/com/yapp18/retrospect/domain/post/PostRepository.java +++ b/src/main/java/com/yapp18/retrospect/domain/post/PostRepository.java @@ -5,15 +5,13 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import java.time.LocalDateTime; import java.util.List; -import java.util.Optional; public interface PostRepository extends JpaRepository { Post findByPostIdx(Long postIdx); - boolean existsByPostIdxLessThan(Long cursorId); + boolean existsByPostIdx(Long postIdx); List findAllByUserUserIdxOrderByCreatedAtDesc(Long userIdx, Pageable pageable); diff --git a/src/main/java/com/yapp18/retrospect/domain/user/User.java b/src/main/java/com/yapp18/retrospect/domain/user/User.java index 96cd6a4..b181f29 100644 --- a/src/main/java/com/yapp18/retrospect/domain/user/User.java +++ b/src/main/java/com/yapp18/retrospect/domain/user/User.java @@ -10,8 +10,8 @@ import java.util.ArrayList; import java.util.List; +@Getter @Setter @Entity -@Getter @Table(name="user_tb") // 기본 생성자 접근을 protected으로 변경하면 외부에서 해당 생성자를 접근 할 수 없으므로 Builder를 통해서만 객체 생성 가능하므로 안전성 보장 @Builder diff --git a/src/main/java/com/yapp18/retrospect/service/CommentService.java b/src/main/java/com/yapp18/retrospect/service/CommentService.java index 658cb4b..a61f218 100644 --- a/src/main/java/com/yapp18/retrospect/service/CommentService.java +++ b/src/main/java/com/yapp18/retrospect/service/CommentService.java @@ -5,55 +5,44 @@ import com.yapp18.retrospect.domain.comment.Comment; import com.yapp18.retrospect.domain.comment.CommentRepository; import com.yapp18.retrospect.domain.post.Post; -import com.yapp18.retrospect.domain.post.PostRepository; import com.yapp18.retrospect.domain.user.User; -import com.yapp18.retrospect.domain.user.UserRepository; -import com.yapp18.retrospect.mapper.CommentMapper; import com.yapp18.retrospect.web.advice.EntityNullException; -import com.yapp18.retrospect.web.dto.ApiPagingResultResponse; -import com.yapp18.retrospect.web.dto.CommentDto; +import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; -import java.util.stream.Collectors; @RequiredArgsConstructor @Service public class CommentService { + private final PostService postService; private final CommentRepository commentRepository; - private final PostRepository postRepository; @Transactional public Comment inputComments(Comment comment){ //타 서비스 의존성을 제거와 코드 가독성을 위해 Entity 외의 메서드 parameter는 최소화 할 것 - return commentRepository.save(comment); + Long postIdx = comment.getPost().getPostIdx(); + comment.setPost(postService.findByPostIdx(postIdx)); + commentRepository.save(comment); + return comment; // commentRepository.save(comment); 그대로 반환하면 테스트 코드에서 엔티티가 null로 날아옴.. } @Transactional(readOnly = true) public List getCommmentsListByPostIdx(Long postIdx, Pageable page){ - Post post = postRepository.findById(postIdx) - .orElseThrow(() -> new EntityNullException(ErrorInfo.POST_NULL)); - + Post post = postService.findByPostIdx(postIdx); return commentRepository.findAllByPost(post, page); } @Transactional(readOnly = true) public Long getCommmentsCountByPostIdx(Long postIdx){ - Post post = postRepository.findByPostIdx(postIdx); + Post post = postService.findByPostIdx(postIdx); return commentRepository.countCommentByPost(post); } - @Transactional(readOnly = true) - public Comment getCommmentsByIdx(Long commentIdx){ - return commentRepository.findById(commentIdx) - .orElseThrow(() -> new EntityNullException(ErrorInfo.COMMENT_NULL)); - } - @Transactional // @PreAuthorize("#oldComment.user.userIdx == #user.userIdx") @@ -61,7 +50,7 @@ public Comment updateComments(Comment newComment){ Long commentIdx = newComment.getCommentIdx(); Comment oldComment = commentRepository.findById(commentIdx) - .orElseThrow(() -> new EntityNullException(ErrorInfo.COMMENT_NULL)); + .orElseThrow(() -> new EntityNullException(ErrorInfo.COMMENT_NULL)); if(!oldComment.isWriter(newComment.getUser())){ throw new AccessDeniedException(TokenErrorInfo.ACCESS_DENIED.getMessage()); diff --git a/src/main/java/com/yapp18/retrospect/service/PostService.java b/src/main/java/com/yapp18/retrospect/service/PostService.java index 9874fe8..27cf050 100644 --- a/src/main/java/com/yapp18/retrospect/service/PostService.java +++ b/src/main/java/com/yapp18/retrospect/service/PostService.java @@ -17,17 +17,17 @@ import com.yapp18.retrospect.web.dto.ApiPagingResultResponse; import com.yapp18.retrospect.web.dto.PostDto; import lombok.RequiredArgsConstructor; - import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; -//import javax.transaction.Transactional; -import java.time.LocalDateTime; + import java.util.List; import java.util.stream.Collectors; +//import javax.transaction.Transactional; + @RequiredArgsConstructor @Service @Transactional @@ -227,4 +227,8 @@ private List compareList(List newList, List compareList) return newList.stream().filter(x -> !compareList.contains(x)).collect(Collectors.toList()); } + //포스트 존재 여부 + public boolean existsByPostIdx(Long postIdx){ + return postRepository.existsByPostIdx(postIdx); + } } diff --git a/src/main/java/com/yapp18/retrospect/web/controller/CommentController.java b/src/main/java/com/yapp18/retrospect/web/controller/CommentController.java index 1b4813e..7604dcb 100644 --- a/src/main/java/com/yapp18/retrospect/web/controller/CommentController.java +++ b/src/main/java/com/yapp18/retrospect/web/controller/CommentController.java @@ -1,21 +1,14 @@ package com.yapp18.retrospect.web.controller; import com.yapp18.retrospect.annotation.CurrentUser; -import com.yapp18.retrospect.config.ErrorInfo; import com.yapp18.retrospect.config.ResponseMessage; import com.yapp18.retrospect.domain.comment.Comment; -import com.yapp18.retrospect.domain.comment.CommentRepository; import com.yapp18.retrospect.domain.post.Post; import com.yapp18.retrospect.domain.user.User; -import com.yapp18.retrospect.domain.user.UserRepository; import com.yapp18.retrospect.mapper.CommentMapper; import com.yapp18.retrospect.service.CommentService; -import com.yapp18.retrospect.service.PostService; -import com.yapp18.retrospect.service.TokenService; -import com.yapp18.retrospect.web.advice.EntityNullException; import com.yapp18.retrospect.web.dto.ApiDefaultResponse; import com.yapp18.retrospect.web.dto.CommentDto; -import com.yapp18.retrospect.web.dto.UserDto; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -25,7 +18,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import javax.servlet.http.HttpServletRequest; import java.util.List; import java.util.stream.Collectors; @@ -53,16 +45,6 @@ public ResponseEntity inputComments(@CurrentUser User user, ); } - @ApiOperation(value = "comment", notes = "[댓글] 댓글 상세보기") - @GetMapping("/{commentIdx}") - public ResponseEntity getCommentsById(@ApiParam(value = "상세보기 comment_idx", required = true, example = "3") - @PathVariable(value = "commentIdx") Long commentIdx) { - return ResponseEntity.status(HttpStatus.OK).body( - ApiDefaultResponse.res(200, ResponseMessage.COMMENT_DETAIL.getResponseMessage(), - commentMapper.toDto(commentService.getCommmentsByIdx(commentIdx))) - ); - } - @ApiOperation(value = "comment", notes = "[댓글] 댓글 수정") @PatchMapping("/{commentIdx}") public ResponseEntity updateComments(@CurrentUser User user, @@ -94,11 +76,11 @@ public ResponseEntity deleteComments(@CurrentUser User user, public ResponseEntity getCommentsByPostIdx(@CurrentUser User user, @ApiParam(value = "회고글 post_idx", required = true, example = "20") @RequestParam(value = "postIdx") Long postIdx, - @RequestParam(value = "cursorIdx(디폴트 0, 페이징 하고 싶은 맨 마지막 postIdx 입력)", defaultValue = "0") Long cursorIdx, + @RequestParam(value = "page", defaultValue = "0") Long page, @RequestParam(value = "pageSize") Integer pageSize){ if (pageSize == null) pageSize = DEFAULT_SIZE; - List result = commentService.getCommmentsListByPostIdx(postIdx, PageRequest.of(page, pageSize)) + List result = commentService.getCommmentsListByPostIdx(postIdx, PageRequest.of(page.intValue(), pageSize)) .stream() .map(comment -> commentMapper.toDto(comment, user)) .collect(Collectors.toList()); diff --git a/src/test/java/com/yapp18/retrospect/common/EntityCreator.java b/src/test/java/com/yapp18/retrospect/common/EntityCreator.java index 491c7f1..f98e07b 100644 --- a/src/test/java/com/yapp18/retrospect/common/EntityCreator.java +++ b/src/test/java/com/yapp18/retrospect/common/EntityCreator.java @@ -21,7 +21,7 @@ public static User createUserEntity(){ .email("test@example.com") .name("테스트이름") .nickname("테스트닉네임") - .profile("profile-url") + .profile("프로필URL") .provider(AuthProvider.kakao) .providerId("12345") .role(Role.MEMBER) diff --git a/src/test/java/com/yapp18/retrospect/service/CommentServiceTest.java b/src/test/java/com/yapp18/retrospect/service/CommentServiceTest.java new file mode 100644 index 0000000..4e8ff62 --- /dev/null +++ b/src/test/java/com/yapp18/retrospect/service/CommentServiceTest.java @@ -0,0 +1,216 @@ +package com.yapp18.retrospect.service; + +import com.yapp18.retrospect.common.EntityCreator; +import com.yapp18.retrospect.config.ErrorInfo; +import com.yapp18.retrospect.config.TokenErrorInfo; +import com.yapp18.retrospect.domain.comment.Comment; +import com.yapp18.retrospect.domain.comment.CommentRepository; +import com.yapp18.retrospect.web.advice.EntityNullException; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +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.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.security.access.AccessDeniedException; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.catchThrowable; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; + +//여기서 Service를 테스트하기 위해서는 Repository 객체를 주입받아야 한다. +//그런데 이것을 주입받으려면 스프링을 띄울 수 밖에 없고, 테스트를 하는데 시간이 오래걸린다. +//무엇보다 데이터가 없는 경우 문제가 발생할 수 있다. +//그래서 Mock를 이용해 테스트를 하면 간단하다 + +@ExtendWith(MockitoExtension.class) +public class CommentServiceTest { + @InjectMocks + private CommentService commentService; + + @Mock + private CommentRepository commentRepository; + + @Mock + private PostService postService; + + private static final Long POST_IDX = 1L; + private static final Long COMMENT_IDX = 1L; + + Comment newComment = Comment.builder() + .commentIdx(COMMENT_IDX) + .comments("새로운 댓글내용") + .user(EntityCreator.createUserEntity()) + .post(EntityCreator.createPostEntity()) + .build(); + + @Nested + @DisplayName("댓글 등록 테스트") + class Input { + @Test + public void 댓글_등록_테스트() { + //given + Comment newComment = EntityCreator.createCommentEntity(); + //mocking + given(postService.findByPostIdx(eq(POST_IDX))).willReturn(newComment.getPost()); + // postService.existsByPostIdx 메서드의 리턴값을 willReturn을 이용해 지정하면 when에서 테스트할 메소드를 호출할때 지정한 값이 사용된다. + //doNothing().when(methodName).postProcess(any()); // void 메소드에 when을 사용하고 싶을때 사용 + + //when + Comment inputtedComment = commentService.inputComments(newComment); + + //then + assertThat(newComment.getCommentIdx()).isEqualTo(inputtedComment.getCommentIdx()); + assertThat(newComment.getComments()).isEqualTo(inputtedComment.getComments()); + assertThat(newComment.getUser().getUserIdx()).isEqualTo(inputtedComment.getUser().getUserIdx()); + assertThat(newComment.getPost().getPostIdx()).isEqualTo(inputtedComment.getPost().getPostIdx()); + } + + @Test + public void 댓글_등록_예외_존재하지_않는_회고글_테스트() { + //given + Comment newComment = EntityCreator.createCommentEntity(); + //mocking + given(postService.findByPostIdx(eq(POST_IDX))).willThrow(new EntityNullException(ErrorInfo.POST_NULL)); + + //when + Throwable throwable = catchThrowable(() -> commentService.inputComments(newComment)); + //then + assertThat(throwable) + .isInstanceOf(EntityNullException.class) + .hasMessage(ErrorInfo.POST_NULL.getErrorMessage()); + } + } + + @Nested + @DisplayName("댓글 조회 테스트") + class Get { + @Test + public void 댓글_리스트_조회_테스트(){ + //given + int page = 0; + int size = 2; + Comment firstComment = EntityCreator.createCommentEntity(); + Comment secondComment = EntityCreator.createCommentEntity(); + secondComment.setCommentIdx(2L); + secondComment.setComments("댓글내용2"); + List arguList = Arrays.asList(firstComment, secondComment); + Pageable pageable = PageRequest.of(page, size); + //mocking + given(postService.findByPostIdx(eq(POST_IDX))).willReturn(EntityCreator.createPostEntity()); + given(commentRepository.findAllByPost(any(), eq(pageable))).willReturn(arguList); + //when + List commentList = commentService.getCommmentsListByPostIdx(POST_IDX, pageable); + //then + assertThat(commentList.get(0).getCommentIdx()).isEqualTo(firstComment.getCommentIdx()); + assertThat(commentList.get(0).getComments()).isEqualTo(firstComment.getComments()); + assertThat(commentList.get(1).getCommentIdx()).isEqualTo(secondComment.getCommentIdx()); + assertThat(commentList.get(1).getComments()).isEqualTo(secondComment.getComments()); + } + + @Test + public void 댓글_갯수_조회_테스트(){ + //given + Comment firstComment = EntityCreator.createCommentEntity(); + Comment secondComment = EntityCreator.createCommentEntity(); + secondComment.setCommentIdx(2L); + secondComment.setComments("댓글내용2"); + List arguList = Arrays.asList(firstComment, secondComment); + //mocking + given(postService.findByPostIdx(eq(POST_IDX))).willReturn(EntityCreator.createPostEntity()); + given(commentRepository.countCommentByPost(any())).willReturn((long)arguList.size()); + //when + Long count = commentService.getCommmentsCountByPostIdx(POST_IDX); + //then + assertThat(count).isEqualTo(arguList.size()); + } + } + + @Nested + @DisplayName("댓글 수정 테스트") + class Update { + @Test + public void 댓글_수정_테스트() { + //given + Comment oldComment = EntityCreator.createCommentEntity(); + //mocking + given(commentRepository.findById(eq(COMMENT_IDX))).willReturn(Optional.ofNullable(oldComment)); + given(commentRepository.save(any())).willReturn(oldComment); + //when + Comment updatedComment = commentService.updateComments(newComment); + //then + assertThat(oldComment.getCommentIdx()).isEqualTo(updatedComment.getCommentIdx()); + assertThat(oldComment.getComments()).isEqualTo(updatedComment.getComments()); + //수정일자도 업데이트 하는 방법이 있을까? + } + + @Test + public void 댓글_수정_예외_권한_없는_사용자_테스트() { + //given + newComment.getUser().setUserIdx(2L); + Comment oldComment = EntityCreator.createCommentEntity(); + //mocking + given(commentRepository.findById(eq(COMMENT_IDX))).willReturn(Optional.ofNullable(oldComment)); + //when + Throwable throwable = catchThrowable(() -> commentService.updateComments(newComment)); + //then + assertThat(throwable) + .isInstanceOf(AccessDeniedException.class) + .hasMessage(TokenErrorInfo.ACCESS_DENIED.getMessage()); + } + + @Test + public void 댓글_수정_예외_존재하지_않는_댓글_테스트() throws Exception { + //given + //mocking + given(commentRepository.findById(eq(COMMENT_IDX))).willThrow(new EntityNullException(ErrorInfo.COMMENT_NULL)); + //when + Throwable thrown = catchThrowable(() -> commentService.updateComments(newComment)); + //then + assertThat(thrown) + .isInstanceOf(EntityNullException.class) + .hasMessage(ErrorInfo.COMMENT_NULL.getErrorMessage()); + } + } + + @Nested + @DisplayName("댓글 삭제 테스트") + class Delete { +// @InjectMocks +// private CommentService commentService; +// +// @Spy +// private CommentRepository commentRepository; +// +// @Spy +// private PostService postService; +// +// @Before +// private void init(){ +// //given +// commentService.inputComments(newComment); +// +// } +// +// @Test +// public void 댓글_삭제_테스트() { +// +// //when +// commentService.deleteComments(inputtedComment.getUser(), inputtedComment.getCommentIdx()); +// //then +// Throwable thrown = catchThrowable(() -> commentRepository.findById(inputtedComment.getCommentIdx())); +// assertThat(thrown) +// .isInstanceOf(EntityNullException.class) +// .hasMessage(ErrorInfo.COMMENT_NULL.getErrorMessage()); +// } + } +} diff --git a/src/test/java/com/yapp18/retrospect/api/comment/web/CommentControllerTest.java b/src/test/java/com/yapp18/retrospect/web/controller/CommentControllerTest.java similarity index 73% rename from src/test/java/com/yapp18/retrospect/api/comment/web/CommentControllerTest.java rename to src/test/java/com/yapp18/retrospect/web/controller/CommentControllerTest.java index 0a17946..297b889 100644 --- a/src/test/java/com/yapp18/retrospect/api/comment/web/CommentControllerTest.java +++ b/src/test/java/com/yapp18/retrospect/web/controller/CommentControllerTest.java @@ -1,12 +1,9 @@ -package com.yapp18.retrospect.api.comment.web; +package com.yapp18.retrospect.web.controller; import com.yapp18.retrospect.api.annotation.WithMockRetrospectUser; import com.yapp18.retrospect.common.EntityCreator; import com.yapp18.retrospect.config.ResponseMessage; import com.yapp18.retrospect.domain.comment.Comment; -import com.yapp18.retrospect.domain.user.Role; -import com.yapp18.retrospect.domain.user.User; -import com.yapp18.retrospect.security.oauth2.AuthProvider; import com.yapp18.retrospect.service.CommentService; import com.yapp18.retrospect.web.AbstractControllerTest; import org.junit.jupiter.api.Test; @@ -27,7 +24,11 @@ public class CommentControllerTest extends AbstractControllerTest { @MockBean - CommentService commentService; // 주된 관심사, 위의 Mock 객체들을 주입받는다. + private CommentService commentService; // 주된 관심사, 위의 Mock 객체들을 주입받는다. + + //@Mock은 로직이 삭제된 빈 껍데기라고 보면 된다. 실제로 메서드는 갖고 있지만 내부 구현이 없는 상태이다. + //@Spy는 모든 기능을 가지고 있는 완전한 객체다. + //대체로 Spy보다는 Mock을 사용하길 권고한다. 하지만 외부라이브러리를 이용한 테스트에는 @Spy를 사용하는 것을 추천한다. private static final Long POST_IDX = 1L; private static final Long COMMENT_IDX = 1L; @@ -38,15 +39,21 @@ public class CommentControllerTest extends AbstractControllerTest { // ArgumentCaptor를 사용하면 메서드 호출 여부를 검증하는 과정에서 실제 호출할 때 전달한 인자를 보관할 수 있다. // ArgumentCaptor userArgumentCaptor = ArgumentCaptor.forClass(User.class); + // CommentService는 CommentRepository, PostRepository를 주입받아야 한다. + // 그런데 이렇게 실행하면 테스트는 성공하는 대신에 CommentService 내에 Repository들은 null 상태가 되어있다. + // 객체주입을 하지 않았기 때문이다. given(commentService.inputComments(any())).willReturn(EntityCreator.createCommentEntity()); + // 그럼에도 불구하고 테스트는 통과되는데 해당메서드의 리턴값을 willReturn을 이용해 지정해두었기 때문이다. + // 실질적으로 Repository의 기능을 사용한 것은 아무것도 없다. mockMvc.perform( post("/api/v1/comments") - .content("{\"postIdx\": 1, \"comments\": \"정말 좋은 글입니다.\"}") + .content("{\"postIdx\": 1, \"comments\": \"댓글내용\"}") .contentType(MediaType.APPLICATION_JSON) ).andExpect(status().isCreated()) .andExpect(MockMvcResultMatchers.jsonPath("$.responseMessage").value(ResponseMessage.COMMENT_SAVE.getResponseMessage())) .andExpect(MockMvcResultMatchers.jsonPath("$.data.commentIdx").value(1L)) + .andExpect(MockMvcResultMatchers.jsonPath("$.data.comments").value("댓글내용")) .andExpect(MockMvcResultMatchers.jsonPath("$.data.nickname").value("테스트닉네임")); } @@ -72,6 +79,7 @@ public class CommentControllerTest extends AbstractControllerTest { int size = 2; Comment secondComment = EntityCreator.createCommentEntity(); secondComment.setCommentIdx(2L); + secondComment.setComments("댓글내용2"); secondComment.setCreatedAt(LocalDateTime.of(2021, 10, 28, 12, 5, 0)); secondComment.setModifiedAt(LocalDateTime.of(2021, 10, 28, 12, 5, 0)); List commentList = Arrays.asList(EntityCreator.createCommentEntity(), secondComment); @@ -83,6 +91,8 @@ public class CommentControllerTest extends AbstractControllerTest { ).andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath("$.responseMessage").value(ResponseMessage.COMMENT_FIND_POSTIDX.getResponseMessage())) .andExpect(MockMvcResultMatchers.jsonPath("$.data[0].commentIdx").value(1L)) - .andExpect(MockMvcResultMatchers.jsonPath("$.data[1].commentIdx").value(2L)); + .andExpect(MockMvcResultMatchers.jsonPath("$.data[0].comments").value("댓글내용")) + .andExpect(MockMvcResultMatchers.jsonPath("$.data[1].commentIdx").value(2L)) + .andExpect(MockMvcResultMatchers.jsonPath("$.data[1].comments").value("댓글내용2")); } -} +} \ No newline at end of file From 899be5da72ed1ed9bd4f2c47a6f8b837377a69b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=99=A9=EC=A2=85=ED=9B=88?= Date: Sat, 3 Jul 2021 18:34:34 +0900 Subject: [PATCH 2/9] =?UTF-8?q?Test=20:=20=EB=8C=93=EA=B8=80=20Service=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=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...nConfiguration.java => JacksonConfig.java} | 4 +- ...Configuration.java => QuerydslConfig.java} | 2 +- .../retrospect/service/CommentService.java | 7 +- .../service/CommentServiceTest.java | 74 ++++++++++++------- .../web/controller/CommentControllerTest.java | 13 +++- 5 files changed, 67 insertions(+), 33 deletions(-) rename src/main/java/com/yapp18/retrospect/config/{JacksonConfiguration.java => JacksonConfig.java} (92%) rename src/main/java/com/yapp18/retrospect/config/{QuerydslConfiguration.java => QuerydslConfig.java} (92%) diff --git a/src/main/java/com/yapp18/retrospect/config/JacksonConfiguration.java b/src/main/java/com/yapp18/retrospect/config/JacksonConfig.java similarity index 92% rename from src/main/java/com/yapp18/retrospect/config/JacksonConfiguration.java rename to src/main/java/com/yapp18/retrospect/config/JacksonConfig.java index 06961d4..07da141 100644 --- a/src/main/java/com/yapp18/retrospect/config/JacksonConfiguration.java +++ b/src/main/java/com/yapp18/retrospect/config/JacksonConfig.java @@ -2,9 +2,7 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.*; -import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -16,7 +14,7 @@ import java.util.Locale; @Configuration -public class JacksonConfiguration { +public class JacksonConfig { private final Locale locale = Locale.UK; private final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("MMM dd, yyyy").withLocale(locale); diff --git a/src/main/java/com/yapp18/retrospect/config/QuerydslConfiguration.java b/src/main/java/com/yapp18/retrospect/config/QuerydslConfig.java similarity index 92% rename from src/main/java/com/yapp18/retrospect/config/QuerydslConfiguration.java rename to src/main/java/com/yapp18/retrospect/config/QuerydslConfig.java index b62c21d..5cfaf75 100644 --- a/src/main/java/com/yapp18/retrospect/config/QuerydslConfiguration.java +++ b/src/main/java/com/yapp18/retrospect/config/QuerydslConfig.java @@ -8,7 +8,7 @@ import javax.persistence.PersistenceContext; @Configuration -public class QuerydslConfiguration { +public class QuerydslConfig { @PersistenceContext private EntityManager entityManager; diff --git a/src/main/java/com/yapp18/retrospect/service/CommentService.java b/src/main/java/com/yapp18/retrospect/service/CommentService.java index a61f218..7007d7a 100644 --- a/src/main/java/com/yapp18/retrospect/service/CommentService.java +++ b/src/main/java/com/yapp18/retrospect/service/CommentService.java @@ -7,7 +7,6 @@ import com.yapp18.retrospect.domain.post.Post; import com.yapp18.retrospect.domain.user.User; import com.yapp18.retrospect.web.advice.EntityNullException; -import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.security.access.AccessDeniedException; @@ -31,6 +30,12 @@ public Comment inputComments(Comment comment){ return comment; // commentRepository.save(comment); 그대로 반환하면 테스트 코드에서 엔티티가 null로 날아옴.. } + @Transactional(readOnly = true) + public Comment getCommmentsByIdx(Long commentIdx){ + return commentRepository.findById(commentIdx) + .orElseThrow(() -> new EntityNullException(ErrorInfo.COMMENT_NULL)); + } + @Transactional(readOnly = true) public List getCommmentsListByPostIdx(Long postIdx, Pageable page){ Post post = postService.findByPostIdx(postIdx); diff --git a/src/test/java/com/yapp18/retrospect/service/CommentServiceTest.java b/src/test/java/com/yapp18/retrospect/service/CommentServiceTest.java index 4e8ff62..90b1d7f 100644 --- a/src/test/java/com/yapp18/retrospect/service/CommentServiceTest.java +++ b/src/test/java/com/yapp18/retrospect/service/CommentServiceTest.java @@ -26,6 +26,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doNothing; //여기서 Service를 테스트하기 위해서는 Repository 객체를 주입받아야 한다. //그런데 이것을 주입받으려면 스프링을 띄울 수 밖에 없고, 테스트를 하는데 시간이 오래걸린다. @@ -185,32 +186,51 @@ class Update { @Nested @DisplayName("댓글 삭제 테스트") class Delete { -// @InjectMocks -// private CommentService commentService; -// -// @Spy -// private CommentRepository commentRepository; -// -// @Spy -// private PostService postService; -// -// @Before -// private void init(){ -// //given -// commentService.inputComments(newComment); -// -// } -// -// @Test -// public void 댓글_삭제_테스트() { -// -// //when -// commentService.deleteComments(inputtedComment.getUser(), inputtedComment.getCommentIdx()); -// //then -// Throwable thrown = catchThrowable(() -> commentRepository.findById(inputtedComment.getCommentIdx())); -// assertThat(thrown) -// .isInstanceOf(EntityNullException.class) -// .hasMessage(ErrorInfo.COMMENT_NULL.getErrorMessage()); -// } + @Test + public void 댓글_삭제_테스트() { + //given + Comment oldComment = EntityCreator.createCommentEntity(); + //mocking + given(commentRepository.findById(eq(COMMENT_IDX))).willReturn(Optional.ofNullable(oldComment)); + doNothing().when(commentRepository).delete(any()); + //when + commentService.deleteComments(oldComment.getUser(), oldComment.getCommentIdx()); + //mocking + given(commentRepository.findById(eq(COMMENT_IDX))).willThrow(new EntityNullException(ErrorInfo.COMMENT_NULL)); + //then + Throwable thrown = catchThrowable(() -> commentService.getCommmentsByIdx(COMMENT_IDX)); + assertThat(thrown) + .isInstanceOf(EntityNullException.class) + .hasMessage(ErrorInfo.COMMENT_NULL.getErrorMessage()); + } + + @Test + public void 댓글_삭제_예외_권한_없는_사용자_테스트() { + //given + newComment.getUser().setUserIdx(2L); + Comment oldComment = EntityCreator.createCommentEntity(); + //mocking + given(commentRepository.findById(eq(COMMENT_IDX))).willReturn(Optional.ofNullable(oldComment)); + //when + Throwable throwable = catchThrowable(() -> commentService.deleteComments(newComment.getUser(), oldComment.getCommentIdx())); + //then + assertThat(throwable) + .isInstanceOf(AccessDeniedException.class) + .hasMessage(TokenErrorInfo.ACCESS_DENIED.getMessage()); + } + + @Test + public void 댓글_삭제_예외_존재하지_않는_댓글_테스트() throws Exception { + //given + Comment oldComment = EntityCreator.createCommentEntity(); + //mocking + given(commentRepository.findById(eq(COMMENT_IDX))).willThrow(new EntityNullException(ErrorInfo.COMMENT_NULL)); + //when + Throwable thrown = catchThrowable(() -> commentService.deleteComments(oldComment.getUser(), oldComment.getCommentIdx())); + //then + assertThat(thrown) + .isInstanceOf(EntityNullException.class) + .hasMessage(ErrorInfo.COMMENT_NULL.getErrorMessage()); + } } } diff --git a/src/test/java/com/yapp18/retrospect/web/controller/CommentControllerTest.java b/src/test/java/com/yapp18/retrospect/web/controller/CommentControllerTest.java index 297b889..81949d9 100644 --- a/src/test/java/com/yapp18/retrospect/web/controller/CommentControllerTest.java +++ b/src/test/java/com/yapp18/retrospect/web/controller/CommentControllerTest.java @@ -19,6 +19,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doNothing; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -63,7 +64,7 @@ public class CommentControllerTest extends AbstractControllerTest { given(commentService.updateComments(any())).willReturn(EntityCreator.createCommentEntity()); mockMvc.perform( - patch("/api/v1/comments/1") + patch("/api/v1/comments/" + COMMENT_IDX) .content("{\"comments\": \"댓글내용\"}") .contentType(MediaType.APPLICATION_JSON) ).andExpect(status().isCreated()) @@ -95,4 +96,14 @@ public class CommentControllerTest extends AbstractControllerTest { .andExpect(MockMvcResultMatchers.jsonPath("$.data[1].commentIdx").value(2L)) .andExpect(MockMvcResultMatchers.jsonPath("$.data[1].comments").value("댓글내용2")); } + + @Test + @WithMockRetrospectUser + public void 댓글_삭제_테스트() throws Exception { + doNothing().when(commentService).deleteComments(any(), eq(COMMENT_IDX)); + + mockMvc.perform( + delete("/api/v1/comments/" + COMMENT_IDX) + ).andExpect(status().isNoContent()); + } } \ No newline at end of file From b92fe48cf3eb23433d3a0c31186ec4a9d4e50172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=99=A9=EC=A2=85=ED=9B=88?= Date: Sun, 4 Jul 2021 22:28:31 +0900 Subject: [PATCH 3/9] =?UTF-8?q?Add=20:=20DBUnit=20=EC=84=A4=EC=A0=95=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 --- .gitignore | 3 ++ build.gradle | 2 ++ .../annotation/RetrospectDataTest.java | 29 +++++++++++++++++++ .../retrospect/config/DBUnitConfig.java | 28 ++++++++++++++++++ .../domain/user/UserRepositoryTest.java | 27 +++++++++++++++++ 5 files changed, 89 insertions(+) create mode 100644 src/test/java/com/yapp18/retrospect/annotation/RetrospectDataTest.java create mode 100644 src/test/java/com/yapp18/retrospect/config/DBUnitConfig.java create mode 100644 src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java diff --git a/.gitignore b/.gitignore index 0b09a53..a3e94eb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ application-oauth.yaml application-aws.yaml ./src/main/resources/static +### test ### +src/test/resources/dbunit + HELP.md .gradle build/ diff --git a/build.gradle b/build.gradle index 7b75bbb..ebc7d76 100644 --- a/build.gradle +++ b/build.gradle @@ -80,6 +80,8 @@ dependencies { // test runtimeOnly 'com.h2database:h2' testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.dbunit:dbunit:2.6.0' + testImplementation 'com.github.springtestdbunit:spring-test-dbunit:1.3.0' } test { diff --git a/src/test/java/com/yapp18/retrospect/annotation/RetrospectDataTest.java b/src/test/java/com/yapp18/retrospect/annotation/RetrospectDataTest.java new file mode 100644 index 0000000..d8f7d80 --- /dev/null +++ b/src/test/java/com/yapp18/retrospect/annotation/RetrospectDataTest.java @@ -0,0 +1,29 @@ +package com.yapp18.retrospect.annotation; + +import com.github.springtestdbunit.TransactionDbUnitTestExecutionListener; +import com.github.springtestdbunit.annotation.DbUnitConfiguration; +import com.yapp18.retrospect.config.DBUnitConfig; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) // 어노테이션을 작성할 곳, @Target(ElementType.FIELD)로 지정해주면, 필드에만 어노테이션을 달 수 있습니다. +@Retention(RetentionPolicy.RUNTIME) // 어노테이션의 지속 시간을 정합니다. 이 어노테이션은 런타임시에도 .class 파일에 존재 합니다. 커스텀 어노테이션을 만들 때 주로 사용합니다. Reflection 사용 가능이 가능합니다. +@Import(DBUnitConfig.class) // https://younicode.tistory.com/entry/Spring-boot%EC%97%90%EC%84%9C-DBUnit-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0 +@DataJpaTest // https://webcoding-start.tistory.com/20, https://howtodoinjava.com/spring-boot2/testing/datajpatest-annotation/ +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) // Replace.NONE로 설정하면 @ActiveProfiles에 설정한 프로파일 환경값에 따라 데이터 소스가 적용됩니다. +// TestContextManager에 어떤 TestExecutionListener들이 등록되어야 하는지 설정할 수 있게 지원합니다. +@ContextConfiguration +@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, // 스프링 테스트 환경에서 일반적으로 사용되는 의존성 주입 (DI) 리스너입니다. 테스트 인스턴스에 대한 의존성 주입 (DI) 을 제공합니다. + TransactionDbUnitTestExecutionListener.class }) +@DbUnitConfiguration(databaseConnection = "dbUnitDatabaseConnection") +public @interface RetrospectDataTest { +} diff --git a/src/test/java/com/yapp18/retrospect/config/DBUnitConfig.java b/src/test/java/com/yapp18/retrospect/config/DBUnitConfig.java new file mode 100644 index 0000000..3b650fb --- /dev/null +++ b/src/test/java/com/yapp18/retrospect/config/DBUnitConfig.java @@ -0,0 +1,28 @@ +package com.yapp18.retrospect.config; + +import com.github.springtestdbunit.bean.DatabaseConfigBean; +import com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean; +import org.dbunit.ext.h2.H2DataTypeFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.sql.DataSource; + +@Configuration +public class DBUnitConfig { + @Bean + public DatabaseConfigBean dbUnitDatabaseConfig() { + DatabaseConfigBean config = new DatabaseConfigBean(); + config.setAllowEmptyFields(true); + config.setDatatypeFactory(new H2DataTypeFactory()); + return config; + } + + @Bean + public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection(DataSource dataSource) { + DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection = new DatabaseDataSourceConnectionFactoryBean(); + dbUnitDatabaseConnection.setDataSource(dataSource); + dbUnitDatabaseConnection.setDatabaseConfig(dbUnitDatabaseConfig()); + return dbUnitDatabaseConnection; + } +} diff --git a/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java b/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java new file mode 100644 index 0000000..b9ef64f --- /dev/null +++ b/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java @@ -0,0 +1,27 @@ +package com.yapp18.retrospect.domain.user; + +import com.github.springtestdbunit.annotation.DatabaseSetup; +import com.yapp18.retrospect.annotation.RetrospectDataTest; +import com.yapp18.retrospect.config.ErrorInfo; +import com.yapp18.retrospect.web.advice.EntityNullException; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.assertj.core.api.Assertions.assertThat; + +@RetrospectDataTest +@DatabaseSetup({ + "classpath:dbunit/entity/user.xml" +}) +public class UserRepositoryTest { + @Autowired + UserRepository userRepository; + + @Test + public void 멤버_조회(){ + User user = userRepository.findById(1L) + .orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL)); + + assertThat(user.getUserIdx()).isEqualTo(1L); + } +} From 24772fd3253b97504c181ccaed685f0385169020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=99=A9=EC=A2=85=ED=9B=88?= Date: Mon, 5 Jul 2021 17:32:52 +0900 Subject: [PATCH 4/9] =?UTF-8?q?Test=20:=20UserRepositoryTest=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 - .../yapp18/retrospect/domain/user/User.java | 7 +- .../retrospect/service/UserService.java | 3 +- .../retrospect/common/EntityCreator.java | 2 +- .../domain/user/UserRepositoryTest.java | 73 +++++++++++++++++-- .../web/AbstractControllerTest.java | 2 +- ..._\355\205\214\354\235\264\353\270\224.xml" | 4 + ...\353\252\205_\354\241\264\354\236\254.xml" | 25 +++++++ ...\353\252\205_\354\241\264\354\236\254.xml" | 14 ++++ ...\354\236\220_\354\240\225\353\263\264.xml" | 14 ++++ 10 files changed, 130 insertions(+), 17 deletions(-) create mode 100644 "src/test/resources/dbunit/User/\353\271\210_\354\202\254\354\232\251\354\236\220_\355\205\214\354\235\264\353\270\224.xml" create mode 100644 "src/test/resources/dbunit/User/\354\202\254\354\232\251\354\236\220_\353\221\220\353\252\205_\354\241\264\354\236\254.xml" create mode 100644 "src/test/resources/dbunit/User/\354\202\254\354\232\251\354\236\220_\355\225\234\353\252\205_\354\241\264\354\236\254.xml" create mode 100644 "src/test/resources/dbunit/User/\354\210\230\354\240\225\353\220\234_\354\202\254\354\232\251\354\236\220_\354\240\225\353\263\264.xml" diff --git a/.gitignore b/.gitignore index a3e94eb..0b09a53 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,6 @@ application-oauth.yaml application-aws.yaml ./src/main/resources/static -### test ### -src/test/resources/dbunit - HELP.md .gradle build/ diff --git a/src/main/java/com/yapp18/retrospect/domain/user/User.java b/src/main/java/com/yapp18/retrospect/domain/user/User.java index b181f29..f42709d 100644 --- a/src/main/java/com/yapp18/retrospect/domain/user/User.java +++ b/src/main/java/com/yapp18/retrospect/domain/user/User.java @@ -3,12 +3,9 @@ import com.sun.istack.NotNull; import com.yapp18.retrospect.domain.BaseTimeEntity; import com.yapp18.retrospect.security.oauth2.AuthProvider; - import lombok.*; import javax.persistence.*; -import java.util.ArrayList; -import java.util.List; @Getter @Setter @Entity @@ -60,10 +57,10 @@ public User updateNickname(String nickname){ return this; } - public User updateProfile(String profile, String name, String nickname, String job, String intro){ + public User updateProfile(String name, String nickname, String profile, String job, String intro){ this.name = name; - this.profile = profile; this.nickname = nickname; + this.profile = profile; this.job = job; this.intro = intro; return this; diff --git a/src/main/java/com/yapp18/retrospect/service/UserService.java b/src/main/java/com/yapp18/retrospect/service/UserService.java index db51127..5c9f3a9 100644 --- a/src/main/java/com/yapp18/retrospect/service/UserService.java +++ b/src/main/java/com/yapp18/retrospect/service/UserService.java @@ -15,7 +15,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -67,7 +66,7 @@ public UserDto.ProfileResponse updateUserProfiles(Long userIdx, UserDto.UpdateRe List list = Arrays.asList(request.getProfile()); imageService.deleteImageList(list, userIdx, s3ProfileImagePathSuffix); // list에 없는 s3 가비지 데이터를 추출하여 삭제 } - return existingUser.updateProfile(request.getProfile(), request.getName(), request.getNickname(), request.getJob(), request.getIntro()); + return existingUser.updateProfile(request.getName(), request.getNickname(), request.getProfile(), request.getJob(), request.getIntro()); }) .orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL)); userRepository.save(user); diff --git a/src/test/java/com/yapp18/retrospect/common/EntityCreator.java b/src/test/java/com/yapp18/retrospect/common/EntityCreator.java index f98e07b..ecc9bab 100644 --- a/src/test/java/com/yapp18/retrospect/common/EntityCreator.java +++ b/src/test/java/com/yapp18/retrospect/common/EntityCreator.java @@ -23,7 +23,7 @@ public static User createUserEntity(){ .nickname("테스트닉네임") .profile("프로필URL") .provider(AuthProvider.kakao) - .providerId("12345") + .providerId("1") .role(Role.MEMBER) .job("테스트직업") .intro("테스트자기소개") diff --git a/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java b/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java index b9ef64f..2f67e50 100644 --- a/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java +++ b/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java @@ -1,27 +1,90 @@ package com.yapp18.retrospect.domain.user; import com.github.springtestdbunit.annotation.DatabaseSetup; +import com.github.springtestdbunit.annotation.ExpectedDatabase; +import com.github.springtestdbunit.assertion.DatabaseAssertionMode; import com.yapp18.retrospect.annotation.RetrospectDataTest; +import com.yapp18.retrospect.common.EntityCreator; import com.yapp18.retrospect.config.ErrorInfo; import com.yapp18.retrospect.web.advice.EntityNullException; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import javax.persistence.EntityManager; + import static org.assertj.core.api.Assertions.assertThat; @RetrospectDataTest -@DatabaseSetup({ - "classpath:dbunit/entity/user.xml" -}) public class UserRepositoryTest { @Autowired UserRepository userRepository; + @Autowired + EntityManager entityManager; + + private final long USER_IDX = 1L; + + @Test + @DatabaseSetup({ + "classpath:dbunit/User/빈_사용자_테이블.xml" + }) + @ExpectedDatabase(value = "classpath:dbunit/User/사용자_한명_존재.xml", + assertionMode= DatabaseAssertionMode.NON_STRICT) + public void 사용자_정보_등록(){ + User user = EntityCreator.createUserEntity(); + + userRepository.save(user); + } + + @Test + @DatabaseSetup({ + "classpath:dbunit/User/사용자_한명_존재.xml" + }) + public void 사용자_정보_조회(){ + User expected = EntityCreator.createUserEntity(); + + User user = userRepository.findById(1L) + .orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL)); + + assertThat(user.getUserIdx()).isEqualTo(expected.getUserIdx()); + assertThat(user.getEmail()).isEqualTo(expected.getEmail()); + assertThat(user.getName()).isEqualTo(expected.getName()); + assertThat(user.getNickname()).isEqualTo(expected.getNickname()); + assertThat(user.getProfile()).isEqualTo(expected.getProfile()); + assertThat(user.getJob()).isEqualTo(expected.getJob()); + assertThat(user.getIntro()).isEqualTo(expected.getIntro()); + assertThat(user.getProvider()).isEqualTo(expected.getProvider()); + assertThat(user.getProviderId()).isEqualTo(expected.getProviderId()); + assertThat(user.getRole()).isEqualTo(expected.getRole()); + } + @Test - public void 멤버_조회(){ + @DatabaseSetup({ + "classpath:dbunit/User/사용자_한명_존재.xml" + }) + @ExpectedDatabase(value = "classpath:dbunit/User/수정된_사용자_정보.xml", + assertionMode= DatabaseAssertionMode.NON_STRICT) + public void 사용자_정보_수정(){ User user = userRepository.findById(1L) .orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL)); - assertThat(user.getUserIdx()).isEqualTo(1L); + user.updateProfile("수정된이름", "수정된닉네임", "수정된프로필URL", "수정된직업", "수정된자기소개"); + + entityManager.flush(); // flush 연산을 통해 데이터베이스에 강제 반영 + } + + @Test + @DatabaseSetup({ + "classpath:dbunit/User/사용자_한명_존재.xml" + }) + @ExpectedDatabase(value = "classpath:dbunit/User/빈_사용자_테이블.xml", + assertionMode= DatabaseAssertionMode.NON_STRICT) + public void 사용자_정보_삭제(){ + User user = userRepository.findById(USER_IDX) + .orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL)); + + userRepository.delete(user); + + entityManager.flush(); // flush 연산을 통해 데이터베이스에 강제 반영 } } diff --git a/src/test/java/com/yapp18/retrospect/web/AbstractControllerTest.java b/src/test/java/com/yapp18/retrospect/web/AbstractControllerTest.java index 6e36caf..9813527 100644 --- a/src/test/java/com/yapp18/retrospect/web/AbstractControllerTest.java +++ b/src/test/java/com/yapp18/retrospect/web/AbstractControllerTest.java @@ -12,7 +12,7 @@ import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; @EncodingConfig -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @AutoConfigureMockMvc public abstract class AbstractControllerTest { @Autowired diff --git "a/src/test/resources/dbunit/User/\353\271\210_\354\202\254\354\232\251\354\236\220_\355\205\214\354\235\264\353\270\224.xml" "b/src/test/resources/dbunit/User/\353\271\210_\354\202\254\354\232\251\354\236\220_\355\205\214\354\235\264\353\270\224.xml" new file mode 100644 index 0000000..3eafd3b --- /dev/null +++ "b/src/test/resources/dbunit/User/\353\271\210_\354\202\254\354\232\251\354\236\220_\355\205\214\354\235\264\353\270\224.xml" @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git "a/src/test/resources/dbunit/User/\354\202\254\354\232\251\354\236\220_\353\221\220\353\252\205_\354\241\264\354\236\254.xml" "b/src/test/resources/dbunit/User/\354\202\254\354\232\251\354\236\220_\353\221\220\353\252\205_\354\241\264\354\236\254.xml" new file mode 100644 index 0000000..cbb1ac6 --- /dev/null +++ "b/src/test/resources/dbunit/User/\354\202\254\354\232\251\354\236\220_\353\221\220\353\252\205_\354\241\264\354\236\254.xml" @@ -0,0 +1,25 @@ + + + + + + + \ No newline at end of file diff --git "a/src/test/resources/dbunit/User/\354\202\254\354\232\251\354\236\220_\355\225\234\353\252\205_\354\241\264\354\236\254.xml" "b/src/test/resources/dbunit/User/\354\202\254\354\232\251\354\236\220_\355\225\234\353\252\205_\354\241\264\354\236\254.xml" new file mode 100644 index 0000000..da04949 --- /dev/null +++ "b/src/test/resources/dbunit/User/\354\202\254\354\232\251\354\236\220_\355\225\234\353\252\205_\354\241\264\354\236\254.xml" @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git "a/src/test/resources/dbunit/User/\354\210\230\354\240\225\353\220\234_\354\202\254\354\232\251\354\236\220_\354\240\225\353\263\264.xml" "b/src/test/resources/dbunit/User/\354\210\230\354\240\225\353\220\234_\354\202\254\354\232\251\354\236\220_\354\240\225\353\263\264.xml" new file mode 100644 index 0000000..76354df --- /dev/null +++ "b/src/test/resources/dbunit/User/\354\210\230\354\240\225\353\220\234_\354\202\254\354\232\251\354\236\220_\354\240\225\353\263\264.xml" @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file From d9c02111e3732b917603bc14118c46ccd88a07c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=99=A9=EC=A2=85=ED=9B=88?= Date: Tue, 6 Jul 2021 19:07:24 +0900 Subject: [PATCH 5/9] =?UTF-8?q?Fix=20:=20userIdx=20Sequence=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80,=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=8B=A4=ED=8C=A8?= =?UTF-8?q?=20=EC=9D=B4=EC=8A=88=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yapp18/retrospect/domain/user/User.java | 2 + .../domain/user/UserRepository.java | 6 ++ .../annotation/WithMockRetrospectUser.java | 4 +- .../api/oauth2/OAuth2ControllerTest.java | 25 ----- .../WithMockUserSecurityContextFactory.java | 4 +- .../domain/comment/CommentRepositoryTest.java | 16 +++ .../domain/user/UserRepositoryTest.java | 102 +++++++++++++----- .../web/controller/CommentControllerTest.java | 2 +- ..._\355\205\214\354\235\264\353\270\224.xml" | 1 - ...\353\252\205_\354\241\264\354\236\254.xml" | 3 +- 10 files changed, 106 insertions(+), 59 deletions(-) rename src/test/java/com/yapp18/retrospect/{api => }/annotation/WithMockRetrospectUser.java (72%) delete mode 100644 src/test/java/com/yapp18/retrospect/api/oauth2/OAuth2ControllerTest.java rename src/test/java/com/yapp18/retrospect/{api => }/config/WithMockUserSecurityContextFactory.java (93%) create mode 100644 src/test/java/com/yapp18/retrospect/domain/comment/CommentRepositoryTest.java diff --git a/src/main/java/com/yapp18/retrospect/domain/user/User.java b/src/main/java/com/yapp18/retrospect/domain/user/User.java index f42709d..6be6dc7 100644 --- a/src/main/java/com/yapp18/retrospect/domain/user/User.java +++ b/src/main/java/com/yapp18/retrospect/domain/user/User.java @@ -69,4 +69,6 @@ public User updateProfile(String name, String nickname, String profile, String j public String getRoleKey(){ return this.role.getKey(); } + + } diff --git a/src/main/java/com/yapp18/retrospect/domain/user/UserRepository.java b/src/main/java/com/yapp18/retrospect/domain/user/UserRepository.java index 89fb2c4..2716f04 100644 --- a/src/main/java/com/yapp18/retrospect/domain/user/UserRepository.java +++ b/src/main/java/com/yapp18/retrospect/domain/user/UserRepository.java @@ -1,6 +1,8 @@ package com.yapp18.retrospect.domain.user; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; import java.util.Optional; @@ -9,4 +11,8 @@ public interface UserRepository extends JpaRepository { Optional findByEmail(String email); Optional findByUserIdx(Long userIdx); boolean existsByNickname(String nickname); + + @Modifying + @Query(value = "ALTER TABLE user_tb ALTER COLUMN user_idx RESTART WITH 1", nativeQuery = true) + void restartIdxSequence(); // 테스트 h2 db sequence 초기화용 (postgres에선 사용 불가) } diff --git a/src/test/java/com/yapp18/retrospect/api/annotation/WithMockRetrospectUser.java b/src/test/java/com/yapp18/retrospect/annotation/WithMockRetrospectUser.java similarity index 72% rename from src/test/java/com/yapp18/retrospect/api/annotation/WithMockRetrospectUser.java rename to src/test/java/com/yapp18/retrospect/annotation/WithMockRetrospectUser.java index b558665..9fe3bcd 100644 --- a/src/test/java/com/yapp18/retrospect/api/annotation/WithMockRetrospectUser.java +++ b/src/test/java/com/yapp18/retrospect/annotation/WithMockRetrospectUser.java @@ -1,6 +1,6 @@ -package com.yapp18.retrospect.api.annotation; +package com.yapp18.retrospect.annotation; -import com.yapp18.retrospect.api.config.WithMockUserSecurityContextFactory; +import com.yapp18.retrospect.config.WithMockUserSecurityContextFactory; import org.springframework.security.test.context.support.WithSecurityContext; import java.lang.annotation.Retention; diff --git a/src/test/java/com/yapp18/retrospect/api/oauth2/OAuth2ControllerTest.java b/src/test/java/com/yapp18/retrospect/api/oauth2/OAuth2ControllerTest.java deleted file mode 100644 index 9a7c44b..0000000 --- a/src/test/java/com/yapp18/retrospect/api/oauth2/OAuth2ControllerTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.yapp18.retrospect.api.oauth2; - -import com.yapp18.retrospect.domain.user.Role; -import com.yapp18.retrospect.domain.user.User; -import com.yapp18.retrospect.security.oauth2.AuthProvider; -import com.yapp18.retrospect.service.UserService; -import com.yapp18.retrospect.web.AbstractControllerTest; -import org.springframework.boot.test.mock.mockito.MockBean; - -public class OAuth2ControllerTest extends AbstractControllerTest { - private final User newUser = User.builder() - .email("ybell1028@daum.net") - .name("real-name") - .nickname("Walkman") - .profile("profile-url") - .provider(AuthProvider.kakao) - .providerId("12345") - .role(Role.MEMBER) - .job("job") - .intro("intro") - .build(); - - @MockBean - UserService userService; -} diff --git a/src/test/java/com/yapp18/retrospect/api/config/WithMockUserSecurityContextFactory.java b/src/test/java/com/yapp18/retrospect/config/WithMockUserSecurityContextFactory.java similarity index 93% rename from src/test/java/com/yapp18/retrospect/api/config/WithMockUserSecurityContextFactory.java rename to src/test/java/com/yapp18/retrospect/config/WithMockUserSecurityContextFactory.java index ddeef28..1f2b23e 100644 --- a/src/test/java/com/yapp18/retrospect/api/config/WithMockUserSecurityContextFactory.java +++ b/src/test/java/com/yapp18/retrospect/config/WithMockUserSecurityContextFactory.java @@ -1,6 +1,6 @@ -package com.yapp18.retrospect.api.config; +package com.yapp18.retrospect.config; -import com.yapp18.retrospect.api.annotation.WithMockRetrospectUser; +import com.yapp18.retrospect.annotation.WithMockRetrospectUser; import com.yapp18.retrospect.domain.user.Role; import com.yapp18.retrospect.domain.user.User; import com.yapp18.retrospect.security.UserPrincipal; diff --git a/src/test/java/com/yapp18/retrospect/domain/comment/CommentRepositoryTest.java b/src/test/java/com/yapp18/retrospect/domain/comment/CommentRepositoryTest.java new file mode 100644 index 0000000..ef0e720 --- /dev/null +++ b/src/test/java/com/yapp18/retrospect/domain/comment/CommentRepositoryTest.java @@ -0,0 +1,16 @@ +package com.yapp18.retrospect.domain.comment; + +import com.yapp18.retrospect.annotation.RetrospectDataTest; +import com.yapp18.retrospect.domain.user.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.persistence.EntityManager; + +@RetrospectDataTest +public class CommentRepositoryTest { + @Autowired + UserRepository userRepository; + + @Autowired + EntityManager entityManager; +} \ No newline at end of file diff --git a/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java b/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java index 2f67e50..5ec085c 100644 --- a/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java +++ b/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java @@ -6,7 +6,9 @@ import com.yapp18.retrospect.annotation.RetrospectDataTest; import com.yapp18.retrospect.common.EntityCreator; import com.yapp18.retrospect.config.ErrorInfo; +import com.yapp18.retrospect.security.oauth2.AuthProvider; import com.yapp18.retrospect.web.advice.EntityNullException; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -15,6 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat; @RetrospectDataTest +@DatabaseSetup({"classpath:dbunit/User/빈_사용자_테이블.xml"}) public class UserRepositoryTest { @Autowired UserRepository userRepository; @@ -24,26 +27,58 @@ public class UserRepositoryTest { private final long USER_IDX = 1L; + @BeforeEach + public void init(){ + userRepository.restartIdxSequence(); // userIdx sequence 초기화 + } + @Test - @DatabaseSetup({ - "classpath:dbunit/User/빈_사용자_테이블.xml" - }) + @DatabaseSetup({"classpath:dbunit/User/빈_사용자_테이블.xml"}) @ExpectedDatabase(value = "classpath:dbunit/User/사용자_한명_존재.xml", - assertionMode= DatabaseAssertionMode.NON_STRICT) - public void 사용자_정보_등록(){ - User user = EntityCreator.createUserEntity(); + assertionMode = DatabaseAssertionMode.NON_STRICT) + public void 사용자_정보_등록() { + userRepository.save(User.builder() + .userIdx(USER_IDX) + .email("test@example.com") + .name("테스트이름") + .nickname("테스트닉네임") + .profile("프로필URL") + .provider(AuthProvider.kakao) + .providerId("1") + .role(Role.MEMBER) + .job("테스트직업") + .intro("테스트자기소개") + .build()); + + entityManager.flush(); + } - userRepository.save(user); + @Test + @DatabaseSetup(value = "classpath:dbunit/User/사용자_한명_존재.xml") + public void 사용자_정보_인덱스로_조회() { + User expected = EntityCreator.createUserEntity(); + + User user = userRepository.findByUserIdx(expected.getUserIdx()) + .orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL)); + + assertThat(user.getUserIdx()).isEqualTo(expected.getUserIdx()); + assertThat(user.getEmail()).isEqualTo(expected.getEmail()); + assertThat(user.getName()).isEqualTo(expected.getName()); + assertThat(user.getNickname()).isEqualTo(expected.getNickname()); + assertThat(user.getProfile()).isEqualTo(expected.getProfile()); + assertThat(user.getJob()).isEqualTo(expected.getJob()); + assertThat(user.getIntro()).isEqualTo(expected.getIntro()); + assertThat(user.getProvider()).isEqualTo(expected.getProvider()); + assertThat(user.getProviderId()).isEqualTo(expected.getProviderId()); + assertThat(user.getRole()).isEqualTo(expected.getRole()); } @Test - @DatabaseSetup({ - "classpath:dbunit/User/사용자_한명_존재.xml" - }) - public void 사용자_정보_조회(){ + @DatabaseSetup(value = "classpath:dbunit/User/사용자_한명_존재.xml") + public void 사용자_정보_이메일로_조회() { User expected = EntityCreator.createUserEntity(); - User user = userRepository.findById(1L) + User user = userRepository.findByEmail(expected.getEmail()) .orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL)); assertThat(user.getUserIdx()).isEqualTo(expected.getUserIdx()); @@ -59,32 +94,45 @@ public class UserRepositoryTest { } @Test - @DatabaseSetup({ - "classpath:dbunit/User/사용자_한명_존재.xml" - }) - @ExpectedDatabase(value = "classpath:dbunit/User/수정된_사용자_정보.xml", - assertionMode= DatabaseAssertionMode.NON_STRICT) - public void 사용자_정보_수정(){ - User user = userRepository.findById(1L) + @DatabaseSetup(value = "classpath:dbunit/User/사용자_한명_존재.xml") + public void 사용자_닉네임_조회_True() { + User expected = EntityCreator.createUserEntity(); + + boolean result = userRepository.existsByNickname(expected.getNickname()); + + assertThat(result).isEqualTo(true); + } + + @Test + @DatabaseSetup(value = "classpath:dbunit/User/사용자_한명_존재.xml") + public void 사용자_닉네임_조회_False() { + boolean result = userRepository.existsByNickname("존재하지않는닉네임"); + + assertThat(result).isEqualTo(false); + } + + @Test + @DatabaseSetup(value = "classpath:dbunit/User/사용자_한명_존재.xml") + @ExpectedDatabase(value = "classpath:dbunit/User/수정된_사용자_정보.xml", assertionMode = DatabaseAssertionMode.NON_STRICT) + + public void 사용자_정보_수정() { + User user = userRepository.findById(USER_IDX) .orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL)); user.updateProfile("수정된이름", "수정된닉네임", "수정된프로필URL", "수정된직업", "수정된자기소개"); + userRepository.save(user); + entityManager.flush(); // flush 연산을 통해 데이터베이스에 강제 반영 } @Test - @DatabaseSetup({ - "classpath:dbunit/User/사용자_한명_존재.xml" - }) - @ExpectedDatabase(value = "classpath:dbunit/User/빈_사용자_테이블.xml", - assertionMode= DatabaseAssertionMode.NON_STRICT) - public void 사용자_정보_삭제(){ + @DatabaseSetup(value = "classpath:dbunit/User/사용자_한명_존재.xml") + @ExpectedDatabase(value = "classpath:dbunit/User/빈_사용자_테이블.xml", assertionMode = DatabaseAssertionMode.NON_STRICT) + public void 사용자_정보_삭제() { User user = userRepository.findById(USER_IDX) .orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL)); userRepository.delete(user); - - entityManager.flush(); // flush 연산을 통해 데이터베이스에 강제 반영 } } diff --git a/src/test/java/com/yapp18/retrospect/web/controller/CommentControllerTest.java b/src/test/java/com/yapp18/retrospect/web/controller/CommentControllerTest.java index 81949d9..04632f7 100644 --- a/src/test/java/com/yapp18/retrospect/web/controller/CommentControllerTest.java +++ b/src/test/java/com/yapp18/retrospect/web/controller/CommentControllerTest.java @@ -1,6 +1,6 @@ package com.yapp18.retrospect.web.controller; -import com.yapp18.retrospect.api.annotation.WithMockRetrospectUser; +import com.yapp18.retrospect.annotation.WithMockRetrospectUser; import com.yapp18.retrospect.common.EntityCreator; import com.yapp18.retrospect.config.ResponseMessage; import com.yapp18.retrospect.domain.comment.Comment; diff --git "a/src/test/resources/dbunit/User/\353\271\210_\354\202\254\354\232\251\354\236\220_\355\205\214\354\235\264\353\270\224.xml" "b/src/test/resources/dbunit/User/\353\271\210_\354\202\254\354\232\251\354\236\220_\355\205\214\354\235\264\353\270\224.xml" index 3eafd3b..e83b00b 100644 --- "a/src/test/resources/dbunit/User/\353\271\210_\354\202\254\354\232\251\354\236\220_\355\205\214\354\235\264\353\270\224.xml" +++ "b/src/test/resources/dbunit/User/\353\271\210_\354\202\254\354\232\251\354\236\220_\355\205\214\354\235\264\353\270\224.xml" @@ -1,4 +1,3 @@ - \ No newline at end of file diff --git "a/src/test/resources/dbunit/User/\354\202\254\354\232\251\354\236\220_\355\225\234\353\252\205_\354\241\264\354\236\254.xml" "b/src/test/resources/dbunit/User/\354\202\254\354\232\251\354\236\220_\355\225\234\353\252\205_\354\241\264\354\236\254.xml" index da04949..76ebc98 100644 --- "a/src/test/resources/dbunit/User/\354\202\254\354\232\251\354\236\220_\355\225\234\353\252\205_\354\241\264\354\236\254.xml" +++ "b/src/test/resources/dbunit/User/\354\202\254\354\232\251\354\236\220_\355\225\234\353\252\205_\354\241\264\354\236\254.xml" @@ -1,7 +1,8 @@ - Date: Wed, 14 Jul 2021 11:24:16 +0900 Subject: [PATCH 6/9] =?UTF-8?q?Test=20:=20CommentRepositoryTest=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 +- .../domain/comment/CommentRepository.java | 13 ++- .../yapp18/retrospect/domain/user/Role.java | 2 +- .../retrospect/service/CommentService.java | 3 +- .../domain/comment/CommentRepositoryTest.java | 86 ++++++++++++++++++- .../domain/user/UserRepositoryTest.java | 16 +--- .../service/CommentServiceTest.java | 3 +- ...\352\260\234_\354\241\264\354\236\254.xml" | 27 ++++++ ...\352\260\234_\354\241\264\354\236\254.xml" | 15 ++++ ...\352\260\234_\354\241\264\354\236\254.xml" | 9 ++ ..._\355\205\214\354\235\264\353\270\224.xml" | 3 + ...\352\260\234_\354\241\264\354\236\254.xml" | 10 +++ 12 files changed, 162 insertions(+), 27 deletions(-) create mode 100644 "src/test/resources/dbunit/Comment/\353\214\223\352\270\200_\353\204\244\352\260\234_\354\241\264\354\236\254.xml" create mode 100644 "src/test/resources/dbunit/Comment/\353\214\223\352\270\200_\353\221\220\352\260\234_\354\241\264\354\236\254.xml" create mode 100644 "src/test/resources/dbunit/Comment/\353\214\223\352\270\200_\355\225\234\352\260\234_\354\241\264\354\236\254.xml" create mode 100644 "src/test/resources/dbunit/Comment/\353\271\210_\353\214\223\352\270\200_\355\205\214\354\235\264\353\270\224.xml" create mode 100644 "src/test/resources/dbunit/Post/\355\232\214\352\263\240\352\270\200_\355\225\234\352\260\234_\354\241\264\354\236\254.xml" diff --git a/build.gradle b/build.gradle index ebc7d76..99d0cb3 100644 --- a/build.gradle +++ b/build.gradle @@ -47,7 +47,7 @@ dependencies { // JWT implementation 'io.jsonwebtoken:jjwt:0.9.1' - // mapstruct + // mapstructㄴ implementation 'org.mapstruct:mapstruct:1.4.2.Final' // lombok diff --git a/src/main/java/com/yapp18/retrospect/domain/comment/CommentRepository.java b/src/main/java/com/yapp18/retrospect/domain/comment/CommentRepository.java index 809d477..e6247dd 100644 --- a/src/main/java/com/yapp18/retrospect/domain/comment/CommentRepository.java +++ b/src/main/java/com/yapp18/retrospect/domain/comment/CommentRepository.java @@ -3,16 +3,21 @@ import com.yapp18.retrospect.domain.post.Post; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; -import java.time.LocalDateTime; import java.util.List; -import java.util.Optional; public interface CommentRepository extends JpaRepository { - List findAllByPost(Post post, Pageable page); + @Query(value = "SELECT * FROM comment_tb WHERE comment_tb.post_idx = :postIdx", nativeQuery = true) + List findAllByPostIdx(Long postIdx, Pageable page); + +// @Query(value = "SELECT COUNT(*) FROM comment_tb WHERE comment_tb.post_idx = :postIdx", nativeQuery = true) + Long countCommentByPost(Post post); boolean existsByCommentIdxGreaterThanAndPost(Long cursorIdx, Post post); - Long countCommentByPost(Post postIdx); + @Modifying + @Query(value = "ALTER TABLE comment_tb ALTER COLUMN comment_idx RESTART WITH 1", nativeQuery = true) + void restartIdxSequence(); // 테스트 h2 db sequence 초기화용 (postgres에선 사용 불가) } \ No newline at end of file diff --git a/src/main/java/com/yapp18/retrospect/domain/user/Role.java b/src/main/java/com/yapp18/retrospect/domain/user/Role.java index 8eac7d4..9a39580 100644 --- a/src/main/java/com/yapp18/retrospect/domain/user/Role.java +++ b/src/main/java/com/yapp18/retrospect/domain/user/Role.java @@ -6,7 +6,7 @@ @Getter @RequiredArgsConstructor public enum Role { - //스프링 시큐리티에서는 권한 코드에 항상 **ROLE_이 앞에 있어야만 합니다**. + //스프링 시큐리티에서는 권한 코드에 항상 ROLE_이 앞에 있어야만 합니다**. ADMIN("ROLE_ADMIN", "관리자"), MEMBER("ROLE_MEMBER", "일반 회원"), GUEST("ROLE_GUEST", "손님"); diff --git a/src/main/java/com/yapp18/retrospect/service/CommentService.java b/src/main/java/com/yapp18/retrospect/service/CommentService.java index 7007d7a..3d9189a 100644 --- a/src/main/java/com/yapp18/retrospect/service/CommentService.java +++ b/src/main/java/com/yapp18/retrospect/service/CommentService.java @@ -38,8 +38,7 @@ public Comment getCommmentsByIdx(Long commentIdx){ @Transactional(readOnly = true) public List getCommmentsListByPostIdx(Long postIdx, Pageable page){ - Post post = postService.findByPostIdx(postIdx); - return commentRepository.findAllByPost(post, page); + return commentRepository.findAllByPostIdx(postIdx, page); } @Transactional(readOnly = true) diff --git a/src/test/java/com/yapp18/retrospect/domain/comment/CommentRepositoryTest.java b/src/test/java/com/yapp18/retrospect/domain/comment/CommentRepositoryTest.java index ef0e720..2847964 100644 --- a/src/test/java/com/yapp18/retrospect/domain/comment/CommentRepositoryTest.java +++ b/src/test/java/com/yapp18/retrospect/domain/comment/CommentRepositoryTest.java @@ -1,16 +1,98 @@ package com.yapp18.retrospect.domain.comment; +import com.github.springtestdbunit.annotation.DatabaseSetup; +import com.github.springtestdbunit.annotation.ExpectedDatabase; +import com.github.springtestdbunit.assertion.DatabaseAssertionMode; import com.yapp18.retrospect.annotation.RetrospectDataTest; -import com.yapp18.retrospect.domain.user.UserRepository; +import com.yapp18.retrospect.common.EntityCreator; +import com.yapp18.retrospect.domain.post.Post; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; import javax.persistence.EntityManager; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; @RetrospectDataTest public class CommentRepositoryTest { @Autowired - UserRepository userRepository; + CommentRepository commentRepository; @Autowired EntityManager entityManager; + + Post post = EntityCreator.createPostEntity(); + + @BeforeEach + public void init(){ + commentRepository.restartIdxSequence(); // userIdx sequence 초기화 + } + + @Test + @DatabaseSetup({ + "classpath:dbunit/User/사용자_한명_존재.xml", + "classpath:dbunit/Post/회고글_한개_존재.xml", + "classpath:dbunit/Comment/빈_댓글_테이블.xml" + }) + @ExpectedDatabase(value = "classpath:dbunit/Comment/댓글_한개_존재.xml", + assertionMode = DatabaseAssertionMode.NON_STRICT) + public void 댓글_등록() { + commentRepository.save(EntityCreator.createCommentEntity()); + } + + @Test + @DatabaseSetup({ + "classpath:dbunit/User/사용자_한명_존재.xml", + "classpath:dbunit/Post/회고글_한개_존재.xml", + "classpath:dbunit/Comment/댓글_두개_존재.xml" + }) + public void 회고글에_달린_댓글_리스트_조회() { + List commentList = commentRepository.findAllByPostIdx(1L, PageRequest.of(0, 2)); + + assertThat(commentList.size()).isEqualTo(2); + assertThat(commentList.get(0).getCommentIdx()).isEqualTo(1); + assertThat(commentList.get(0).getComments()).isEqualTo("댓글내용1"); + assertThat(commentList.get(1).getCommentIdx()).isEqualTo(2); + assertThat(commentList.get(1).getComments()).isEqualTo("댓글내용2"); + } + + @Test + @DatabaseSetup({ + "classpath:dbunit/User/사용자_한명_존재.xml", + "classpath:dbunit/Post/회고글_한개_존재.xml", + "classpath:dbunit/Comment/댓글_두개_존재.xml" + }) + public void 회고글에_달린_댓글_커서_조회() { + Long count = commentRepository.countCommentByPost(post); + + assertThat(count).isEqualTo(2); + } + + @Test + @DatabaseSetup({ + "classpath:dbunit/User/사용자_한명_존재.xml", + "classpath:dbunit/Post/회고글_한개_존재.xml", + "classpath:dbunit/Comment/댓글_네개_존재.xml" + }) +// public void 회고글에_달린_댓글_커서_페이징_True() { + public void 마지막_댓글_다음_페이지_있는지_True() { + boolean exist = commentRepository.existsByCommentIdxGreaterThanAndPost(2L, post); + + assertThat(exist).isEqualTo(true); + } + + @Test + @DatabaseSetup({ + "classpath:dbunit/User/사용자_한명_존재.xml", + "classpath:dbunit/Post/회고글_한개_존재.xml", + "classpath:dbunit/Comment/댓글_네개_존재.xml" + }) + public void 마지막_댓글_다음_페이지_있는지_False() { + boolean exist = commentRepository.existsByCommentIdxGreaterThanAndPost(4L, post); + + assertThat(exist).isEqualTo(false); + } } \ No newline at end of file diff --git a/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java b/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java index 5ec085c..9bf0be7 100644 --- a/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java +++ b/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java @@ -6,7 +6,6 @@ import com.yapp18.retrospect.annotation.RetrospectDataTest; import com.yapp18.retrospect.common.EntityCreator; import com.yapp18.retrospect.config.ErrorInfo; -import com.yapp18.retrospect.security.oauth2.AuthProvider; import com.yapp18.retrospect.web.advice.EntityNullException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -37,20 +36,7 @@ public void init(){ @ExpectedDatabase(value = "classpath:dbunit/User/사용자_한명_존재.xml", assertionMode = DatabaseAssertionMode.NON_STRICT) public void 사용자_정보_등록() { - userRepository.save(User.builder() - .userIdx(USER_IDX) - .email("test@example.com") - .name("테스트이름") - .nickname("테스트닉네임") - .profile("프로필URL") - .provider(AuthProvider.kakao) - .providerId("1") - .role(Role.MEMBER) - .job("테스트직업") - .intro("테스트자기소개") - .build()); - - entityManager.flush(); + userRepository.save(EntityCreator.createUserEntity()); } @Test diff --git a/src/test/java/com/yapp18/retrospect/service/CommentServiceTest.java b/src/test/java/com/yapp18/retrospect/service/CommentServiceTest.java index 90b1d7f..4f690c7 100644 --- a/src/test/java/com/yapp18/retrospect/service/CommentServiceTest.java +++ b/src/test/java/com/yapp18/retrospect/service/CommentServiceTest.java @@ -107,8 +107,7 @@ class Get { List arguList = Arrays.asList(firstComment, secondComment); Pageable pageable = PageRequest.of(page, size); //mocking - given(postService.findByPostIdx(eq(POST_IDX))).willReturn(EntityCreator.createPostEntity()); - given(commentRepository.findAllByPost(any(), eq(pageable))).willReturn(arguList); + given(commentRepository.findAllByPostIdx(eq(COMMENT_IDX), eq(pageable))).willReturn(arguList); //when List commentList = commentService.getCommmentsListByPostIdx(POST_IDX, pageable); //then diff --git "a/src/test/resources/dbunit/Comment/\353\214\223\352\270\200_\353\204\244\352\260\234_\354\241\264\354\236\254.xml" "b/src/test/resources/dbunit/Comment/\353\214\223\352\270\200_\353\204\244\352\260\234_\354\241\264\354\236\254.xml" new file mode 100644 index 0000000..7d2b133 --- /dev/null +++ "b/src/test/resources/dbunit/Comment/\353\214\223\352\270\200_\353\204\244\352\260\234_\354\241\264\354\236\254.xml" @@ -0,0 +1,27 @@ + + + + + + + + + + + \ No newline at end of file diff --git "a/src/test/resources/dbunit/Comment/\353\214\223\352\270\200_\353\221\220\352\260\234_\354\241\264\354\236\254.xml" "b/src/test/resources/dbunit/Comment/\353\214\223\352\270\200_\353\221\220\352\260\234_\354\241\264\354\236\254.xml" new file mode 100644 index 0000000..3342c1b --- /dev/null +++ "b/src/test/resources/dbunit/Comment/\353\214\223\352\270\200_\353\221\220\352\260\234_\354\241\264\354\236\254.xml" @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git "a/src/test/resources/dbunit/Comment/\353\214\223\352\270\200_\355\225\234\352\260\234_\354\241\264\354\236\254.xml" "b/src/test/resources/dbunit/Comment/\353\214\223\352\270\200_\355\225\234\352\260\234_\354\241\264\354\236\254.xml" new file mode 100644 index 0000000..79cb0f9 --- /dev/null +++ "b/src/test/resources/dbunit/Comment/\353\214\223\352\270\200_\355\225\234\352\260\234_\354\241\264\354\236\254.xml" @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git "a/src/test/resources/dbunit/Comment/\353\271\210_\353\214\223\352\270\200_\355\205\214\354\235\264\353\270\224.xml" "b/src/test/resources/dbunit/Comment/\353\271\210_\353\214\223\352\270\200_\355\205\214\354\235\264\353\270\224.xml" new file mode 100644 index 0000000..e83b00b --- /dev/null +++ "b/src/test/resources/dbunit/Comment/\353\271\210_\353\214\223\352\270\200_\355\205\214\354\235\264\353\270\224.xml" @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git "a/src/test/resources/dbunit/Post/\355\232\214\352\263\240\352\270\200_\355\225\234\352\260\234_\354\241\264\354\236\254.xml" "b/src/test/resources/dbunit/Post/\355\232\214\352\263\240\352\270\200_\355\225\234\352\260\234_\354\241\264\354\236\254.xml" new file mode 100644 index 0000000..3425689 --- /dev/null +++ "b/src/test/resources/dbunit/Post/\355\232\214\352\263\240\352\270\200_\355\225\234\352\260\234_\354\241\264\354\236\254.xml" @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file From 7cb411b2e60ca514994eda4661a024c075473a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=99=A9=EC=A2=85=ED=9B=88?= Date: Mon, 19 Jul 2021 23:39:43 +0900 Subject: [PATCH 7/9] =?UTF-8?q?Test=20:=20LikeRepositoryTest=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 --- .../yapp18/retrospect/domain/like/Like.java | 2 +- .../domain/like/LikeRepository.java | 7 +- .../yapp18/retrospect/domain/post/Post.java | 4 +- .../service/CustomOAuth2UserService.java | 4 +- .../retrospect/service/UserService.java | 7 +- .../retrospect/common/EntityCreator.java | 15 ++ .../domain/comment/CommentRepositoryTest.java | 1 - .../domain/like/LikeRepositoryTest.java | 232 ++++++++++-------- .../domain/user/UserRepositoryTest.java | 4 +- ...\352\260\234_\354\241\264\354\236\254.xml" | 27 ++ ...\352\260\234_\354\241\264\354\236\254.xml" | 12 + ...\352\260\234_\354\241\264\354\236\254.xml" | 8 + ...\352\260\234_\354\241\264\354\236\254.xml" | 29 +++ ...\352\260\234_\354\241\264\354\236\254.xml" | 16 ++ ..._\355\205\214\354\235\264\353\270\224.xml" | 1 + 15 files changed, 246 insertions(+), 123 deletions(-) create mode 100644 "src/test/resources/dbunit/Like/\354\212\244\355\201\254\353\236\251_\353\213\244\354\204\257\352\260\234_\354\241\264\354\236\254.xml" create mode 100644 "src/test/resources/dbunit/Like/\354\212\244\355\201\254\353\236\251_\353\221\220\352\260\234_\354\241\264\354\236\254.xml" create mode 100644 "src/test/resources/dbunit/Like/\354\212\244\355\201\254\353\236\251_\355\225\234\352\260\234_\354\241\264\354\236\254.xml" create mode 100644 "src/test/resources/dbunit/Post/\355\232\214\352\263\240\352\270\200_\353\204\244\352\260\234_\354\241\264\354\236\254.xml" create mode 100644 "src/test/resources/dbunit/Post/\355\232\214\352\263\240\352\270\200_\353\221\220\352\260\234_\354\241\264\354\236\254.xml" rename "src/test/resources/dbunit/User/\353\271\210_\354\202\254\354\232\251\354\236\220_\355\205\214\354\235\264\353\270\224.xml" => "src/test/resources/dbunit/common/\353\271\210_\355\205\214\354\235\264\353\270\224.xml" (98%) diff --git a/src/main/java/com/yapp18/retrospect/domain/like/Like.java b/src/main/java/com/yapp18/retrospect/domain/like/Like.java index cb6dbc2..fa0b0b2 100644 --- a/src/main/java/com/yapp18/retrospect/domain/like/Like.java +++ b/src/main/java/com/yapp18/retrospect/domain/like/Like.java @@ -35,7 +35,7 @@ public class Like extends BaseTimeEntity { @ManyToOne @JoinColumn(name = "post_idx") - private Post post; // 어떻게..? + private Post post; @ManyToOne @JoinColumn(name = "user_idx") diff --git a/src/main/java/com/yapp18/retrospect/domain/like/LikeRepository.java b/src/main/java/com/yapp18/retrospect/domain/like/LikeRepository.java index a7e04a3..ddeaf07 100644 --- a/src/main/java/com/yapp18/retrospect/domain/like/LikeRepository.java +++ b/src/main/java/com/yapp18/retrospect/domain/like/LikeRepository.java @@ -4,6 +4,7 @@ import com.yapp18.retrospect.domain.user.User; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import java.util.List; @@ -23,6 +24,8 @@ public interface LikeRepository extends JpaRepository { boolean existsByUserAndLikeIdxLessThan(User user, Long lastIdx); void deleteByUserAndPost(User user, Post post); -// List findByUserOrderByCreatedAtDesc(Long userIdx, Pageable page); -// Like findByPostAndUser(Post post, User user); + + @Modifying + @Query(value = "ALTER TABLE like_tb ALTER COLUMN like_idx RESTART WITH 1", nativeQuery = true) + void restartIdxSequence(); // 테스트 h2 db sequence 초기화용 (postgres에선 사용 불가) } \ No newline at end of file diff --git a/src/main/java/com/yapp18/retrospect/domain/post/Post.java b/src/main/java/com/yapp18/retrospect/domain/post/Post.java index 0999fbd..52db163 100644 --- a/src/main/java/com/yapp18/retrospect/domain/post/Post.java +++ b/src/main/java/com/yapp18/retrospect/domain/post/Post.java @@ -17,9 +17,7 @@ import javax.persistence.*; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; @Getter @Setter @@ -56,7 +54,7 @@ public class Post extends BaseTimeEntity { @ManyToOne @JoinColumn(name = "template_idx") - private Template template; // 어떻게? + private Template template; @JsonIgnore @OneToMany(mappedBy = "post",orphanRemoval = true) diff --git a/src/main/java/com/yapp18/retrospect/service/CustomOAuth2UserService.java b/src/main/java/com/yapp18/retrospect/service/CustomOAuth2UserService.java index 400ffdd..50beac0 100644 --- a/src/main/java/com/yapp18/retrospect/service/CustomOAuth2UserService.java +++ b/src/main/java/com/yapp18/retrospect/service/CustomOAuth2UserService.java @@ -1,7 +1,5 @@ package com.yapp18.retrospect.service; -import com.yapp18.retrospect.config.AppProperties; -import com.yapp18.retrospect.domain.user.Role; import com.yapp18.retrospect.domain.user.User; import com.yapp18.retrospect.domain.user.UserRepository; import com.yapp18.retrospect.exception.OAuth2AuthenticationProcessingException; @@ -43,7 +41,7 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic private OAuth2User processOAuth2User(OAuth2UserRequest userRequest, OAuth2User oAuth2User){ String registrationId = userRequest.getClientRegistration().getRegistrationId(); - OAuth2UserInfo oAuth2UserInfo = OAuth2UserInfoFactory.getOAuth2UserInfo(registrationId, oAuth2User.getAttributes());; + OAuth2UserInfo oAuth2UserInfo = OAuth2UserInfoFactory.getOAuth2UserInfo(registrationId, oAuth2User.getAttributes()); if(!StringUtils.hasText(oAuth2UserInfo.getEmail())) { throw new OAuth2AuthenticationProcessingException("OAuth2 공급자(구글, 카카오, ...) 에서 이메일을 찾을 수 없습니다."); diff --git a/src/main/java/com/yapp18/retrospect/service/UserService.java b/src/main/java/com/yapp18/retrospect/service/UserService.java index 5c9f3a9..4fbd5e6 100644 --- a/src/main/java/com/yapp18/retrospect/service/UserService.java +++ b/src/main/java/com/yapp18/retrospect/service/UserService.java @@ -21,11 +21,10 @@ @RequiredArgsConstructor @Service public class UserService { - private final UserMapper mapper; + private final UserMapper userMapper; private final UserRepository userRepository; private final ImageService imageService; private final AppProperties appProperties; - private final UserMapper userMapper; @Value("${app.values.s3ProfileImagePathSuffix}") public String s3ProfileImagePathSuffix; @@ -53,7 +52,7 @@ public User registerNewUser(String registrationId, OAuth2UserInfo oAuth2UserInfo @Transactional(readOnly = true) public UserDto.ProfileResponse getUserProfiles(Long userIdx, Long extractedIdx) { return userRepository.findByUserIdx(userIdx) - .map(user -> mapper.userToProfileResponse(user, user.getUserIdx().equals(extractedIdx))) + .map(user -> userMapper.userToProfileResponse(user, user.getUserIdx().equals(extractedIdx))) .orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL)); } @@ -70,7 +69,7 @@ public UserDto.ProfileResponse updateUserProfiles(Long userIdx, UserDto.UpdateRe }) .orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL)); userRepository.save(user); - return mapper.userToProfileResponse(user); + return userMapper.userToProfileResponse(user); } @Transactional diff --git a/src/test/java/com/yapp18/retrospect/common/EntityCreator.java b/src/test/java/com/yapp18/retrospect/common/EntityCreator.java index ecc9bab..9dd10bc 100644 --- a/src/test/java/com/yapp18/retrospect/common/EntityCreator.java +++ b/src/test/java/com/yapp18/retrospect/common/EntityCreator.java @@ -1,6 +1,7 @@ package com.yapp18.retrospect.common; import com.yapp18.retrospect.domain.comment.Comment; +import com.yapp18.retrospect.domain.like.Like; import com.yapp18.retrospect.domain.post.Post; import com.yapp18.retrospect.domain.template.Template; import com.yapp18.retrospect.domain.user.Role; @@ -14,6 +15,7 @@ public class EntityCreator { private static final Long POST_IDX = 1L; private static final Long COMMENT_IDX = 1L; private static final Long TEMPLATE_IDX = 1L; + private static final Long LIKE_IDX = 1L; public static User createUserEntity(){ User user = User.builder() @@ -77,4 +79,17 @@ public static Comment createCommentEntity(){ return comment; } + + public static Like createLikeEntity(){ + Like like = Like.builder() + .likeIdx(LIKE_IDX) + .post(createPostEntity()) + .user(createUserEntity()) + .build(); + + like.setCreatedAt(LocalDateTime.of(2021, 10, 28, 12, 0, 0)); + like.setModifiedAt(LocalDateTime.of(2021, 10, 28, 12, 0, 0)); + + return like; + } } diff --git a/src/test/java/com/yapp18/retrospect/domain/comment/CommentRepositoryTest.java b/src/test/java/com/yapp18/retrospect/domain/comment/CommentRepositoryTest.java index 2847964..fe71d1d 100644 --- a/src/test/java/com/yapp18/retrospect/domain/comment/CommentRepositoryTest.java +++ b/src/test/java/com/yapp18/retrospect/domain/comment/CommentRepositoryTest.java @@ -35,7 +35,6 @@ public void init(){ @DatabaseSetup({ "classpath:dbunit/User/사용자_한명_존재.xml", "classpath:dbunit/Post/회고글_한개_존재.xml", - "classpath:dbunit/Comment/빈_댓글_테이블.xml" }) @ExpectedDatabase(value = "classpath:dbunit/Comment/댓글_한개_존재.xml", assertionMode = DatabaseAssertionMode.NON_STRICT) diff --git a/src/test/java/com/yapp18/retrospect/domain/like/LikeRepositoryTest.java b/src/test/java/com/yapp18/retrospect/domain/like/LikeRepositoryTest.java index 6c35b88..eff1e06 100644 --- a/src/test/java/com/yapp18/retrospect/domain/like/LikeRepositoryTest.java +++ b/src/test/java/com/yapp18/retrospect/domain/like/LikeRepositoryTest.java @@ -1,106 +1,126 @@ -//package com.yapp18.retrospect.domain.like; -// -//import com.yapp18.retrospect.domain.post.Post; -//import com.yapp18.retrospect.domain.template.Template; -//import com.yapp18.retrospect.domain.user.User; -//import org.junit.jupiter.api.AfterEach; -//import org.junit.jupiter.api.Test; -//import org.junit.jupiter.api.extension.ExtendWith; -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.boot.test.context.SpringBootTest; -//import org.springframework.test.context.junit.jupiter.SpringExtension; -// -//import java.util.List; -// -//import static org.assertj.core.api.Assertions.assertThat; -// -//@ExtendWith(SpringExtension.class) -//@SpringBootTest -//public class LikeRepositoryTest { -// @Autowired -// LikeRepository likeRepository; -// -// @AfterEach -// public void teardown() { -// likeRepository.deleteAll(); -// } -// -// String name_1 = "테스트 이름1"; -// String nickname_1 = "테스트 닉네임1"; -// String intro_1 = "테스트 자기소개1"; -// String email_1 = "test1@gmail.com"; -// String picture_1 = null; -// String platform_1 = "google"; -// String job_1 = "개발자"; -// String access_token_1 = null; -// -// String name_2 = "테스트 이름2"; -// String nickname_2 = "테스트 닉네임2"; -// String intro_2 = "테스트 자기소개2"; -// String email_2 = "test2@naver.com"; -// String picture_2 = null; -// String platform_2 = "naver"; -// String job_2 = "기획자"; -// String access_token_2 = null; -// -// User user1 = User.builder() -// .name(name_1) -// .nickname(nickname_1) -// .intro(intro_1) -// .email(email_1) -// .picture(picture_1) -// .platform(platform_1) -// .job(job_1) -// .build(); -// -// -// User user2 = User.builder() -// .name(name_2) -// .nickname(nickname_2) -// .intro(intro_2) -// .email(email_2) -// .picture(picture_2) -// .platform(platform_2) -// .job(job_2) -// .build(); -// -// String template_name = "4F"; -// String template_content = "..."; -// -// Template template = Template.builder() -// .template_name(template_name) -// .template(template_content) -// .user(user2) -// .build(); -// -// String category = "개발"; -// String title = "테스트 제목"; -// String content = "테스트 콘텐츠"; -// long view = 0; -// -// Post post = Post.builder() -// .category(category) -// .title(title) -// .contents(content) -// .view(view) -// .user(user2) -// .template(template) -// .build(); -// -// @Test -// public void 스크랩저장_불러오기() { -// likeRepository.save(Like.builder() -// .user(user1) -// .post(post) -// .build() -// ); -// -// List likeList = likeRepository.findAll(); -// -// Like like = likeList.get(0); -// -// assertThat(like.getUser().getName()).isEqualTo(name_1); -// assertThat(like.getPost().getUser().getName()).isEqualTo(name_2); -// assertThat(like.getPost().getTitle()).isEqualTo(title); -// } -//} +package com.yapp18.retrospect.domain.like; + +import com.github.springtestdbunit.annotation.DatabaseSetup; +import com.github.springtestdbunit.annotation.ExpectedDatabase; +import com.github.springtestdbunit.assertion.DatabaseAssertionMode; +import com.yapp18.retrospect.annotation.RetrospectDataTest; +import com.yapp18.retrospect.common.EntityCreator; +import com.yapp18.retrospect.domain.post.Post; +import com.yapp18.retrospect.domain.user.User; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; + +import javax.persistence.EntityManager; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@RetrospectDataTest +public class LikeRepositoryTest { + @Autowired + LikeRepository likeRepository; + + @Autowired + EntityManager entityManager; + + private final long USER_IDX = 1; + private final long LIKE_IDX = 1; + + @BeforeEach + public void init(){ + likeRepository.restartIdxSequence(); // likeIdx sequence 초기화 + } + + @Test + @DatabaseSetup({ + "classpath:dbunit/User/사용자_한명_존재.xml", + "classpath:dbunit/Post/회고글_한개_존재.xml", + }) + @ExpectedDatabase(value = "classpath:dbunit/Like/스크랩_한개_존재.xml", + assertionMode = DatabaseAssertionMode.NON_STRICT) + public void 스크랩_등록() { + likeRepository.save(EntityCreator.createLikeEntity()); + } + + @Test + @DatabaseSetup({ + "classpath:dbunit/User/사용자_두명_존재.xml", + "classpath:dbunit/Post/회고글_두개_존재.xml", + "classpath:dbunit/Like/스크랩_두개_존재.xml" + }) + public void 스크랩_조회_유저_별_생성일자_내림차순() { + User user = EntityCreator.createUserEntity(); + + List listList = likeRepository.findByUserOrderByCreatedAtDesc(user, PageRequest.of(0, 2)); + + assertThat(listList.size()).isEqualTo(2); + //내림차순이니까 2부터 + assertThat(listList.get(0).getLikeIdx()).isEqualTo(2L); + assertThat(listList.get(0).getPost().getPostIdx()).isEqualTo(2L); + assertThat(listList.get(1).getLikeIdx()).isEqualTo(1L); + assertThat(listList.get(1).getPost().getPostIdx()).isEqualTo(1L); + } + + @Test + @DatabaseSetup({ + "classpath:dbunit/User/사용자_두명_존재.xml", + "classpath:dbunit/Post/회고글_네개_존재.xml", + "classpath:dbunit/Like/스크랩_다섯개_존재.xml" + }) + public void 스크랩_커서_조회_유저_별_생성일자_내림차순() { + List listList = likeRepository.cursorFindByUserOrderByCreatedAtDesc(5L, USER_IDX, PageRequest.of(0, 2)); + + assertThat(listList.size()).isEqualTo(2); + //내림차순이니까 2부터 + assertThat(listList.get(0).getLikeIdx()).isEqualTo(2L); + assertThat(listList.get(0).getPost().getPostIdx()).isEqualTo(2L); + assertThat(listList.get(1).getLikeIdx()).isEqualTo(1L); + assertThat(listList.get(1).getPost().getPostIdx()).isEqualTo(1L); + } + + @Test + @DatabaseSetup({ + "classpath:dbunit/User/사용자_두명_존재.xml", + "classpath:dbunit/Post/회고글_네개_존재.xml", + "classpath:dbunit/Like/스크랩_다섯개_존재.xml" + }) + public void 스크랩_페이징_True() { + User user = EntityCreator.createUserEntity(); + + boolean result = likeRepository.existsByUserAndLikeIdxLessThan(user, 4L); + + assertThat(result).isEqualTo(true); + } + + @Test + @DatabaseSetup({ + "classpath:dbunit/User/사용자_두명_존재.xml", + "classpath:dbunit/Post/회고글_네개_존재.xml", + "classpath:dbunit/Like/스크랩_다섯개_존재.xml" + }) + public void 스크랩_페이징_False() { + User user = EntityCreator.createUserEntity(); + user.setUserIdx(2L); + + boolean result = likeRepository.existsByUserAndLikeIdxLessThan(user, 3L); + + assertThat(result).isEqualTo(false); + } + + @Test + @DatabaseSetup({ + "classpath:dbunit/User/사용자_한명_존재.xml", + "classpath:dbunit/Post/회고글_한개_존재.xml", + "classpath:dbunit/Like/스크랩_한개_존재.xml" + }) + @ExpectedDatabase(value = "classpath:dbunit/common/빈_테이블.xml", + assertionMode = DatabaseAssertionMode.NON_STRICT) + public void 스크랩_삭제_사용자_회고글() { + User user = EntityCreator.createUserEntity(); + Post post = EntityCreator.createPostEntity(); + + likeRepository.deleteByUserAndPost(user, post); + } +} diff --git a/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java b/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java index 9bf0be7..84addd0 100644 --- a/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java +++ b/src/test/java/com/yapp18/retrospect/domain/user/UserRepositoryTest.java @@ -16,7 +16,6 @@ import static org.assertj.core.api.Assertions.assertThat; @RetrospectDataTest -@DatabaseSetup({"classpath:dbunit/User/빈_사용자_테이블.xml"}) public class UserRepositoryTest { @Autowired UserRepository userRepository; @@ -32,7 +31,6 @@ public void init(){ } @Test - @DatabaseSetup({"classpath:dbunit/User/빈_사용자_테이블.xml"}) @ExpectedDatabase(value = "classpath:dbunit/User/사용자_한명_존재.xml", assertionMode = DatabaseAssertionMode.NON_STRICT) public void 사용자_정보_등록() { @@ -114,7 +112,7 @@ public void init(){ @Test @DatabaseSetup(value = "classpath:dbunit/User/사용자_한명_존재.xml") - @ExpectedDatabase(value = "classpath:dbunit/User/빈_사용자_테이블.xml", assertionMode = DatabaseAssertionMode.NON_STRICT) + @ExpectedDatabase(value = "classpath:dbunit/common/빈_테이블.xml", assertionMode = DatabaseAssertionMode.NON_STRICT) public void 사용자_정보_삭제() { User user = userRepository.findById(USER_IDX) .orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL)); diff --git "a/src/test/resources/dbunit/Like/\354\212\244\355\201\254\353\236\251_\353\213\244\354\204\257\352\260\234_\354\241\264\354\236\254.xml" "b/src/test/resources/dbunit/Like/\354\212\244\355\201\254\353\236\251_\353\213\244\354\204\257\352\260\234_\354\241\264\354\236\254.xml" new file mode 100644 index 0000000..7011884 --- /dev/null +++ "b/src/test/resources/dbunit/Like/\354\212\244\355\201\254\353\236\251_\353\213\244\354\204\257\352\260\234_\354\241\264\354\236\254.xml" @@ -0,0 +1,27 @@ + + + + + + + + + + + + \ No newline at end of file diff --git "a/src/test/resources/dbunit/Like/\354\212\244\355\201\254\353\236\251_\353\221\220\352\260\234_\354\241\264\354\236\254.xml" "b/src/test/resources/dbunit/Like/\354\212\244\355\201\254\353\236\251_\353\221\220\352\260\234_\354\241\264\354\236\254.xml" new file mode 100644 index 0000000..c4d7038 --- /dev/null +++ "b/src/test/resources/dbunit/Like/\354\212\244\355\201\254\353\236\251_\353\221\220\352\260\234_\354\241\264\354\236\254.xml" @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git "a/src/test/resources/dbunit/Like/\354\212\244\355\201\254\353\236\251_\355\225\234\352\260\234_\354\241\264\354\236\254.xml" "b/src/test/resources/dbunit/Like/\354\212\244\355\201\254\353\236\251_\355\225\234\352\260\234_\354\241\264\354\236\254.xml" new file mode 100644 index 0000000..c6185cf --- /dev/null +++ "b/src/test/resources/dbunit/Like/\354\212\244\355\201\254\353\236\251_\355\225\234\352\260\234_\354\241\264\354\236\254.xml" @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git "a/src/test/resources/dbunit/Post/\355\232\214\352\263\240\352\270\200_\353\204\244\352\260\234_\354\241\264\354\236\254.xml" "b/src/test/resources/dbunit/Post/\355\232\214\352\263\240\352\270\200_\353\204\244\352\260\234_\354\241\264\354\236\254.xml" new file mode 100644 index 0000000..a4c7d0f --- /dev/null +++ "b/src/test/resources/dbunit/Post/\355\232\214\352\263\240\352\270\200_\353\204\244\352\260\234_\354\241\264\354\236\254.xml" @@ -0,0 +1,29 @@ + + + + + + + + + \ No newline at end of file diff --git "a/src/test/resources/dbunit/Post/\355\232\214\352\263\240\352\270\200_\353\221\220\352\260\234_\354\241\264\354\236\254.xml" "b/src/test/resources/dbunit/Post/\355\232\214\352\263\240\352\270\200_\353\221\220\352\260\234_\354\241\264\354\236\254.xml" new file mode 100644 index 0000000..833d7e0 --- /dev/null +++ "b/src/test/resources/dbunit/Post/\355\232\214\352\263\240\352\270\200_\353\221\220\352\260\234_\354\241\264\354\236\254.xml" @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git "a/src/test/resources/dbunit/User/\353\271\210_\354\202\254\354\232\251\354\236\220_\355\205\214\354\235\264\353\270\224.xml" "b/src/test/resources/dbunit/common/\353\271\210_\355\205\214\354\235\264\353\270\224.xml" similarity index 98% rename from "src/test/resources/dbunit/User/\353\271\210_\354\202\254\354\232\251\354\236\220_\355\205\214\354\235\264\353\270\224.xml" rename to "src/test/resources/dbunit/common/\353\271\210_\355\205\214\354\235\264\353\270\224.xml" index e83b00b..c42acca 100644 --- "a/src/test/resources/dbunit/User/\353\271\210_\354\202\254\354\232\251\354\236\220_\355\205\214\354\235\264\353\270\224.xml" +++ "b/src/test/resources/dbunit/common/\353\271\210_\355\205\214\354\235\264\353\270\224.xml" @@ -1,3 +1,4 @@ + \ No newline at end of file From 08b55acd7b64c0720100e0d50817823a9e930538 Mon Sep 17 00:00:00 2001 From: HurJungMin Date: Wed, 21 Jul 2021 14:36:53 +0900 Subject: [PATCH 8/9] =?UTF-8?q?Chore:=20=ED=9A=8C=EA=B3=A0=EA=B8=80=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yapp18/retrospect/config/ErrorInfo.java | 3 +- .../retrospect/service/PostService.java | 21 +++--- .../web/advice/ControllerAdvice.java | 3 +- src/main/resources/application-key.yaml | 2 + .../retrospect/post/PostControllerTest.java | 4 ++ .../yapp18/retrospect/post/PostCrudTest.java | 66 ----------------- .../retrospect/post/PostServiceTest.java | 71 +++++++++++++++++++ 7 files changed, 93 insertions(+), 77 deletions(-) create mode 100644 src/main/resources/application-key.yaml create mode 100644 src/test/java/com/yapp18/retrospect/post/PostControllerTest.java delete mode 100644 src/test/java/com/yapp18/retrospect/post/PostCrudTest.java create mode 100644 src/test/java/com/yapp18/retrospect/post/PostServiceTest.java diff --git a/src/main/java/com/yapp18/retrospect/config/ErrorInfo.java b/src/main/java/com/yapp18/retrospect/config/ErrorInfo.java index 9d6c8fc..300c274 100644 --- a/src/main/java/com/yapp18/retrospect/config/ErrorInfo.java +++ b/src/main/java/com/yapp18/retrospect/config/ErrorInfo.java @@ -10,7 +10,8 @@ public enum ErrorInfo { TEMPLATE_NULL("EE004", "존재하지 않는 템플릿입니다."), TAG_NULL("EE005", "존재하지 않는 태그입니다."), IMAGE_NULL("EE006", "존재하지 않는 이미지입니다."), - LIKE_NULL("EE007", "존재하지 않는 스크랩입니다."); + LIKE_NULL("EE007", "존재하지 않는 스크랩입니다."), + CONDITION_NULL("EE008","해당 조건에 맞는 회고글이 없습니다."); private final String errorCode; private final String errorMessage; diff --git a/src/main/java/com/yapp18/retrospect/service/PostService.java b/src/main/java/com/yapp18/retrospect/service/PostService.java index 27cf050..dd77910 100644 --- a/src/main/java/com/yapp18/retrospect/service/PostService.java +++ b/src/main/java/com/yapp18/retrospect/service/PostService.java @@ -70,25 +70,30 @@ public Post findByPostIdx(Long postIdx){ @Transactional(readOnly = true) public ApiPagingResultResponse getPostsListView(Long cursorId, Pageable page, Long userIdx){ // 마지막으로 검색된 회고글의 조회수 - List result = getPostsView(cursorId, page).stream().map(post->postMapper.postToListResponse(post, userIdx)) + List posts = getPostsView(cursorId, page); + if (posts.isEmpty()) throw new EntityNullException(ErrorInfo.CONDITION_NULL); + + List result = posts.stream().map(post->postMapper.postToListResponse(post, userIdx)) .collect(Collectors.toList()); Long lastIdx = result.isEmpty() ? null : result.get(result.size()-1).getPostIdx(); // 다음 postIdx return new ApiPagingResultResponse<>(isNextView(lastIdx), result); } + // 최신순 @Transactional(readOnly = true) public ApiPagingResultResponse getPostsListCreatedAt(Long cursorIdx, Long userIdx, Pageable pageable){ User user = userRepository.findByUserIdx(userIdx) .orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL)); - List postList = cursorIdx == 0 || cursorIdx == null ? + List posts = cursorIdx == 0 || cursorIdx == null ? postRepository.findByUserOrderByCreatedAtDesc(user, pageable) : postRepository.cursorFindByUserOrderByCreatedAtDesc(cursorIdx, user.getUserIdx(), pageable); + if (posts.isEmpty()) throw new EntityNullException(ErrorInfo.CONDITION_NULL); - Long lastIdx = postList.isEmpty() ? null : postList.get(postList.size() - 1).getPostIdx(); // 낮은 조회수 체크 + Long lastIdx = posts.isEmpty() ? null : posts.get(posts.size() - 1).getPostIdx(); // 낮은 조회수 체크 - List result = postList.stream() + List result = posts.stream() .map(post -> postMapper.postToListResponse(post, userIdx)) .collect(Collectors.toList()); @@ -101,7 +106,9 @@ public ApiPagingResultResponse getPostsListCreatedAt(Long public ApiIsResultResponse findPostContents(Long postIdx, Long userIdx){ Post post = postRepository.findById(postIdx) .orElseThrow(() -> new EntityNullException(ErrorInfo.POST_NULL)); - post.updateview(post.getView()); // 조회수 증가 + // 조회수 증가 + post.updateview(post.getView()); + if(userIdx != 0L){ listService.saveRecentReadPosts(userIdx, postIdx); // 최근 읽은 글에 추가 } @@ -181,10 +188,6 @@ public boolean deletePosts(Long userIdx,Long postIdx) { .orElseThrow(() -> new EntityNullException(ErrorInfo.POST_NULL)); if (isWriter(post.getUser().getUserIdx(), userIdx)){ postRepository.deleteById(postIdx); -// if (listService.isPostsExist(userIdx, postIdx)) { -// // ** redis에 있는 모든...어쩌구.... -// listService.deleteRedisPost(userIdx, postIdx); // redis 에서도 삭제 -// } return true; } return false; diff --git a/src/main/java/com/yapp18/retrospect/web/advice/ControllerAdvice.java b/src/main/java/com/yapp18/retrospect/web/advice/ControllerAdvice.java index ae05478..b08e3fd 100644 --- a/src/main/java/com/yapp18/retrospect/web/advice/ControllerAdvice.java +++ b/src/main/java/com/yapp18/retrospect/web/advice/ControllerAdvice.java @@ -1,5 +1,6 @@ package com.yapp18.retrospect.web.advice; +import com.yapp18.retrospect.web.dto.ApiDefaultResponse; import com.yapp18.retrospect.web.dto.ErrorDefaultResponse; import com.yapp18.retrospect.web.dto.ErrorDto; import org.springframework.http.HttpStatus; @@ -79,7 +80,7 @@ public ResponseEntity> restExceptionHandler(RestException e) // @ExceptionHandler(EntityNullException.class) // public ResponseEntity entityNullExceptionHandler(EntityNullException e) { -// return new ResponseEntity<>(ApiDefaultResponse.res(404, e.getMessage()), e.getStatus()); +// return new ResponseEntity<>(ApiDefaultResponse.res(404, e.getMessage()), e.getCode()); // } // @ResponseStatus(HttpStatus.BAD_REQUEST) diff --git a/src/main/resources/application-key.yaml b/src/main/resources/application-key.yaml new file mode 100644 index 0000000..5711bb0 --- /dev/null +++ b/src/main/resources/application-key.yaml @@ -0,0 +1,2 @@ +secret: + access: accessTokenSecret \ No newline at end of file diff --git a/src/test/java/com/yapp18/retrospect/post/PostControllerTest.java b/src/test/java/com/yapp18/retrospect/post/PostControllerTest.java new file mode 100644 index 0000000..69a6c1c --- /dev/null +++ b/src/test/java/com/yapp18/retrospect/post/PostControllerTest.java @@ -0,0 +1,4 @@ +package com.yapp18.retrospect.post; + +public class PostControllerTest { +} diff --git a/src/test/java/com/yapp18/retrospect/post/PostCrudTest.java b/src/test/java/com/yapp18/retrospect/post/PostCrudTest.java deleted file mode 100644 index 8319662..0000000 --- a/src/test/java/com/yapp18/retrospect/post/PostCrudTest.java +++ /dev/null @@ -1,66 +0,0 @@ -//package com.yapp18.retrospect.post; -// -//import com.yapp18.retrospect.domain.post.Post; -//import com.yapp18.retrospect.domain.post.PostQueryRepository; -//import com.yapp18.retrospect.domain.post.PostRepository; -//import com.yapp18.retrospect.domain.template.Template; -//import com.yapp18.retrospect.domain.template.TemplateRepository; -//import com.yapp18.retrospect.domain.user.Role; -//import com.yapp18.retrospect.domain.user.User; -//import com.yapp18.retrospect.domain.user.UserRepository; -//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 java.awt.font.OpenType; -//import java.util.Optional; -// -//@DataJpaTest -//public class PostCrudTest { -// -// @Autowired -// PostRepository postRepository; -// -// @Autowired -// UserRepository userRepository; -// -// @Autowired -// TemplateRepository templateRepository; -// -// @BeforeEach -// void setUp(){ -// // user 설정 -// User user1 = User.builder() -// .name("허정민").nickname("tape22").intro("자기소개.").job("백수") -// .email("test@naver.com").profile("profile_url") -// .provider("google").providerId("13453252535").role(Role.MEMBER).build(); -// // template 설정 -// Template template = Template.builder().template("템플릿").templateName("4F").build(); -// -// userRepository.save(user1); -// templateRepository.save(template); -// -// System.out.println(user1.getUserIdx()); -// System.out.println(template.getTemplateIdx()); -// -// } -// -// @Test -// @DisplayName("회고글 목록 조회: 최신순") -// void getRecentPostsList(){ -// // given -//// User user = userRepository.findById(1L); -//// Post post = Post.builder() -//// .category("design") -//// .contents("내용.......!!!!") -//// .title("테스트 1 제목") -//// .user(user) -//// .build(); -// -// // when -// // then -// System.out.println("test..."); -// } -//} diff --git a/src/test/java/com/yapp18/retrospect/post/PostServiceTest.java b/src/test/java/com/yapp18/retrospect/post/PostServiceTest.java new file mode 100644 index 0000000..9125525 --- /dev/null +++ b/src/test/java/com/yapp18/retrospect/post/PostServiceTest.java @@ -0,0 +1,71 @@ +package com.yapp18.retrospect.post; + +import com.yapp18.retrospect.common.EntityCreator; +import com.yapp18.retrospect.domain.post.Post; +import com.yapp18.retrospect.domain.post.PostQueryRepository; +import com.yapp18.retrospect.domain.post.PostRepository; +import com.yapp18.retrospect.domain.template.Template; +import com.yapp18.retrospect.domain.template.TemplateRepository; +import com.yapp18.retrospect.domain.user.Role; +import com.yapp18.retrospect.domain.user.User; +import com.yapp18.retrospect.domain.user.UserRepository; +import com.yapp18.retrospect.security.oauth2.AuthProvider; +import com.yapp18.retrospect.service.PostService; +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.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.domain.PageRequest; + +import java.awt.font.OpenType; +import java.util.List; +import java.util.Optional; + +//@DataJpaTest +@ExtendWith(MockitoExtension.class) +public class PostServiceTest { + + @InjectMocks + private PostService postService; + + @Mock + private PostRepository postRepository; + @Mock + private UserRepository userRepository; + @Mock + private TemplateRepository templateRepository; + + @BeforeEach + void setUp(){ +// // user 설정 +// User user1 = User.builder() +// .name("허정민").nickname("tape22").intro("자기소개.").job("백수") +// .email("test@naver.com").profile("profile_url") +// .provider(AuthProvider.google).providerId("13453252535").role(Role.MEMBER).build(); +// // template 설정 +// Template template = Template.builder().template("템플릿").templateName("4F").build(); +// +// userRepository.save(user1); +// templateRepository.save(template); +// +// System.out.println(user1.getUserIdx()); +// System.out.println(template.getTemplateIdx()); + } + + @Test + void 회고글이_없는_경우(){ + // list로 글 읽어오기 + List posts = postRepository.findAllByOrderByViewDesc(PageRequest.of(0,10)); + System.out.println(posts); + + // when + + // 없으면 빈 배열? 아니면 exception? + + } +} From 6cb3aba4218168ae5fd6b2eb4be416d82b0e625b Mon Sep 17 00:00:00 2001 From: HurJungMin Date: Wed, 21 Jul 2021 15:35:37 +0900 Subject: [PATCH 9/9] =?UTF-8?q?Refactor:=20PostController=20@CurrentUser?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD,=20ResponseEntity=20=EB=B9=8C?= =?UTF-8?q?=EB=8D=94=20=ED=83=80=EC=9E=85=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../retrospect/service/PostService.java | 21 ++-- .../retrospect/service/SearchService.java | 21 ++-- .../retrospect/service/UserService.java | 5 + .../web/controller/PostController.java | 102 ++++++++---------- 4 files changed, 75 insertions(+), 74 deletions(-) diff --git a/src/main/java/com/yapp18/retrospect/service/PostService.java b/src/main/java/com/yapp18/retrospect/service/PostService.java index dd77910..1c23dfa 100644 --- a/src/main/java/com/yapp18/retrospect/service/PostService.java +++ b/src/main/java/com/yapp18/retrospect/service/PostService.java @@ -103,18 +103,16 @@ public ApiPagingResultResponse getPostsListCreatedAt(Long // 회고글 상세페이지 @Transactional(isolation = Isolation.READ_COMMITTED) - public ApiIsResultResponse findPostContents(Long postIdx, Long userIdx){ + public Post findPostContents(Long postIdx, Long userIdx){ Post post = postRepository.findById(postIdx) .orElseThrow(() -> new EntityNullException(ErrorInfo.POST_NULL)); // 조회수 증가 post.updateview(post.getView()); - + // 최근 읽은 글에 추가 if(userIdx != 0L){ - listService.saveRecentReadPosts(userIdx, postIdx); // 최근 읽은 글에 추가 + listService.saveRecentReadPosts(userIdx, postIdx); } - return new ApiIsResultResponse<>(isWriter(post.getUser().getUserIdx(),userIdx), - isScrap(post, userIdx), - postMapper.postToDetailResponse(post)); // 작성자 판단 + return post; } @@ -183,14 +181,13 @@ public Long updatePosts(Long userIdx,Long postIdx, PostDto.updateRequest request // 회고글 삭제 @Transactional - public boolean deletePosts(Long userIdx,Long postIdx) { + public void deletePosts(Long userIdx,Long postIdx) { Post post = postRepository.findById(postIdx) .orElseThrow(() -> new EntityNullException(ErrorInfo.POST_NULL)); - if (isWriter(post.getUser().getUserIdx(), userIdx)){ + if (!isWriter(post.getUser().getUserIdx(), userIdx)) throw new EntityNullException(ErrorInfo.POST_NULL); + else{ postRepository.deleteById(postIdx); - return true; } - return false; } @@ -215,13 +212,13 @@ public boolean isView(User user, Long cursorId){ // 작성자 판별 - private boolean isWriter(Long postUserIdx, Long userIdx){ + public boolean isWriter(Long postUserIdx, Long userIdx){ if (userIdx == 0L) return false; return postUserIdx.equals(userIdx); } // 스크랩 여부 판별 -> 리팩토링 필요 - private boolean isScrap(Post post, Long userIdx){ + public boolean isScrap(Post post, Long userIdx){ return likeRepository.findByPostAndUserUserIdx(post, userIdx).isPresent(); } diff --git a/src/main/java/com/yapp18/retrospect/service/SearchService.java b/src/main/java/com/yapp18/retrospect/service/SearchService.java index 39ea944..889763b 100644 --- a/src/main/java/com/yapp18/retrospect/service/SearchService.java +++ b/src/main/java/com/yapp18/retrospect/service/SearchService.java @@ -1,9 +1,11 @@ package com.yapp18.retrospect.service; +import com.yapp18.retrospect.config.ErrorInfo; import com.yapp18.retrospect.domain.post.Post; import com.yapp18.retrospect.domain.post.PostQueryRepository; import com.yapp18.retrospect.domain.post.PostRepository; import com.yapp18.retrospect.mapper.PostMapper; +import com.yapp18.retrospect.web.advice.EntityNullException; import com.yapp18.retrospect.web.dto.ApiPagingResultResponse; import com.yapp18.retrospect.web.dto.PostDto; import com.yapp18.retrospect.web.dto.SearchDto; @@ -30,15 +32,20 @@ public ApiPagingResultResponse searchByType(SearchDto sear // 카테고리 검색 시 List result; if (searchDto.getType().equals("category") && searchDto.getKeyword() == null){ // 검색타입이 카테고리고 키워드가 없음. - result = getPostCategory(searchDto.getPage(), pageable, searchDto.getQuery()) // cursorId, 페이지 정보, 쿼리 넘김(카테고리) - .stream().map(post->postMapper.postToListResponse(post, userIdx)) + List posts = getPostCategory(searchDto.getPage(), pageable, searchDto.getQuery()) ;// cursorId, 페이지 정보, 쿼리 넘김(카테고리) + if (posts.isEmpty()) throw new EntityNullException(ErrorInfo.CONDITION_NULL); + + result = posts.stream().map(post->postMapper.postToListResponse(post, userIdx)) .collect(Collectors.toList()); } else{ // 통합 검색 시 - result = findAllByType(searchDto.getType(), searchDto.getQuery(), searchDto.getKeyword(), searchDto.getPage(),pageable) - .stream().map(post->postMapper.postToListResponse(post, userIdx)) + List posts = findAllByType(searchDto.getType(), searchDto.getQuery(), searchDto.getKeyword(), searchDto.getPage(),pageable); + if (posts.isEmpty()) throw new EntityNullException(ErrorInfo.CONDITION_NULL); + + result = posts.stream().map(post->postMapper.postToListResponse(post, userIdx)) .collect(Collectors.toList()); } + Long lastIdx = result.isEmpty() ? null : result.get(result.size()-1).getPostIdx(); return new ApiPagingResultResponse<>(isNext(searchDto, pageable, lastIdx), result); } @@ -47,7 +54,10 @@ public ApiPagingResultResponse searchByType(SearchDto sear // 해시태그로 검색 @Transactional(readOnly = true) public ApiPagingResultResponse getPostsByHashTag(String tag, Long cursorId, Pageable pageable, Long userIdx){ - List result = findAllByTag(cursorId, pageable, tag).stream() + List posts = findAllByTag(cursorId, pageable, tag); + if (posts.isEmpty()) throw new EntityNullException(ErrorInfo.CONDITION_NULL); + + List result= posts.stream() .map(post->postMapper.postToListResponse(post, userIdx)) .collect(Collectors.toList()); Long lastIdx = result.isEmpty() ? null : result.get(result.size()-1).getPostIdx(); @@ -55,7 +65,6 @@ public ApiPagingResultResponse getPostsByHashTag(String ta } - // 통합 검색 분기처리 private List findAllByType(String type, String query, String keyword, Long cursorId, Pageable page){ return cursorId == null || cursorId == 0 ? diff --git a/src/main/java/com/yapp18/retrospect/service/UserService.java b/src/main/java/com/yapp18/retrospect/service/UserService.java index 4fbd5e6..263eb5e 100644 --- a/src/main/java/com/yapp18/retrospect/service/UserService.java +++ b/src/main/java/com/yapp18/retrospect/service/UserService.java @@ -89,4 +89,9 @@ public User findByUserEmail(String email){ return userRepository.findByEmail(email) .orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL)); } + + + public Long getUserInfoFromToken(User user){ + return (user != null)? user.getUserIdx(): 0L; + } } diff --git a/src/main/java/com/yapp18/retrospect/web/controller/PostController.java b/src/main/java/com/yapp18/retrospect/web/controller/PostController.java index 133aaea..a554e67 100644 --- a/src/main/java/com/yapp18/retrospect/web/controller/PostController.java +++ b/src/main/java/com/yapp18/retrospect/web/controller/PostController.java @@ -1,10 +1,16 @@ package com.yapp18.retrospect.web.controller; +import com.yapp18.retrospect.annotation.CurrentUser; import com.yapp18.retrospect.config.ResponseMessage; +import com.yapp18.retrospect.domain.post.Post; +import com.yapp18.retrospect.domain.user.User; +import com.yapp18.retrospect.mapper.PostMapper; import com.yapp18.retrospect.service.PostService; import com.yapp18.retrospect.service.TokenService; +import com.yapp18.retrospect.service.UserService; import com.yapp18.retrospect.web.dto.ApiDefaultResponse; +import com.yapp18.retrospect.web.dto.ApiIsResultResponse; import com.yapp18.retrospect.web.dto.PostDto; import io.swagger.annotations.*; import lombok.RequiredArgsConstructor; @@ -24,30 +30,22 @@ public class PostController { private final PostService postService; private final TokenService tokenService; + private final UserService userService; + private final PostMapper postMapper; private static final int DEFAULT_SIZE = 20; -// @ApiOperation(value = "main", notes = "[메인] 회고글 목록 조회, 최신순") // api tag, 설명 -// @GetMapping("/lists/new") -// public ResponseEntity getMainPosts(@ApiParam(value = "현재 페이지 마지막 post_idx", required = true, example = "20") -// HttpServletRequest request, -// @RequestParam(value = "page", defaultValue = "0") Long page, -// @RequestParam(value = "pageSize",defaultValue = "20") Integer pageSize){ -// if (pageSize == null) pageSize = DEFAULT_SIZE; -// Long userIdx = (tokenService.getTokenFromRequest(request) != null) ? tokenService.getUserIdx(tokenService.getTokenFromRequest(request)) : 0L; -// return new ResponseEntity<>(ApiDefaultResponse.res(200,ResponseMessage.POST_FIND_RECENT.getResponseMessage(), -// postService.getPostsListRecent(page, PageRequest.of(0, pageSize), userIdx)), HttpStatus.OK); -// } - @ApiOperation(value = "main", notes = "[메인] 회고글 목록 조회, 누적조회순") @GetMapping("/lists") public ResponseEntity getMainPostsOrderByView(@ApiParam(value = "현재 페이지 마지막 post_idx", required = true, example = "20") - HttpServletRequest request, - @RequestParam(value = "page", defaultValue = "0") Long page, - @RequestParam(value = "pageSize") Integer pageSize){ + @CurrentUser User user, + @RequestParam(value = "page", defaultValue = "0") Long page, + @RequestParam(value = "pageSize") Integer pageSize){ if (pageSize == null) pageSize = DEFAULT_SIZE; - Long userIdx = (tokenService.getTokenFromRequest(request) != null) ? tokenService.getUserIdx(tokenService.getTokenFromRequest(request)) : 0L; - return new ResponseEntity<>(ApiDefaultResponse.res(200,ResponseMessage.POST_FIND_VIEW.getResponseMessage(), - postService.getPostsListView(page, PageRequest.of(0, pageSize), userIdx)), HttpStatus.OK); + + return ResponseEntity.status(HttpStatus.OK).body( + ApiDefaultResponse.res(200, + ResponseMessage.POST_FIND_VIEW.getResponseMessage(), + postService.getPostsListView(page, PageRequest.of(0,pageSize), userService.getUserInfoFromToken(user)))); } @ApiOperation(value = "main", notes = "[프로필] 유저 회고글 목록 조회, 생성일자순") @@ -57,68 +55,60 @@ public ResponseEntity getPostsByUserIdxOrderByCreatedAtDesc(@ApiParam(va @RequestParam(value = "page", defaultValue = "0") Long page, @RequestParam(value = "pageSize") Integer pageSize){ if (pageSize == null) pageSize = DEFAULT_SIZE; - return new ResponseEntity<>(ApiDefaultResponse.res(200, - ResponseMessage.POST_FIND_CREATED.getResponseMessage(), - postService.getPostsListCreatedAt(page, userIdx, PageRequest.of(0, pageSize))), HttpStatus.OK); + return ResponseEntity.status(HttpStatus.OK).body( + ApiDefaultResponse.res(200, ResponseMessage.POST_FIND_CREATED.getResponseMessage(), + postService.getPostsListCreatedAt(page, userIdx, PageRequest.of(0, pageSize)))); } @ApiOperation(value = "detail", notes = "[상세] 회고글 상세보기") @GetMapping("/{postIdx}") - public ResponseEntity findPostsContentById(HttpServletRequest request, + public ResponseEntity findPostsContentById(@CurrentUser User user, @ApiParam(value = "상세보기 post_idx", required = true, example = "3") @PathVariable(value = "postIdx") Long postIdx) { - Long userIdx = (tokenService.getTokenFromRequest(request) != null) ? tokenService.getUserIdx(tokenService.getTokenFromRequest(request)) : 0L; - return new ResponseEntity<>(ApiDefaultResponse.res(200,ResponseMessage.POST_DETAIL.getResponseMessage(), - postService.findPostContents(postIdx, userIdx)), HttpStatus.OK); - } + Long userIdx = userService.getUserInfoFromToken(user); + Post post = postService.findPostContents(postIdx, userIdx); + + return ResponseEntity.status(HttpStatus.OK).body( + new ApiIsResultResponse<>(postService.isWriter(post.getUser().getUserIdx(), userIdx), + postService.isScrap(post, userIdx), + postMapper.postToDetailResponse(post)) + ); + } @ApiOperation(value = "main", notes = "[메인]회고글 저장하기") @PostMapping("") - public ResponseEntity inputPosts(HttpServletRequest request, + public ResponseEntity inputPosts(@CurrentUser User user, @RequestBody PostDto.saveResponse saveResponse){ - Long postIdx = postService.inputPosts(saveResponse, tokenService.getUserIdx(tokenService.getTokenFromRequest(request))); - return new ResponseEntity<>(ApiDefaultResponse.res(200,ResponseMessage.POST_SAVE.getResponseMessage(), postIdx), HttpStatus.OK); + Long userIdx = userService.getUserInfoFromToken(user); + Long postIdx = postService.inputPosts(saveResponse, userIdx); + return ResponseEntity.status(HttpStatus.OK).body( + ApiDefaultResponse.res(200, ResponseMessage.POST_SAVE.getResponseMessage(), postIdx) + ); } @ApiOperation(value = "mypage", notes = "[마이페이지]회고글 수정하기") @PutMapping("/{postIdx}") - public ResponseEntity updatePosts(HttpServletRequest request, + public ResponseEntity updatePosts(@CurrentUser User user, @ApiParam(value = "회고글 post_idx", required = true, example = "1") @PathVariable(value = "postIdx") Long postIdx, @RequestBody PostDto.updateRequest requestDto){ - Long post = postService.updatePosts(tokenService.getUserIdx(tokenService.getTokenFromRequest(request)), postIdx, requestDto); - return new ResponseEntity<>(ApiDefaultResponse.res(200,ResponseMessage.POST_UPDATE.getResponseMessage(),post),HttpStatus.OK); + Long userIdx = userService.getUserInfoFromToken(user); + Long post = postService.updatePosts(userIdx, postIdx, requestDto); + return ResponseEntity.status(HttpStatus.OK).body( + ApiDefaultResponse.res(200, ResponseMessage.POST_UPDATE.getResponseMessage(), post) + ); } @ApiOperation(value = "mypage", notes = "[마이페이지]회고글 삭제하기") @DeleteMapping("/{postIdx}") - public ResponseEntity deletePosts(HttpServletRequest request, + public ResponseEntity deletePosts(@CurrentUser User user, @ApiParam(value = "회고글 post_idx", required = true, example = "1") @PathVariable(value = "postIdx") Long postIdx){ - boolean isPost = postService.deletePosts(tokenService.getUserIdx(tokenService.getTokenFromRequest(request)),postIdx); - if (!isPost){ - return new ResponseEntity<>(ApiDefaultResponse.res(400,"삭제할 idx 없음...", false),HttpStatus.BAD_REQUEST); - } - return new ResponseEntity<>(ApiDefaultResponse.res(200, ResponseMessage.POST_DELETE.getResponseMessage(), true),HttpStatus.OK); + postService.deletePosts(userService.getUserInfoFromToken(user),postIdx); + return ResponseEntity.status(HttpStatus.OK).body( + ApiDefaultResponse.res(200, ResponseMessage.POST_DELETE.getResponseMessage()) + ); } - - // @ApiOperation(value = "main", notes = "[메인] 카테고리 필터링") -// @GetMapping("/lists/category") -// public ResponseEntity findPostsByCategory(HttpServletRequest request, -// @ApiParam(value = "카테고리", required = true, example = "design") -// @RequestParam(value = "query") String query, -// @ApiParam(value = "page", required = true, example = "0") -// @RequestParam(value = "page") Long page, -// @ApiParam(value = "pageSize", required = true, example = "20") -// @RequestParam(value = "pageSize") Integer pageSize -// ){ -// if (pageSize == null) pageSize = DEFAULT_SIZE; -// System.out.println("_---->" + request.getQueryString()); -// System.out.println(query); -// Long userIdx = (tokenService.getTokenFromRequest(request) != null) ? tokenService.getUserIdx(tokenService.getTokenFromRequest(request)) : 0L; -// return new ResponseEntity<>(ApiDefaultResponse.res(200,ResponseMessage.POST_FIND_CATEGORY.getResponseMessage(), -// postService.getPostsByCategory(query, page, PageRequest.of(0,pageSize), userIdx)), HttpStatus.OK); -// } }