SNS 제작 (댓글 수정)

개발연습생log·2023년 1월 4일
0

SNS 제작

목록 보기
8/15
post-thumbnail

✨개요

🏃 목표

📢 댓글을 수정하는 기능을 구현하자.

📜 접근방법

  • 포스트 수정과 같은 방법으로 구현하면 된다.

✅ TO-DO

  • 댓글 수정 컨트롤러 테스트 구현
  • 댓글 수정 서비스 테스트 구현
  • 댓글 수정 컨트롤러 구현
  • 댓글 수정 서비스 구현

🔧 구현

댓글 수정 컨트롤러 테스트 구현

댓글 수정 성공

<@Test
    @DisplayName("댓글 수정 성공")
    @WithMockUser
    void comment_modify_SUCCESS() throws Exception {

        when(commentService.modify("홍길동", 1L, 1L, "테스트입니다."))
                .thenReturn(commentModifyResponse);

        mockMvc.perform(put("/api/v1/posts/1/comments/1")
                        .with(csrf())
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsBytes(new CommentRequest("테스트입니다."))))
                .andDo(print())
                .andExpect(status().isOk());
    }

댓글 수정 실패

  • 인증 실패
@Test
    @DisplayName("댓글 수정 실패1_로그인을 하지 않은 경우")
    @WithAnonymousUser
    void comment_modify_FAILD_login() throws Exception {
        when(commentService.modify("홍길동", 1L, 1L, "테스트입니다."))
                .thenThrow(new AppException(ErrorCode.USERNAME_NOT_FOUND, ErrorCode.USERNAME_NOT_FOUND.getMessage()));

        mockMvc.perform(put("/api/v1/posts/1/comments/1")
                        .with(csrf())
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsBytes(new CommentRequest("테스트입니다."))))
                .andDo(print())
                .andExpect(status().isUnauthorized());
    }
  • 작성자 불일치
@Test
    @DisplayName("댓글 작성 실패2_작성자 불일치인 경우")
    @WithMockUser
    void comment_modify_FAIL_different() throws Exception {

        when(commentService.modify(any(), any(), any(), any()))
                .thenThrow(new AppException(ErrorCode.INVALID_PERMISSION, ErrorCode.INVALID_PERMISSION.getMessage()));

        mockMvc.perform(put("/api/v1/posts/1/comments/1")
                        .with(csrf())
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsBytes(new CommentRequest("테스트입니다."))))
                .andDo(print())
                .andExpect(status().isUnauthorized());
    }
  • 데이터베이스 에러
@Test
    @DisplayName("댓글 작성 실패3_DB 에러인 경우")
    @WithMockUser
    void comment_modify_FAIL_db() throws Exception {

        when(commentService.modify(any(), any(), any(), any()))
                .thenThrow(new AppException(ErrorCode.DATABASE_ERROR, ErrorCode.DATABASE_ERROR.getMessage()));

        mockMvc.perform(put("/api/v1/posts/1/comments/1")
                        .with(csrf())
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsBytes(new CommentRequest("테스트입니다."))))
                .andDo(print())
                .andExpect(status().isInternalServerError());
    }

댓글 수정 서비스 테스트 구현

댓글 수정 성공

@Test
    @DisplayName("댓글 수정 성공")
    void comment_modify_SUCCESS() {
        when(userRepository.findByUserName(any()))
                .thenReturn(Optional.of(user));
        when(postRepository.findById(any()))
                .thenReturn(Optional.of(post));
        when(commentRepository.findById(any()))
                .thenReturn(Optional.of(comment));
        when(commentRepository.saveAndFlush(any()))
                .thenReturn(comment);

        assertDoesNotThrow(() -> commentService.modify(user.getUserName(), post.getId(), comment.getId(), comment.getComment()));
    }

댓글 수정 실패

  • 포스트 존재하지 않음
@Test
    @DisplayName("댓글 수정 실패2_포스트가 없는 경우")
    void comment_modify_FALID_post() {
        when(userRepository.findByUserName(any()))
                .thenReturn(Optional.of(user));
        when(postRepository.findById(any()))
                .thenReturn(Optional.empty());
        when(commentRepository.saveAndFlush(any()))
                .thenReturn(comment);

        AppException exception = assertThrows(AppException.class, () -> commentService.modify(user.getUserName(), post.getId(), comment.getId(), comment.getComment()));
        assertEquals(ErrorCode.POST_NOT_FOUND, exception.getErrorCode());
    }
  • 작성자 불일치
@Test
    @DisplayName("댓글 수정 실패3_작성자 불일치인 경우")
    void comment_modify_FALID_different() {
        when(userRepository.findByUserName(any()))
                .thenReturn(Optional.of(user2));
        when(postRepository.findById(any()))
                .thenReturn(Optional.of(post));
        when(commentRepository.findById(any()))
                .thenReturn(Optional.of(comment));
        when(commentRepository.saveAndFlush(any()))
                .thenReturn(comment);

        AppException exception = assertThrows(AppException.class, () -> commentService.modify(user2.getUserName(), post.getId(), comment.getId(), comment.getComment()));
        assertEquals(ErrorCode.INVALID_PERMISSION, exception.getErrorCode());
    }
  • 유저 존재하지 않음
@Test
    @DisplayName("댓글 수정 실패1_유저가 존재하지 않는 경우")
    void comment_modify_FALID_user() {
        when(userRepository.findByUserName(any()))
                .thenReturn(Optional.empty());
        when(postRepository.findById(any()))
                .thenReturn(Optional.of(post));
        when(commentRepository.saveAndFlush(any()))
                .thenReturn(comment);

        AppException exception = assertThrows(AppException.class, () -> commentService.modify(user.getUserName(), post.getId(), comment.getId(), comment.getComment()));
        assertEquals(ErrorCode.USERNAME_NOT_FOUND, exception.getErrorCode());
    }

댓글 수정 컨트롤러 구현

CommentController 메서드 추가

@PutMapping("/{id}")
    public ResponseEntity<Response> modify(Authentication authentication, @PathVariable Long postId, @PathVariable Long id, @RequestBody CommentRequest commentRequest){
        String userName = authentication.getName();
        CommentModifyResponse commentModifyResponse = commentService.modify(userName,postId,id,commentRequest.getComment());
        return ResponseEntity.ok().body(Response.of("SUCCESS", commentModifyResponse));
    }

CommentModifyResponse 구현

@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
@Setter
public class CommentModifyResponse {
    private Long id;
    private String comment;
    private String userName;
    private Long postId;
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd' 'HH:mm:ss", timezone = "Asia/Seoul")
    private LocalDateTime createdAt;
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd' 'HH:mm:ss", timezone = "Asia/Seoul")
    private LocalDateTime lastModifiedAt;

    public static CommentModifyResponse of(Comment comment) {
        return CommentModifyResponse.builder()
                .id(comment.getId())
                .comment(comment.getComment())
                .userName(comment.getUser().getUserName())
                .postId(comment.getPost().getId())
                .createdAt(comment.getCreatedAt())
                .lastModifiedAt(comment.getLastModifiedAt())
                .build();
    }
}

댓글 수정 서비스 구현

CommentService 메서드 추가

public CommentModifyResponse modify(String userName, Long postId, Long id, String comment) {
        //유저체크
        User findUser = AppUtil.findUser(userRepository, userName);
        //포스트 체크
        Post findPost = AppUtil.findPost(postRepository, postId);
        //댓글 체크
        Comment findComment = AppUtil.findComment(commentRepository, id);
        //작성자 체크
        AppUtil.compareUser(findComment.getUser().getUserName(), findUser.getUserName());
        //댓글 수정
        findComment.modify(comment);
        commentRepository.saveAndFlush(findComment);
        return CommentModifyResponse.of(findComment);
    }

AppUtil 메서드 추가

//댓글 체크
    public static Comment findComment(CommentRepository commentRepository, Long id) {
        return commentRepository.findById(id).orElseThrow(() -> {
            throw new AppException(ErrorCode.COMMENT_NOT_FOUND, ErrorCode.COMMENT_NOT_FOUND.getMessage());
        });
    }

Comment 메서드 추가

public void modify(String comment) {
        this.comment = comment;
    }

🌉회고

📖 회고

  • 구현하는 과정은 익숙해져 갔다.
  • 하지만 반복되는 코드 내용이 점점 많아지면서 AOP에 대해 공부할 필요성을 느끼게 되었다.
profile
주니어 개발자를 향해서..

0개의 댓글