Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9b15a18
fix(community): CommunityComment 엔티티 및 Dto에 communityBoardId 추가
ayoung-dev Nov 29, 2024
cc82066
feat(community): CommunityBoardRepository에 existsById 추가 및 검증 테스트 추가
ayoung-dev Nov 29, 2024
0f63ec6
feat(community): CommunityComment 생성 시 게시글 검증 로직 추가
ayoung-dev Nov 29, 2024
b7b0d9d
test(community): CommunityComment 생성 시 게시글 검증 테스트 추가
ayoung-dev Nov 29, 2024
5af09e9
test(community): CommunityCommentRepositoryTest 수정
ayoung-dev Nov 29, 2024
3b6552f
test(community): 불필요한 import 및 변수 삭제
ayoung-dev Nov 29, 2024
ff886b7
Feature/75 관심기관 등록, 취소 기능 구현 (#85)
7zrv Nov 29, 2024
c339f4f
cicd: workflow 환경변수 추가 (#90)
7zrv Nov 30, 2024
4e00263
cicd: workflow 환경변수 추가 (#92)
7zrv Nov 30, 2024
c5ea384
feat: 스웨거 API 테스트를 위한 봉사자 / 기관 토큰 발급 (#91)
leebs0521 Nov 30, 2024
511c89d
hotfix: fix typo (#94)
leebs0521 Nov 30, 2024
5350e83
fix(community): CommunityComment 엔티티 및 Dto에 communityBoardId 추가
ayoung-dev Nov 29, 2024
aefe88e
feat(community): CommunityBoardRepository에 existsById 추가 및 검증 테스트 추가
ayoung-dev Nov 29, 2024
58b731e
feat(community): CommunityComment 생성 시 게시글 검증 로직 추가
ayoung-dev Nov 29, 2024
139c454
test(community): CommunityComment 생성 시 게시글 검증 테스트 추가
ayoung-dev Nov 29, 2024
1e53d65
test(community): CommunityCommentRepositoryTest 수정
ayoung-dev Nov 29, 2024
53576ef
test(community): 불필요한 import 및 변수 삭제
ayoung-dev Nov 29, 2024
1412311
refactor(community): 코드 리뷰 사항 반영
ayoung-dev Nov 30, 2024
7e4f4c4
Merge remote-tracking branch 'origin/bug/80-modify-community-comment-…
ayoung-dev Nov 30, 2024
6f73258
test(community): 변수명 변경
ayoung-dev Nov 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,27 @@
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;

@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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,9 @@ public interface CommunityBoardRepository {
Optional<CommunityBoard> findById(Long id);
List<CommunityBoardView> getCommunityBoards();
List<CommunityBoardView> findByWriterId(UUID writerId);
boolean existsById(Long id);
default boolean doesNotExistById(Long id) {
return !existsById(id);
}
Comment on lines +16 to +18
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 메서드가 필요할까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

서진님 코드에서 멋져 보여서 저도 따라해봤습니다 ㅎ

Copy link
Collaborator Author

@ayoung-dev ayoung-dev Nov 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 !를 쓰지 않으려고 만든다고 생각했습니다..!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 참고하겠습니다!

void deleteAllInBatch();
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ public List<CommunityBoardView> 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;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@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;
}
@Override
public boolean existsById(Long id) {
return communityBoardJpaRepository.existsByIdAndDeletedFalse(id);
}
  1. 위 코드로 변경하는 것이 어떤지 여쭤보고 싶습니다.
  2. dsl로 존재 체크하는 fetchExists도 deprecated 된건지도 여쭤보고 싶습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

existsByIdAndDeletedFalse가 너무 긴 거 같아서 querydsl로 했었는데 이렇게 보니 jpa로 하는게 훨씬 간결할 거 같네요! 수정하겠습니다.

찾아보니 fetchCount() 메서드가 deprecated 되어서 fetchFirst() 또는 limit(1)을 사용하여 존재 여부를 확인하는 방식이 권장되고 있다고 하네요!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다. 조건이 1개가 아니라서 찝찝하긴 한데, id and deleted는 괜찮지 않을까 싶어서 제안드렸습니다.


private JPAQuery<CommunityBoardView> getCommunityBoardsQuery() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 이번 변경사항은 아닌데 repo에 find로 맞추기로 하지 않았는지 여쭤보고 싶습니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안그래도 저도 다시 수정하면서 거슬렸는데
board의 controller 만들면서 같이 수정하려고 놔뒀습니다!
그떄 같이 수정할게욤

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 !

QCommunityBoard communityBoard = QCommunityBoard.communityBoard;
QVolunteer volunteer = QVolunteer.volunteer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -11,24 +12,34 @@

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
@Transactional
@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());
}
}
Comment on lines +39 to +43
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이전에는 early return 으로 해결하시지 않으셨는지, 변경하게 된 의도도 여쭤보고 싶습니다!

Copy link
Collaborator Author

@ayoung-dev ayoung-dev Nov 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 지난번에는 validator가 아니고 리턴 값이 있었는데
이번에는 void라 validate 부분은 이렇게 하게 되었습니다!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다. 이해했습니다. 저는 반환값이 없는 return을 적어두는 편이라서 여쭤보고 싶었습니다 ㅎㅎ


private void validateParentCommentExists(Long parentCommentId) {
if (parentCommentId != null && !communityCommentRepository.existsById(parentCommentId)) {
throw new BadRequestException(NOT_EXISTS_COMMUNITY_COMMENT.getMessage());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 다시 보는데 조건 가독성이 아쉬운 것 같아요. 정확한 의도를 여쭤보고 싶습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    if (requestDto.parentCommentId() != null) {
        validateParentCommentExists(communityComment.getParentCommentId());
    }

private void validateParentCommentExists(Long parentCommentId) {
    if (communityCommentRepository.doesNotExistById(parentCommentId)) {
        throw new BadRequestException(NOT_EXISTS_COMMUNITY_COMMENT.getMessage());
    }
}

이게 더 가독성 별로 인가요..
부모 아이디 값이 있을 경우 그 값을 검증하는 의도입니다

더 좋은 방법이 생각나시면 알려주세용

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하 존재를 검증한다는 의도로 느껴지는 메서드 네이밍이라서 헷갈렸던 것 같아요

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.somemore.community.repository;

import com.somemore.IntegrationTestSupport;
import com.somemore.community.domain.CommunityBoard;
import com.somemore.community.domain.CommunityComment;
import com.somemore.community.repository.board.CommunityBoardRepository;
import com.somemore.community.repository.comment.CommunityCommentRepository;
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;
Expand All @@ -17,6 +20,24 @@
class CommunityCommentRepositoryTest extends IntegrationTestSupport {
@Autowired
CommunityCommentRepository communityCommentRepository;
@Autowired
CommunityBoardRepository communityBoardRepository;

private Long boardId;

@BeforeEach
void setUp() {
CommunityBoard communityBoard = CommunityBoard.builder()
.title("테스트 커뮤니티 게시글 제목")
.content("테스트 커뮤니티 게시글 내용")
.imgUrl("http://community.example.com/123")
.writerId(UUID.randomUUID())
.build();

communityBoardRepository.save(communityBoard);

boardId = communityBoard.getId();
}

@DisplayName("커뮤니티 게시글에 댓글을 생성할 수 있다. (Repository)")
@Test
Expand All @@ -26,6 +47,7 @@ void createCommunityComment() {
UUID writerId = UUID.randomUUID();

CommunityComment communityComment = CommunityComment.builder()
.communityBoardId(boardId)
.writerId(writerId)
.content("커뮤니티 댓글 테스트 내용")
.parentCommentId(null)
Expand All @@ -48,6 +70,7 @@ void createCommunityCommentReply() {
UUID writerId = UUID.randomUUID();

CommunityComment communityComment = CommunityComment.builder()
.communityBoardId(boardId)
.writerId(writerId)
.content("커뮤니티 댓글 테스트 내용")
.parentCommentId(1L)
Expand All @@ -70,6 +93,7 @@ void findCommunityCommentById() {
UUID writerId = UUID.randomUUID();

CommunityComment communityComment = CommunityComment.builder()
.communityBoardId(boardId)
.writerId(writerId)
.content("커뮤니티 댓글 테스트 내용")
.parentCommentId(null)
Expand All @@ -95,6 +119,7 @@ void existsById() {
UUID writerId = UUID.randomUUID();

CommunityComment communityComment = CommunityComment.builder()
.communityBoardId(boardId)
.writerId(writerId)
.content("커뮤니티 댓글 테스트 내용")
.parentCommentId(null)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 빌더 부분이 중복되는 것이 보이는데 추출해내면 좋을 것 같습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다!

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -24,6 +28,25 @@ class CreateCommunityCommentServiceTest extends IntegrationTestSupport {
private CreateCommunityCommentService createCommunityCommentService;
@Autowired
private CommunityCommentRepository communityCommentRepository;
@Autowired
private CreateCommunityBoardUseCase createCommunityBoardUseCase;
@Autowired
private DeleteCommunityBoardUseCase deleteCommunityBoardUseCase;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CommunityRepository 주입받아서도 가능할 것 같은데 맞나요..?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 repository로 하는게 나을까요?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트 하려는 서비스만 주입받고 나머지는 레포지토리가 좋아보입니다.!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다!
컨트롤러 구현할 때 board 쪽도 이렇게 수정하겠습니다!

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() {
Expand All @@ -36,12 +59,11 @@ void createCommunityCommentWithDto() {

//given
CommunityCommentCreateRequestDto dto = CommunityCommentCreateRequestDto.builder()
.communityBoardId(boardId)
.content("커뮤니티 댓글 테스트 내용")
.parentCommentId(null)
.build();

UUID writerId = UUID.randomUUID();

//when
Long commentId = createCommunityCommentService.createCommunityComment(dto, writerId);

Expand All @@ -61,14 +83,15 @@ void createCommunityCommentRelyWithDto() {

//given
CommunityCommentCreateRequestDto commentDto = CommunityCommentCreateRequestDto.builder()
.communityBoardId(boardId)
.content("커뮤니티 댓글 테스트 내용")
.parentCommentId(null)
.build();

UUID writerId = UUID.randomUUID();
Long commentId = createCommunityCommentService.createCommunityComment(commentDto, writerId);

CommunityCommentCreateRequestDto replyDto = CommunityCommentCreateRequestDto.builder()
.communityBoardId(boardId)
.content("커뮤니티 대댓글 테스트 내용")
.parentCommentId(commentId)
.build();
Expand All @@ -86,12 +109,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();
Expand All @@ -104,4 +128,26 @@ void createCommunityCommentReplyWithDeletedParentId() {
.isThrownBy(callable)
.withMessage(ExceptionMessage.NOT_EXISTS_COMMUNITY_COMMENT.getMessage());
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 static import 하면 좋을 것 같습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다~


@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());
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static import 하면 좋을 것 같아요.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵! 수정했습니다

}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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();
Expand Down