|
24 | 24 | import org.springframework.transaction.annotation.Transactional; |
25 | 25 |
|
26 | 26 | import java.time.LocalDate; |
| 27 | +import java.util.List; |
27 | 28 |
|
28 | 29 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; |
29 | 30 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; |
@@ -581,4 +582,247 @@ void deleteComment_noToken() throws Exception { |
581 | 582 | .andExpect(jsonPath("$.code").value("AUTH_001")) |
582 | 583 | .andExpect(jsonPath("$.message").value("인증이 필요합니다.")); |
583 | 584 | } |
| 585 | + |
| 586 | + // ====================== 대댓글 생성 테스트 ====================== |
| 587 | + |
| 588 | + @Test |
| 589 | + @DisplayName("대댓글 생성 성공 → 201 Created") |
| 590 | + void createReply_success() throws Exception { |
| 591 | + // given: 유저 + 게시글 + 부모 댓글 |
| 592 | + User user = User. createUser( "writer", "[email protected]", passwordEncoder. encode( "P@ssw0rd!")); |
| 593 | + user.setUserProfile(new UserProfile(user, "이몽룡", null, null, LocalDate.of(2000, 1, 1), 1000)); |
| 594 | + user.setUserStatus(UserStatus.ACTIVE); |
| 595 | + userRepository.save(user); |
| 596 | + |
| 597 | + Post post = new Post(user, "첫 글", "내용"); |
| 598 | + postRepository.save(post); |
| 599 | + |
| 600 | + Comment parent = new Comment(post, user, "부모 댓글", null); |
| 601 | + commentRepository.save(parent); |
| 602 | + |
| 603 | + String accessToken = generateAccessToken(user); |
| 604 | + |
| 605 | + CommentRequest request = new CommentRequest("저도 동의합니다!"); |
| 606 | + |
| 607 | + // when |
| 608 | + ResultActions resultActions = mvc.perform( |
| 609 | + post("/api/posts/{postId}/comments/{commentId}/replies", post.getId(), parent.getId()) |
| 610 | + .header("Authorization", "Bearer " + accessToken) |
| 611 | + .contentType(MediaType.APPLICATION_JSON) |
| 612 | + .content(objectMapper.writeValueAsString(request)) |
| 613 | + ).andDo(print()); |
| 614 | + |
| 615 | + // then |
| 616 | + resultActions |
| 617 | + .andExpect(status().isCreated()) |
| 618 | + .andExpect(jsonPath("$.success").value(true)) |
| 619 | + .andExpect(jsonPath("$.code").value("SUCCESS_200")) |
| 620 | + .andExpect(jsonPath("$.data.content").value("저도 동의합니다!")) |
| 621 | + .andExpect(jsonPath("$.data.author.nickname").value("이몽룡")) |
| 622 | + .andExpect(jsonPath("$.data.postId").value(post.getId())) |
| 623 | + .andExpect(jsonPath("$.data.parentId").value(parent.getId())); |
| 624 | + } |
| 625 | + |
| 626 | + @Test |
| 627 | + @DisplayName("대댓글 생성 실패 - 존재하지 않는 사용자 → 404 Not Found") |
| 628 | + void createReply_userNotFound() throws Exception { |
| 629 | + // given: 게시글 + 부모 댓글 |
| 630 | + User user = User. createUser( "writer", "[email protected]", passwordEncoder. encode( "P@ssw0rd!")); |
| 631 | + user.setUserProfile(new UserProfile(user, "이몽룡", null, null, null, 0)); |
| 632 | + user.setUserStatus(UserStatus.ACTIVE); |
| 633 | + userRepository.save(user); |
| 634 | + |
| 635 | + Post post = new Post(user, "제목", "내용"); |
| 636 | + postRepository.save(post); |
| 637 | + |
| 638 | + Comment parent = new Comment(post, user, "부모 댓글", null); |
| 639 | + commentRepository.save(parent); |
| 640 | + |
| 641 | + // DB에 없는 userId로 JWT 발급 |
| 642 | + String fakeToken = testJwtTokenProvider. createAccessToken( 999L, "[email protected]", "USER"); |
| 643 | + |
| 644 | + CommentRequest request = new CommentRequest("대댓글 내용"); |
| 645 | + |
| 646 | + // when & then |
| 647 | + mvc.perform(post("/api/posts/{postId}/comments/{commentId}/replies", post.getId(), parent.getId()) |
| 648 | + .header("Authorization", "Bearer " + fakeToken) |
| 649 | + .contentType(MediaType.APPLICATION_JSON) |
| 650 | + .content(objectMapper.writeValueAsString(request))) |
| 651 | + .andDo(print()) |
| 652 | + .andExpect(status().isNotFound()) |
| 653 | + .andExpect(jsonPath("$.code").value("USER_001")) |
| 654 | + .andExpect(jsonPath("$.message").value("존재하지 않는 사용자입니다.")); |
| 655 | + } |
| 656 | + |
| 657 | + @Test |
| 658 | + @DisplayName("대댓글 생성 실패 - 존재하지 않는 게시글 → 404 Not Found") |
| 659 | + void createReply_postNotFound() throws Exception { |
| 660 | + // given |
| 661 | + User user = User. createUser( "writer", "[email protected]", passwordEncoder. encode( "P@ssw0rd!")); |
| 662 | + user.setUserProfile(new UserProfile(user, "이몽룡", null, null, null, 0)); |
| 663 | + user.setUserStatus(UserStatus.ACTIVE); |
| 664 | + userRepository.save(user); |
| 665 | + |
| 666 | + Post post = new Post(user, "제목", "내용"); |
| 667 | + postRepository.save(post); |
| 668 | + |
| 669 | + Comment parent = new Comment(post, user, "부모 댓글", null); |
| 670 | + commentRepository.save(parent); |
| 671 | + |
| 672 | + String accessToken = generateAccessToken(user); |
| 673 | + CommentRequest request = new CommentRequest("대댓글 내용"); |
| 674 | + |
| 675 | + // when & then |
| 676 | + mvc.perform(post("/api/posts/{postId}/comments/{commentId}/replies", 999L, parent.getId()) |
| 677 | + .header("Authorization", "Bearer " + accessToken) |
| 678 | + .contentType(MediaType.APPLICATION_JSON) |
| 679 | + .content(objectMapper.writeValueAsString(request))) |
| 680 | + .andDo(print()) |
| 681 | + .andExpect(status().isNotFound()) |
| 682 | + .andExpect(jsonPath("$.code").value("POST_001")) |
| 683 | + .andExpect(jsonPath("$.message").value("존재하지 않는 게시글입니다.")); |
| 684 | + } |
| 685 | + |
| 686 | + @Test |
| 687 | + @DisplayName("대댓글 생성 실패 - 존재하지 않는 부모 댓글 → 404 Not Found") |
| 688 | + void createReply_commentNotFound() throws Exception { |
| 689 | + // given |
| 690 | + User user = User. createUser( "writer", "[email protected]", passwordEncoder. encode( "P@ssw0rd!")); |
| 691 | + user.setUserProfile(new UserProfile(user, "이몽룡", null, null, null, 0)); |
| 692 | + user.setUserStatus(UserStatus.ACTIVE); |
| 693 | + userRepository.save(user); |
| 694 | + |
| 695 | + Post post = new Post(user, "제목", "내용"); |
| 696 | + postRepository.save(post); |
| 697 | + |
| 698 | + String accessToken = generateAccessToken(user); |
| 699 | + CommentRequest request = new CommentRequest("대댓글 내용"); |
| 700 | + |
| 701 | + // when & then |
| 702 | + mvc.perform(post("/api/posts/{postId}/comments/{commentId}/replies", post.getId(), 999L) |
| 703 | + .header("Authorization", "Bearer " + accessToken) |
| 704 | + .contentType(MediaType.APPLICATION_JSON) |
| 705 | + .content(objectMapper.writeValueAsString(request))) |
| 706 | + .andDo(print()) |
| 707 | + .andExpect(status().isNotFound()) |
| 708 | + .andExpect(jsonPath("$.code").value("COMMENT_001")) |
| 709 | + .andExpect(jsonPath("$.message").value("존재하지 않는 댓글입니다.")); |
| 710 | + } |
| 711 | + |
| 712 | + @Test |
| 713 | + @DisplayName("대댓글 생성 실패 - 부모 댓글이 다른 게시글에 속함 → 400 Bad Request") |
| 714 | + void createReply_parentMismatch() throws Exception { |
| 715 | + // given |
| 716 | + User user = User. createUser( "writer", "[email protected]", passwordEncoder. encode( "P@ssw0rd!")); |
| 717 | + user.setUserProfile(new UserProfile(user, "이몽룡", null, null, null, 0)); |
| 718 | + user.setUserStatus(UserStatus.ACTIVE); |
| 719 | + userRepository.save(user); |
| 720 | + |
| 721 | + Post post1 = new Post(user, "게시글1", "내용1"); |
| 722 | + Post post2 = new Post(user, "게시글2", "내용2"); |
| 723 | + postRepository.saveAll(List.of(post1, post2)); |
| 724 | + |
| 725 | + Comment parent = new Comment(post1, user, "부모 댓글", null); |
| 726 | + commentRepository.save(parent); |
| 727 | + |
| 728 | + String accessToken = generateAccessToken(user); |
| 729 | + CommentRequest request = new CommentRequest("대댓글 내용"); |
| 730 | + |
| 731 | + // when & then |
| 732 | + mvc.perform(post("/api/posts/{postId}/comments/{commentId}/replies", post2.getId(), parent.getId()) |
| 733 | + .header("Authorization", "Bearer " + accessToken) |
| 734 | + .contentType(MediaType.APPLICATION_JSON) |
| 735 | + .content(objectMapper.writeValueAsString(request))) |
| 736 | + .andDo(print()) |
| 737 | + .andExpect(status().isBadRequest()) |
| 738 | + .andExpect(jsonPath("$.code").value("COMMENT_003")) |
| 739 | + .andExpect(jsonPath("$.message").value("부모 댓글이 해당 게시글에 속하지 않습니다.")); |
| 740 | + } |
| 741 | + |
| 742 | + @Test |
| 743 | + @DisplayName("대댓글 생성 실패 - depth 제한 초과(부모가 이미 대댓글) → 400 Bad Request") |
| 744 | + void createReply_depthExceeded() throws Exception { |
| 745 | + // given |
| 746 | + User user = User. createUser( "writer", "[email protected]", passwordEncoder. encode( "P@ssw0rd!")); |
| 747 | + user.setUserProfile(new UserProfile(user, "이몽룡", null, null, null, 0)); |
| 748 | + user.setUserStatus(UserStatus.ACTIVE); |
| 749 | + userRepository.save(user); |
| 750 | + |
| 751 | + Post post = new Post(user, "제목", "내용"); |
| 752 | + postRepository.save(post); |
| 753 | + |
| 754 | + Comment parent = new Comment(post, user, "부모 댓글", null); |
| 755 | + Comment child = new Comment(post, user, "대댓글1", parent); |
| 756 | + commentRepository.saveAll(List.of(parent, child)); |
| 757 | + |
| 758 | + String accessToken = generateAccessToken(user); |
| 759 | + CommentRequest request = new CommentRequest("대댓글2"); |
| 760 | + |
| 761 | + // when & then |
| 762 | + mvc.perform(post("/api/posts/{postId}/comments/{commentId}/replies", post.getId(), child.getId()) |
| 763 | + .header("Authorization", "Bearer " + accessToken) |
| 764 | + .contentType(MediaType.APPLICATION_JSON) |
| 765 | + .content(objectMapper.writeValueAsString(request))) |
| 766 | + .andDo(print()) |
| 767 | + .andExpect(status().isBadRequest()) |
| 768 | + .andExpect(jsonPath("$.code").value("COMMENT_004")) |
| 769 | + .andExpect(jsonPath("$.message").value("대댓글은 한 단계까지만 작성할 수 있습니다.")); |
| 770 | + } |
| 771 | + |
| 772 | + @Test |
| 773 | + @DisplayName("대댓글 생성 실패 - 필드 누락(content 없음) → 400 Bad Request") |
| 774 | + void createReply_badRequest() throws Exception { |
| 775 | + // given |
| 776 | + User user = User. createUser( "writer", "[email protected]", passwordEncoder. encode( "P@ssw0rd!")); |
| 777 | + user.setUserProfile(new UserProfile(user, "이몽룡", null, null, null, 0)); |
| 778 | + user.setUserStatus(UserStatus.ACTIVE); |
| 779 | + userRepository.save(user); |
| 780 | + |
| 781 | + Post post = new Post(user, "제목", "내용"); |
| 782 | + postRepository.save(post); |
| 783 | + |
| 784 | + Comment parent = new Comment(post, user, "부모 댓글", null); |
| 785 | + commentRepository.save(parent); |
| 786 | + |
| 787 | + String accessToken = generateAccessToken(user); |
| 788 | + |
| 789 | + String invalidJson = "{}"; |
| 790 | + |
| 791 | + // when & then |
| 792 | + mvc.perform(post("/api/posts/{postId}/comments/{commentId}/replies", post.getId(), parent.getId()) |
| 793 | + .header("Authorization", "Bearer " + accessToken) |
| 794 | + .contentType(MediaType.APPLICATION_JSON) |
| 795 | + .content(invalidJson)) |
| 796 | + .andDo(print()) |
| 797 | + .andExpect(status().isBadRequest()) |
| 798 | + .andExpect(jsonPath("$.code").value("COMMON_400")) |
| 799 | + .andExpect(jsonPath("$.message").value("잘못된 요청입니다.")); |
| 800 | + } |
| 801 | + |
| 802 | + @Test |
| 803 | + @DisplayName("대댓글 생성 실패 - 토큰 없음 → 401 Unauthorized") |
| 804 | + void createReply_noToken() throws Exception { |
| 805 | + // given |
| 806 | + User user = User. createUser( "writer", "[email protected]", passwordEncoder. encode( "P@ssw0rd!")); |
| 807 | + user.setUserProfile(new UserProfile(user, "이몽룡", null, null, null, 0)); |
| 808 | + user.setUserStatus(UserStatus.ACTIVE); |
| 809 | + userRepository.save(user); |
| 810 | + |
| 811 | + Post post = new Post(user, "제목", "내용"); |
| 812 | + postRepository.save(post); |
| 813 | + |
| 814 | + Comment parent = new Comment(post, user, "부모 댓글", null); |
| 815 | + commentRepository.save(parent); |
| 816 | + |
| 817 | + CommentRequest request = new CommentRequest("대댓글 내용"); |
| 818 | + |
| 819 | + // when & then |
| 820 | + mvc.perform(post("/api/posts/{postId}/comments/{commentId}/replies", post.getId(), parent.getId()) |
| 821 | + .contentType(MediaType.APPLICATION_JSON) |
| 822 | + .content(objectMapper.writeValueAsString(request))) |
| 823 | + .andDo(print()) |
| 824 | + .andExpect(status().isUnauthorized()) |
| 825 | + .andExpect(jsonPath("$.code").value("AUTH_001")) |
| 826 | + .andExpect(jsonPath("$.message").value("인증이 필요합니다.")); |
| 827 | + } |
584 | 828 | } |
0 commit comments