diff --git a/src/main/java/com/somemore/community/domain/CommunityComment.java b/src/main/java/com/somemore/community/domain/CommunityComment.java index 42acddc2d..36cb2c792 100644 --- a/src/main/java/com/somemore/community/domain/CommunityComment.java +++ b/src/main/java/com/somemore/community/domain/CommunityComment.java @@ -22,6 +22,9 @@ public class CommunityComment extends BaseEntity { @Column(name = "id", nullable = false) private Long id; + @Column(name = "community_board_id", nullable = false) + private Long communityBoardId; + @Column(name = "writer_id", nullable = false, length = 16) private UUID writerId; @@ -33,7 +36,8 @@ public class CommunityComment extends BaseEntity { private Long parentCommentId; @Builder - public CommunityComment(UUID writerId, String content, Long parentCommentId) { + public CommunityComment(Long communityBoardId, UUID writerId, String content, Long parentCommentId) { + this.communityBoardId = communityBoardId; this.writerId = writerId; this.content = content; this.parentCommentId = parentCommentId; diff --git a/src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java b/src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java index 4366779a0..2c6a5b104 100644 --- a/src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java +++ b/src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java @@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Builder; import java.util.UUID; @@ -13,15 +14,19 @@ @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) @Builder public record CommunityCommentCreateRequestDto( + @Schema(description = "커뮤니티 게시글 ID", example = "33") + @NotNull(message = "게시글 ID는 필수 값입니다.") + Long communityBoardId, @Schema(description = "커뮤니티 댓글 내용", example = "저도 함께 하고 싶습니다.") @NotBlank(message = "댓글 내용은 필수 값입니다.") String content, - @Schema(description = "부모 댓글의 ID", example = "1234", nullable = true) + @Schema(description = "부모 댓글 ID", example = "1234", nullable = true) @Nullable Long parentCommentId ) { public CommunityComment toEntity(UUID writerId) { return CommunityComment.builder() + .communityBoardId(communityBoardId) .writerId(writerId) .content(content) .parentCommentId(parentCommentId) diff --git a/src/main/java/com/somemore/community/repository/board/CommunityBoardRepository.java b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepository.java index 3340735a5..44b34f517 100644 --- a/src/main/java/com/somemore/community/repository/board/CommunityBoardRepository.java +++ b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepository.java @@ -12,5 +12,9 @@ public interface CommunityBoardRepository { Optional findById(Long id); List getCommunityBoards(); List findByWriterId(UUID writerId); + boolean existsById(Long id); + default boolean doesNotExistById(Long id) { + return !existsById(id); + } void deleteAllInBatch(); } diff --git a/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java index ad1d79924..cf3d2f080 100644 --- a/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java +++ b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java @@ -52,6 +52,18 @@ public List findByWriterId(UUID writerId) { .fetch(); } + @Override + public boolean existsById(Long id) { + QCommunityBoard communityBoard = QCommunityBoard.communityBoard; + + return queryFactory + .selectOne() + .from(communityBoard) + .where(communityBoard.id.eq(id) + .and(communityBoard.deleted.eq(false))) + .fetchFirst() != null; + } + private JPAQuery getCommunityBoardsQuery() { QCommunityBoard communityBoard = QCommunityBoard.communityBoard; QVolunteer volunteer = QVolunteer.volunteer; diff --git a/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java b/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java index e6da18066..0eaa711be 100644 --- a/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java +++ b/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java @@ -2,6 +2,7 @@ import com.somemore.community.domain.CommunityComment; import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; +import com.somemore.community.repository.board.CommunityBoardRepository; import com.somemore.community.repository.comment.CommunityCommentRepository; import com.somemore.community.usecase.comment.CreateCommunityCommentUseCase; import com.somemore.global.exception.BadRequestException; @@ -11,6 +12,7 @@ import java.util.UUID; +import static com.somemore.global.exception.ExceptionMessage.NOT_EXISTS_COMMUNITY_BOARD; import static com.somemore.global.exception.ExceptionMessage.NOT_EXISTS_COMMUNITY_COMMENT; @RequiredArgsConstructor @@ -18,17 +20,26 @@ @Service public class CreateCommunityCommentService implements CreateCommunityCommentUseCase { + private final CommunityBoardRepository communityBoardRepository; private final CommunityCommentRepository communityCommentRepository; @Override public Long createCommunityComment(CommunityCommentCreateRequestDto requestDto, UUID writerId) { CommunityComment communityComment = requestDto.toEntity(writerId); + validateCommunityBoardExists(communityComment.getCommunityBoardId()); + validateParentCommentExists(communityComment.getParentCommentId()); return communityCommentRepository.save(communityComment).getId(); } + private void validateCommunityBoardExists(Long communityBoardId) { + if (communityBoardRepository.doesNotExistById(communityBoardId)) { + throw new BadRequestException(NOT_EXISTS_COMMUNITY_BOARD.getMessage()); + } + } + private void validateParentCommentExists(Long parentCommentId) { if (parentCommentId != null && !communityCommentRepository.existsById(parentCommentId)) { throw new BadRequestException(NOT_EXISTS_COMMUNITY_COMMENT.getMessage()); diff --git a/src/test/java/com/somemore/community/repository/CommunityBoardRepositoryTest.java b/src/test/java/com/somemore/community/repository/CommunityBoardRepositoryTest.java index 2f6fdbd52..acb29075f 100644 --- a/src/test/java/com/somemore/community/repository/CommunityBoardRepositoryTest.java +++ b/src/test/java/com/somemore/community/repository/CommunityBoardRepositoryTest.java @@ -158,4 +158,27 @@ void getCommunityBoardsByWriterId() { assertThat(communityBoards.getLast().writerNickname()).isEqualTo(volunteer.getNickname()); assertThat(communityBoards.getLast().communityBoard().getCreatedAt()).isEqualTo(communityBoard1.getCreatedAt()); } + + @DisplayName("게시글 id로 게시글이 존재하는지 확인할 수 있다.") + @Test + void existsById() { + + //given + UUID writerId = UUID.randomUUID(); + + CommunityBoard communityBoard = CommunityBoard.builder() + .title("테스트 커뮤니티 게시글 제목") + .content("테스트 커뮤니티 게시글 내용") + .imgUrl("http://community.example.com/123") + .writerId(writerId) + .build(); + + CommunityBoard savedComment = communityBoardRepository.save(communityBoard); + + //when + boolean isExist = communityBoardRepository.existsById(savedComment.getId()); + + //then + assertThat(isExist).isTrue(); + } } diff --git a/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java b/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java index bc955770c..4b981f62f 100644 --- a/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java +++ b/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java @@ -2,12 +2,16 @@ import com.somemore.IntegrationTestSupport; import com.somemore.community.domain.CommunityComment; +import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; import com.somemore.community.repository.comment.CommunityCommentRepository; +import com.somemore.community.usecase.board.CreateCommunityBoardUseCase; +import com.somemore.community.usecase.board.DeleteCommunityBoardUseCase; import com.somemore.global.exception.BadRequestException; import com.somemore.global.exception.ExceptionMessage; import org.assertj.core.api.ThrowableAssert; import org.junit.jupiter.api.AfterEach; +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; @@ -24,6 +28,25 @@ class CreateCommunityCommentServiceTest extends IntegrationTestSupport { private CreateCommunityCommentService createCommunityCommentService; @Autowired private CommunityCommentRepository communityCommentRepository; + @Autowired + private CreateCommunityBoardUseCase createCommunityBoardUseCase; + @Autowired + private DeleteCommunityBoardUseCase deleteCommunityBoardUseCase; + + private UUID writerId; + private Long boardId; + + @BeforeEach + void setUp() { + CommunityBoardCreateRequestDto boardDto = CommunityBoardCreateRequestDto.builder() + .title("커뮤니티 테스트 제목") + .content("커뮤니티 테스트 내용") + .build(); + + writerId = UUID.randomUUID(); + + boardId = createCommunityBoardUseCase.createCommunityBoard(boardDto, writerId, null); + } @AfterEach void tearDown() { @@ -36,6 +59,7 @@ void createCommunityCommentWithDto() { //given CommunityCommentCreateRequestDto dto = CommunityCommentCreateRequestDto.builder() + .communityBoardId(boardId) .content("커뮤니티 댓글 테스트 내용") .parentCommentId(null) .build(); @@ -61,6 +85,7 @@ void createCommunityCommentRelyWithDto() { //given CommunityCommentCreateRequestDto commentDto = CommunityCommentCreateRequestDto.builder() + .communityBoardId(boardId) .content("커뮤니티 댓글 테스트 내용") .parentCommentId(null) .build(); @@ -69,6 +94,7 @@ void createCommunityCommentRelyWithDto() { Long commentId = createCommunityCommentService.createCommunityComment(commentDto, writerId); CommunityCommentCreateRequestDto replyDto = CommunityCommentCreateRequestDto.builder() + .communityBoardId(boardId) .content("커뮤니티 대댓글 테스트 내용") .parentCommentId(commentId) .build(); @@ -86,12 +112,13 @@ void createCommunityCommentRelyWithDto() { assertThat(communityCommentReply.get().getParentCommentId()).isEqualTo(commentId); } - @DisplayName("삭제된 댓글에 대댓글을 등록할 때 예외를 던진다.") + @DisplayName("삭제된 댓글이나 존재하지 않는 댓글에 대댓글을 등록할 때 예외를 던진다.") @Test void createCommunityCommentReplyWithDeletedParentId() { //given CommunityCommentCreateRequestDto replyDto = CommunityCommentCreateRequestDto.builder() + .communityBoardId(boardId) .content("커뮤니티 대댓글 테스트 내용") .parentCommentId(2L) .build(); @@ -104,4 +131,26 @@ void createCommunityCommentReplyWithDeletedParentId() { .isThrownBy(callable) .withMessage(ExceptionMessage.NOT_EXISTS_COMMUNITY_COMMENT.getMessage()); } + + @DisplayName("삭제된 게시글에 댓글을 등록할 때 예외를 던진다.") + @Test + void createCommunityCommentWithDeletedBoardId() { + + //given + CommunityCommentCreateRequestDto commentDto = CommunityCommentCreateRequestDto.builder() + .communityBoardId(boardId) + .content("커뮤니티 댓글 테스트 내용") + .parentCommentId(null) + .build(); + + deleteCommunityBoardUseCase.deleteCommunityBoard(writerId, boardId); + + //when + ThrowableAssert.ThrowingCallable callable = () -> createCommunityCommentService.createCommunityComment(commentDto, UUID.randomUUID()); + + //then + assertThatExceptionOfType(BadRequestException.class) + .isThrownBy(callable) + .withMessage(ExceptionMessage.NOT_EXISTS_COMMUNITY_BOARD.getMessage()); + } } diff --git a/src/test/java/com/somemore/community/service/comment/DeleteCommunityCommentServiceTest.java b/src/test/java/com/somemore/community/service/comment/DeleteCommunityCommentServiceTest.java index 0b5df5d2c..32e9559e2 100644 --- a/src/test/java/com/somemore/community/service/comment/DeleteCommunityCommentServiceTest.java +++ b/src/test/java/com/somemore/community/service/comment/DeleteCommunityCommentServiceTest.java @@ -1,8 +1,10 @@ package com.somemore.community.service.comment; import com.somemore.IntegrationTestSupport; +import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; import com.somemore.community.repository.comment.CommunityCommentRepository; +import com.somemore.community.usecase.board.CreateCommunityBoardUseCase; import com.somemore.community.usecase.comment.CreateCommunityCommentUseCase; import com.somemore.global.exception.BadRequestException; import com.somemore.global.exception.ExceptionMessage; @@ -26,13 +28,25 @@ class DeleteCommunityCommentServiceTest extends IntegrationTestSupport { private CreateCommunityCommentUseCase createCommunityCommentUseCase; @Autowired private CommunityCommentRepository communityCommentRepository; + @Autowired + private CreateCommunityBoardUseCase createCommunityBoardUseCase; private UUID writerId; private Long commentId; @BeforeEach void setUp() { + CommunityBoardCreateRequestDto boardDto = CommunityBoardCreateRequestDto.builder() + .title("커뮤니티 테스트 제목") + .content("커뮤니티 테스트 내용") + .build(); + + writerId = UUID.randomUUID(); + + Long boardId = createCommunityBoardUseCase.createCommunityBoard(boardDto, writerId, null); + CommunityCommentCreateRequestDto dto = CommunityCommentCreateRequestDto.builder() + .communityBoardId(boardId) .content("커뮤니티 댓글 테스트 내용") .parentCommentId(null) .build();