From 6094c713367c7089b905ab86e6ca96578b3b0c45 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 11:25:45 +0900 Subject: [PATCH 01/25] =?UTF-8?q?test(community):=20communityComment=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommunityCommentRepositoryTest.java | 62 +++++++++++++++ .../CreateCommunityCommentServiceTest.java | 76 +++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java create mode 100644 src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java diff --git a/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java b/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java new file mode 100644 index 000000000..21142d6b2 --- /dev/null +++ b/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java @@ -0,0 +1,62 @@ +package com.somemore.community.repository; + +import com.somemore.IntegrationTestSupport; +import com.somemore.community.domain.CommunityComment; +import com.somemore.community.repository.comment.CommunityCommentRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +@Transactional +public class CommunityCommentRepositoryTest extends IntegrationTestSupport { + @Autowired + CommunityCommentRepository communityCommentRepository; + + @DisplayName("커뮤니티 게시글에 댓글을 생성할 수 있다. (Repository)") + @Test + void createCommunityComment() { + + //given + UUID writerId = UUID.randomUUID(); + + CommunityComment communityComment = CommunityComment.builder() + .writerId(writerId) + .content("커뮤니티 댓글 테스트 내용") + .parentCommentId(null) + .build(); + + //when + CommunityComment savedComment = communityCommentRepository.save(communityComment); + + //then + assertThat(savedComment.getWriterId()).isEqualTo(writerId); + assertThat(savedComment.getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); + assertThat(savedComment.getParentCommentId()).isNull(); + } + + @DisplayName("커뮤니티 게시글에 대댓글을 생성할 수 있다. (Repository)") + @Test + void createCommunityCommentReply() { + + //given + UUID writerId = UUID.randomUUID(); + + CommunityComment communityComment = CommunityComment.builder() + .writerId(writerId) + .content("커뮤니티 댓글 테스트 내용") + .parentCommentId(1L) + .build(); + + //when + CommunityComment savedComment = communityCommentRepository.save(communityComment); + + //then + assertThat(savedComment.getWriterId()).isEqualTo(writerId); + assertThat(savedComment.getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); + assertThat(savedComment.getParentCommentId()).isEqualTo(1L); + } +} diff --git a/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java b/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java new file mode 100644 index 000000000..2aab170de --- /dev/null +++ b/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java @@ -0,0 +1,76 @@ +package com.somemore.community.service.comment; + +import com.somemore.IntegrationTestSupport; +import com.somemore.community.domain.CommunityComment; +import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; +import com.somemore.community.repository.comment.CommunityCommentRepository; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Optional; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CreateCommunityCommentServiceTest extends IntegrationTestSupport { + + @Autowired + private CreateCommunityCommentService createCommunityCommentService; + @Autowired + private CommunityCommentRepository communityCommentRepository; + + @AfterEach + void tearDown() { + communityCommentRepository.deleteAllInBatch(); + } + + @DisplayName("커뮤니티 게시글에 댓글을 등록한다.") + @Test + void createCommunityCommentWithDto() { + + //given + CommunityCommentCreateRequestDto dto = CommunityCommentCreateRequestDto.builder() + .content("커뮤니티 댓글 테스트 내용") + .build(); + + UUID writerId = UUID.randomUUID(); + + //when + Long commentId = createCommunityCommentService.CreateCommunityComment(dto, writerId, null); + + //then + Optional communityComment = communityCommentRepository.findById(commentId); + + assertThat(communityComment).isPresent(); + assertThat(communityComment.get().getId()).isEqualTo(commentId); + assertThat(communityComment.get().getWriterId()).isEqualTo(writerId); + assertThat(communityComment.get().getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); + assertThat(communityComment.get().getParentCommentId()).isNull(); + } + + @DisplayName("커뮤니티 게시글에 대댓글을 등록한다.") + @Test + void createCommunityCommenReplytWithDto() { + + //given + CommunityCommentCreateRequestDto dto = CommunityCommentCreateRequestDto.builder() + .content("커뮤니티 댓글 테스트 내용") + .build(); + + UUID writerId = UUID.randomUUID(); + + //when + Long commentId = createCommunityCommentService.CreateCommunityComment(dto, writerId, 2L); + + //then + Optional communityComment = communityCommentRepository.findById(commentId); + + assertThat(communityComment).isPresent(); + assertThat(communityComment.get().getId()).isEqualTo(commentId); + assertThat(communityComment.get().getWriterId()).isEqualTo(writerId); + assertThat(communityComment.get().getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); + assertThat(communityComment.get().getParentCommentId()).isEqualTo(2L); + } +} From 4b666aa19434449492506b7d71b750a577dd3d5f Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 11:28:03 +0900 Subject: [PATCH 02/25] =?UTF-8?q?feat(community):=20communityComment=20Ent?= =?UTF-8?q?ity,=20Repository=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../community/domain/CommunityComment.java | 41 +++++++++++++++++++ .../CommunityCommentJpaRepository.java | 7 ++++ .../comment/CommunityCommentRepository.java | 11 +++++ .../CommunityCommentRepositoryImpl.java | 37 +++++++++++++++++ .../somemore/domains/CommunityComment.java | 28 ------------- 5 files changed, 96 insertions(+), 28 deletions(-) create mode 100644 src/main/java/com/somemore/community/domain/CommunityComment.java create mode 100644 src/main/java/com/somemore/community/repository/comment/CommunityCommentJpaRepository.java create mode 100644 src/main/java/com/somemore/community/repository/comment/CommunityCommentRepository.java create mode 100644 src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java delete mode 100644 src/main/java/com/somemore/domains/CommunityComment.java diff --git a/src/main/java/com/somemore/community/domain/CommunityComment.java b/src/main/java/com/somemore/community/domain/CommunityComment.java new file mode 100644 index 000000000..a55f8cdb8 --- /dev/null +++ b/src/main/java/com/somemore/community/domain/CommunityComment.java @@ -0,0 +1,41 @@ +package com.somemore.community.domain; + +import com.somemore.global.common.BaseEntity; +import jakarta.persistence.*; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +import static lombok.AccessLevel.PROTECTED; + + +@Getter +@NoArgsConstructor(access = PROTECTED) +@Entity +@Table(name = "Community_comment") +public class CommunityComment extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", nullable = false) + private Long id; + + @Column(name = "writer_id", nullable = false, length = 16) + private UUID writerId; + + @Lob + @Column(name = "content", nullable = false) + private String content; + + @Column(name = "parent_comment_id") + private Long parentCommentId; + + @Builder + public CommunityComment(UUID writerId, String content, Long parentCommentId) { + this.writerId = writerId; + this.content = content; + this.parentCommentId = parentCommentId; + } +} \ No newline at end of file diff --git a/src/main/java/com/somemore/community/repository/comment/CommunityCommentJpaRepository.java b/src/main/java/com/somemore/community/repository/comment/CommunityCommentJpaRepository.java new file mode 100644 index 000000000..fd02cad53 --- /dev/null +++ b/src/main/java/com/somemore/community/repository/comment/CommunityCommentJpaRepository.java @@ -0,0 +1,7 @@ +package com.somemore.community.repository.comment; + +import com.somemore.community.domain.CommunityComment; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CommunityCommentJpaRepository extends JpaRepository { +} diff --git a/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepository.java b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepository.java new file mode 100644 index 000000000..f38f5af58 --- /dev/null +++ b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepository.java @@ -0,0 +1,11 @@ +package com.somemore.community.repository.comment; + +import com.somemore.community.domain.CommunityComment; + +import java.util.Optional; + +public interface CommunityCommentRepository { + CommunityComment save(CommunityComment communityComment); + Optional findById(Long id); + void deleteAllInBatch(); +} diff --git a/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java new file mode 100644 index 000000000..12da16d85 --- /dev/null +++ b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java @@ -0,0 +1,37 @@ +package com.somemore.community.repository.comment; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import com.somemore.community.domain.CommunityComment; +import com.somemore.community.domain.QCommunityBoard; +import com.somemore.community.domain.QCommunityComment; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@RequiredArgsConstructor +@Repository +public class CommunityCommentRepositoryImpl implements CommunityCommentRepository { + + private final JPAQueryFactory queryFactory; + private final CommunityCommentJpaRepository communityCommentJpaRepository; + + @Override + public CommunityComment save(CommunityComment communityComment) { + return communityCommentJpaRepository.save(communityComment); + } + + @Override + public Optional findById(Long id) { + QCommunityComment communityComment = QCommunityComment.communityComment; + + return Optional.ofNullable(queryFactory + .selectFrom(communityComment) + .where(communityComment.id.eq(id) + .and(communityComment.deleted.eq(false))) + .fetchOne()); + } + + @Override + public void deleteAllInBatch() { communityCommentJpaRepository.deleteAllInBatch(); } +} diff --git a/src/main/java/com/somemore/domains/CommunityComment.java b/src/main/java/com/somemore/domains/CommunityComment.java deleted file mode 100644 index 423975fbd..000000000 --- a/src/main/java/com/somemore/domains/CommunityComment.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.somemore.domains; - -import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; - -import java.util.UUID; - -@Getter -@Setter -@Entity -@Table(name = "Community_comment") -public class CommunityComment { - @Id - @GeneratedValue(strategy = GenerationType.UUID) - private UUID id; - - @Column(name = "writer_id", nullable = false, length = 16) - private String writerId; - - @Lob - @Column(name = "content", nullable = false) - private String content; - - @Column(name = "parent_comment_id") - private Long parentCommentId; - -} \ No newline at end of file From e087c0c845e652e0158134a990105b29a221926b Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 11:29:06 +0900 Subject: [PATCH 03/25] =?UTF-8?q?feat(community):=20communityComment=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20RequestDto,=20Usecase=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20=EB=B0=8F=20Service=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommunityCommentCreateRequestDto.java | 26 +++++++++++++++++ .../CreateCommunityCommentService.java | 29 +++++++++++++++++++ .../CreateCommunityCommentUseCase.java | 13 +++++++++ 3 files changed, 68 insertions(+) create mode 100644 src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java create mode 100644 src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java create mode 100644 src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java diff --git a/src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java b/src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java new file mode 100644 index 000000000..b15202fd4 --- /dev/null +++ b/src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java @@ -0,0 +1,26 @@ +package com.somemore.community.dto.request; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.somemore.community.domain.CommunityComment; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Builder; + +import java.util.UUID; + +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +@Builder +public record CommunityCommentCreateRequestDto( + @Schema(description = "커뮤니티 댓글 내용", example = "저도 함께 하고 싶습니다.") + @NotBlank(message = "댓글 내용은 필수 값입니다.") + String content +) { + public CommunityComment toEntity(UUID writerId, Long parentCommentId) { + return CommunityComment.builder() + .writerId(writerId) + .content(content) + .parentCommentId(parentCommentId) + .build(); + } +} diff --git a/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java b/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java new file mode 100644 index 000000000..95ea80e9a --- /dev/null +++ b/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java @@ -0,0 +1,29 @@ +package com.somemore.community.service.comment; + +import com.somemore.community.domain.CommunityComment; +import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; +import com.somemore.community.repository.comment.CommunityCommentRepository; +import com.somemore.community.usecase.comment.CreateCommunityCommentUseCase; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.UUID; + +@RequiredArgsConstructor +@Transactional +@Service +public class CreateCommunityCommentService implements CreateCommunityCommentUseCase { + + private final CommunityCommentRepository communityCommentRepository; + + @Override + public Long CreateCommunityComment(CommunityCommentCreateRequestDto requestDto, UUID writerId, Long parentCommunityId) { + + CommunityComment communityComment = requestDto.toEntity(writerId, parentCommunityId); + + communityCommentRepository.save(communityComment); + + return communityComment.getId(); + } +} diff --git a/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java b/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java new file mode 100644 index 000000000..5c6224877 --- /dev/null +++ b/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java @@ -0,0 +1,13 @@ +package com.somemore.community.usecase.comment; + +import com.somemore.community.domain.CommunityComment; +import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; + +import java.util.UUID; + +public interface CreateCommunityCommentUseCase { + Long CreateCommunityComment( + CommunityCommentCreateRequestDto requestDto, + UUID writerId, + Long parentCommunityId); +} From 9a4c087d6668f0c2db350864a94df86f959118f7 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 11:30:20 +0900 Subject: [PATCH 04/25] =?UTF-8?q?refactor(community):=20CommunityBoardRepo?= =?UTF-8?q?sitory=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommunityBoardRepositoryImpl.java} | 4 ++-- ...yRepositoryTest.java => CommunityBoardRepositoryTest.java} | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) rename src/main/java/com/somemore/community/repository/{CommunityRepositoryImpl.java => board/CommunityBoardRepositoryImpl.java} (94%) rename src/test/java/com/somemore/community/repository/{CommunityRepositoryTest.java => CommunityBoardRepositoryTest.java} (98%) diff --git a/src/main/java/com/somemore/community/repository/CommunityRepositoryImpl.java b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java similarity index 94% rename from src/main/java/com/somemore/community/repository/CommunityRepositoryImpl.java rename to src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java index 26ec5360e..ad1d79924 100644 --- a/src/main/java/com/somemore/community/repository/CommunityRepositoryImpl.java +++ b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java @@ -1,4 +1,4 @@ -package com.somemore.community.repository; +package com.somemore.community.repository.board; import com.querydsl.core.types.Projections; import com.querydsl.jpa.impl.JPAQuery; @@ -16,7 +16,7 @@ @RequiredArgsConstructor @Repository -public class CommunityRepositoryImpl implements CommunityBoardRepository { +public class CommunityBoardRepositoryImpl implements CommunityBoardRepository { private final JPAQueryFactory queryFactory; private final CommunityBoardJpaRepository communityBoardJpaRepository; diff --git a/src/test/java/com/somemore/community/repository/CommunityRepositoryTest.java b/src/test/java/com/somemore/community/repository/CommunityBoardRepositoryTest.java similarity index 98% rename from src/test/java/com/somemore/community/repository/CommunityRepositoryTest.java rename to src/test/java/com/somemore/community/repository/CommunityBoardRepositoryTest.java index f39083074..2f6fdbd52 100644 --- a/src/test/java/com/somemore/community/repository/CommunityRepositoryTest.java +++ b/src/test/java/com/somemore/community/repository/CommunityBoardRepositoryTest.java @@ -4,6 +4,7 @@ import com.somemore.auth.oauth.OAuthProvider; import com.somemore.community.domain.CommunityBoard; import com.somemore.community.domain.CommunityBoardView; +import com.somemore.community.repository.board.CommunityBoardRepository; import com.somemore.volunteer.domain.Volunteer; import com.somemore.volunteer.repository.VolunteerRepository; import org.junit.jupiter.api.DisplayName; @@ -18,7 +19,7 @@ import static org.assertj.core.api.Assertions.assertThat; @Transactional -class CommunityRepositoryTest extends IntegrationTestSupport { +class CommunityBoardRepositoryTest extends IntegrationTestSupport { @Autowired private CommunityBoardRepository communityBoardRepository; From 58038ee6135497bd1c3a5e354b441f4e847099f3 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 11:30:41 +0900 Subject: [PATCH 05/25] =?UTF-8?q?refactor(community):=20community=20board/?= =?UTF-8?q?comment=20=ED=8F=B4=EB=8D=94=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{ => board}/CommunityBoardJpaRepository.java | 2 +- .../repository/{ => board}/CommunityBoardRepository.java | 2 +- .../service/{ => board}/CommunityBoardQueryService.java | 6 +++--- .../service/{ => board}/CreateCommunityBoardService.java | 6 +++--- .../service/{ => board}/DeleteCommunityBoardService.java | 6 +++--- .../service/{ => board}/UpdateCommunityBoardService.java | 6 +++--- .../usecase/{ => board}/CommunityBoardQueryUseCase.java | 2 +- .../usecase/{ => board}/CreateCommunityBoardUseCase.java | 2 +- .../usecase/{ => board}/DeleteCommunityBoardUseCase.java | 2 +- .../usecase/{ => board}/UpdateCommunityBoardUseCase.java | 2 +- .../{ => board}/CommunityBoardQueryServiceTest.java | 8 ++++---- .../{ => board}/CreateCommunityBoardServiceTest.java | 4 ++-- .../{ => board}/DeleteCommunityBoardServiceTest.java | 8 ++++---- .../{ => board}/UpdateCommunityBoardServiceTest.java | 6 +++--- 14 files changed, 31 insertions(+), 31 deletions(-) rename src/main/java/com/somemore/community/repository/{ => board}/CommunityBoardJpaRepository.java (81%) rename src/main/java/com/somemore/community/repository/{ => board}/CommunityBoardRepository.java (90%) rename src/main/java/com/somemore/community/service/{ => board}/CommunityBoardQueryService.java (91%) rename src/main/java/com/somemore/community/service/{ => board}/CreateCommunityBoardService.java (81%) rename src/main/java/com/somemore/community/service/{ => board}/DeleteCommunityBoardService.java (88%) rename src/main/java/com/somemore/community/service/{ => board}/UpdateCommunityBoardService.java (88%) rename src/main/java/com/somemore/community/usecase/{ => board}/CommunityBoardQueryUseCase.java (91%) rename src/main/java/com/somemore/community/usecase/{ => board}/CreateCommunityBoardUseCase.java (85%) rename src/main/java/com/somemore/community/usecase/{ => board}/DeleteCommunityBoardUseCase.java (73%) rename src/main/java/com/somemore/community/usecase/{ => board}/UpdateCommunityBoardUseCase.java (87%) rename src/test/java/com/somemore/community/service/{ => board}/CommunityBoardQueryServiceTest.java (96%) rename src/test/java/com/somemore/community/service/{ => board}/CreateCommunityBoardServiceTest.java (96%) rename src/test/java/com/somemore/community/service/{ => board}/DeleteCommunityBoardServiceTest.java (92%) rename src/test/java/com/somemore/community/service/{ => board}/UpdateCommunityBoardServiceTest.java (95%) diff --git a/src/main/java/com/somemore/community/repository/CommunityBoardJpaRepository.java b/src/main/java/com/somemore/community/repository/board/CommunityBoardJpaRepository.java similarity index 81% rename from src/main/java/com/somemore/community/repository/CommunityBoardJpaRepository.java rename to src/main/java/com/somemore/community/repository/board/CommunityBoardJpaRepository.java index ce59211b9..79b03cd1c 100644 --- a/src/main/java/com/somemore/community/repository/CommunityBoardJpaRepository.java +++ b/src/main/java/com/somemore/community/repository/board/CommunityBoardJpaRepository.java @@ -1,4 +1,4 @@ -package com.somemore.community.repository; +package com.somemore.community.repository.board; import com.somemore.community.domain.CommunityBoard; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/com/somemore/community/repository/CommunityBoardRepository.java b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepository.java similarity index 90% rename from src/main/java/com/somemore/community/repository/CommunityBoardRepository.java rename to src/main/java/com/somemore/community/repository/board/CommunityBoardRepository.java index f7df7bbd5..3340735a5 100644 --- a/src/main/java/com/somemore/community/repository/CommunityBoardRepository.java +++ b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepository.java @@ -1,4 +1,4 @@ -package com.somemore.community.repository; +package com.somemore.community.repository.board; import com.somemore.community.domain.CommunityBoard; import com.somemore.community.domain.CommunityBoardView; diff --git a/src/main/java/com/somemore/community/service/CommunityBoardQueryService.java b/src/main/java/com/somemore/community/service/board/CommunityBoardQueryService.java similarity index 91% rename from src/main/java/com/somemore/community/service/CommunityBoardQueryService.java rename to src/main/java/com/somemore/community/service/board/CommunityBoardQueryService.java index e451949ff..98d45143f 100644 --- a/src/main/java/com/somemore/community/service/CommunityBoardQueryService.java +++ b/src/main/java/com/somemore/community/service/board/CommunityBoardQueryService.java @@ -1,11 +1,11 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import com.somemore.community.domain.CommunityBoard; import com.somemore.community.domain.CommunityBoardView; import com.somemore.community.dto.response.CommunityBoardGetDetailResponseDto; import com.somemore.community.dto.response.CommunityBoardGetResponseDto; -import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.CommunityBoardQueryUseCase; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.community.usecase.board.CommunityBoardQueryUseCase; import com.somemore.global.exception.BadRequestException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/somemore/community/service/CreateCommunityBoardService.java b/src/main/java/com/somemore/community/service/board/CreateCommunityBoardService.java similarity index 81% rename from src/main/java/com/somemore/community/service/CreateCommunityBoardService.java rename to src/main/java/com/somemore/community/service/board/CreateCommunityBoardService.java index 07ad1d456..61bcf1767 100644 --- a/src/main/java/com/somemore/community/service/CreateCommunityBoardService.java +++ b/src/main/java/com/somemore/community/service/board/CreateCommunityBoardService.java @@ -1,9 +1,9 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import com.somemore.community.domain.CommunityBoard; import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; -import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.CreateCommunityBoardUseCase; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.community.usecase.board.CreateCommunityBoardUseCase; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/com/somemore/community/service/DeleteCommunityBoardService.java b/src/main/java/com/somemore/community/service/board/DeleteCommunityBoardService.java similarity index 88% rename from src/main/java/com/somemore/community/service/DeleteCommunityBoardService.java rename to src/main/java/com/somemore/community/service/board/DeleteCommunityBoardService.java index 79c735bf9..ed9ff1424 100644 --- a/src/main/java/com/somemore/community/service/DeleteCommunityBoardService.java +++ b/src/main/java/com/somemore/community/service/board/DeleteCommunityBoardService.java @@ -1,8 +1,8 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import com.somemore.community.domain.CommunityBoard; -import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.DeleteCommunityBoardUseCase; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.community.usecase.board.DeleteCommunityBoardUseCase; import com.somemore.global.exception.BadRequestException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/somemore/community/service/UpdateCommunityBoardService.java b/src/main/java/com/somemore/community/service/board/UpdateCommunityBoardService.java similarity index 88% rename from src/main/java/com/somemore/community/service/UpdateCommunityBoardService.java rename to src/main/java/com/somemore/community/service/board/UpdateCommunityBoardService.java index ef3f96c36..89a5dfb84 100644 --- a/src/main/java/com/somemore/community/service/UpdateCommunityBoardService.java +++ b/src/main/java/com/somemore/community/service/board/UpdateCommunityBoardService.java @@ -1,9 +1,9 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import com.somemore.community.domain.CommunityBoard; import com.somemore.community.dto.request.CommunityBoardUpdateRequestDto; -import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.UpdateCommunityBoardUseCase; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.community.usecase.board.UpdateCommunityBoardUseCase; import com.somemore.global.exception.BadRequestException; import java.util.UUID; diff --git a/src/main/java/com/somemore/community/usecase/CommunityBoardQueryUseCase.java b/src/main/java/com/somemore/community/usecase/board/CommunityBoardQueryUseCase.java similarity index 91% rename from src/main/java/com/somemore/community/usecase/CommunityBoardQueryUseCase.java rename to src/main/java/com/somemore/community/usecase/board/CommunityBoardQueryUseCase.java index 2b4da6312..70987a033 100644 --- a/src/main/java/com/somemore/community/usecase/CommunityBoardQueryUseCase.java +++ b/src/main/java/com/somemore/community/usecase/board/CommunityBoardQueryUseCase.java @@ -1,4 +1,4 @@ -package com.somemore.community.usecase; +package com.somemore.community.usecase.board; import com.somemore.community.dto.response.CommunityBoardGetDetailResponseDto; import com.somemore.community.dto.response.CommunityBoardGetResponseDto; diff --git a/src/main/java/com/somemore/community/usecase/CreateCommunityBoardUseCase.java b/src/main/java/com/somemore/community/usecase/board/CreateCommunityBoardUseCase.java similarity index 85% rename from src/main/java/com/somemore/community/usecase/CreateCommunityBoardUseCase.java rename to src/main/java/com/somemore/community/usecase/board/CreateCommunityBoardUseCase.java index 2e0c3828f..6df8878da 100644 --- a/src/main/java/com/somemore/community/usecase/CreateCommunityBoardUseCase.java +++ b/src/main/java/com/somemore/community/usecase/board/CreateCommunityBoardUseCase.java @@ -1,4 +1,4 @@ -package com.somemore.community.usecase; +package com.somemore.community.usecase.board; import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; diff --git a/src/main/java/com/somemore/community/usecase/DeleteCommunityBoardUseCase.java b/src/main/java/com/somemore/community/usecase/board/DeleteCommunityBoardUseCase.java similarity index 73% rename from src/main/java/com/somemore/community/usecase/DeleteCommunityBoardUseCase.java rename to src/main/java/com/somemore/community/usecase/board/DeleteCommunityBoardUseCase.java index d2f26500e..345936db9 100644 --- a/src/main/java/com/somemore/community/usecase/DeleteCommunityBoardUseCase.java +++ b/src/main/java/com/somemore/community/usecase/board/DeleteCommunityBoardUseCase.java @@ -1,4 +1,4 @@ -package com.somemore.community.usecase; +package com.somemore.community.usecase.board; import java.util.UUID; diff --git a/src/main/java/com/somemore/community/usecase/UpdateCommunityBoardUseCase.java b/src/main/java/com/somemore/community/usecase/board/UpdateCommunityBoardUseCase.java similarity index 87% rename from src/main/java/com/somemore/community/usecase/UpdateCommunityBoardUseCase.java rename to src/main/java/com/somemore/community/usecase/board/UpdateCommunityBoardUseCase.java index e8690b283..4014f5fe3 100644 --- a/src/main/java/com/somemore/community/usecase/UpdateCommunityBoardUseCase.java +++ b/src/main/java/com/somemore/community/usecase/board/UpdateCommunityBoardUseCase.java @@ -1,4 +1,4 @@ -package com.somemore.community.usecase; +package com.somemore.community.usecase.board; import com.somemore.community.dto.request.CommunityBoardUpdateRequestDto; diff --git a/src/test/java/com/somemore/community/service/CommunityBoardQueryServiceTest.java b/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java similarity index 96% rename from src/test/java/com/somemore/community/service/CommunityBoardQueryServiceTest.java rename to src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java index 3d82d4281..e8c72be10 100644 --- a/src/test/java/com/somemore/community/service/CommunityBoardQueryServiceTest.java +++ b/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java @@ -1,4 +1,4 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import com.somemore.IntegrationTestSupport; import com.somemore.auth.oauth.OAuthProvider; @@ -7,9 +7,9 @@ import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; import com.somemore.community.dto.response.CommunityBoardGetDetailResponseDto; import com.somemore.community.dto.response.CommunityBoardGetResponseDto; -import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.CreateCommunityBoardUseCase; -import com.somemore.community.usecase.DeleteCommunityBoardUseCase; +import com.somemore.community.repository.board.CommunityBoardRepository; +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 com.somemore.volunteer.domain.Volunteer; diff --git a/src/test/java/com/somemore/community/service/CreateCommunityBoardServiceTest.java b/src/test/java/com/somemore/community/service/board/CreateCommunityBoardServiceTest.java similarity index 96% rename from src/test/java/com/somemore/community/service/CreateCommunityBoardServiceTest.java rename to src/test/java/com/somemore/community/service/board/CreateCommunityBoardServiceTest.java index d373da46a..ec9db956b 100644 --- a/src/test/java/com/somemore/community/service/CreateCommunityBoardServiceTest.java +++ b/src/test/java/com/somemore/community/service/board/CreateCommunityBoardServiceTest.java @@ -1,11 +1,11 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import static org.assertj.core.api.Assertions.assertThat; import com.somemore.IntegrationTestSupport; import com.somemore.community.domain.CommunityBoard; import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; -import com.somemore.community.repository.CommunityBoardRepository; +import com.somemore.community.repository.board.CommunityBoardRepository; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/somemore/community/service/DeleteCommunityBoardServiceTest.java b/src/test/java/com/somemore/community/service/board/DeleteCommunityBoardServiceTest.java similarity index 92% rename from src/test/java/com/somemore/community/service/DeleteCommunityBoardServiceTest.java rename to src/test/java/com/somemore/community/service/board/DeleteCommunityBoardServiceTest.java index e72667431..8cc6a566e 100644 --- a/src/test/java/com/somemore/community/service/DeleteCommunityBoardServiceTest.java +++ b/src/test/java/com/somemore/community/service/board/DeleteCommunityBoardServiceTest.java @@ -1,13 +1,13 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import com.somemore.IntegrationTestSupport; import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; -import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.CreateCommunityBoardUseCase; -import com.somemore.community.usecase.CommunityBoardQueryUseCase; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.community.usecase.board.CreateCommunityBoardUseCase; +import com.somemore.community.usecase.board.CommunityBoardQueryUseCase; import com.somemore.global.exception.BadRequestException; import com.somemore.global.exception.ExceptionMessage; import org.assertj.core.api.ThrowableAssert; diff --git a/src/test/java/com/somemore/community/service/UpdateCommunityBoardServiceTest.java b/src/test/java/com/somemore/community/service/board/UpdateCommunityBoardServiceTest.java similarity index 95% rename from src/test/java/com/somemore/community/service/UpdateCommunityBoardServiceTest.java rename to src/test/java/com/somemore/community/service/board/UpdateCommunityBoardServiceTest.java index 06bd1de86..5e7f30264 100644 --- a/src/test/java/com/somemore/community/service/UpdateCommunityBoardServiceTest.java +++ b/src/test/java/com/somemore/community/service/board/UpdateCommunityBoardServiceTest.java @@ -1,4 +1,4 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -7,8 +7,8 @@ import com.somemore.community.domain.CommunityBoard; import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; import com.somemore.community.dto.request.CommunityBoardUpdateRequestDto; -import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.CreateCommunityBoardUseCase; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.community.usecase.board.CreateCommunityBoardUseCase; import com.somemore.global.exception.BadRequestException; import com.somemore.global.exception.ExceptionMessage; import org.assertj.core.api.ThrowableAssert; From b686152c855d82ae84945c4243cbd9667f2a9e50 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 11:36:48 +0900 Subject: [PATCH 06/25] =?UTF-8?q?chore(community):=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20import=20=EB=B0=8F=20public=20=ED=82=A4?= =?UTF-8?q?=EC=9B=8C=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/comment/CommunityCommentRepositoryImpl.java | 1 - .../usecase/comment/CreateCommunityCommentUseCase.java | 1 - .../community/repository/CommunityCommentRepositoryTest.java | 2 +- .../service/comment/CreateCommunityCommentServiceTest.java | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java index 12da16d85..9d2cee7ba 100644 --- a/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java +++ b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java @@ -2,7 +2,6 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import com.somemore.community.domain.CommunityComment; -import com.somemore.community.domain.QCommunityBoard; import com.somemore.community.domain.QCommunityComment; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; diff --git a/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java b/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java index 5c6224877..823d3acce 100644 --- a/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java +++ b/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java @@ -1,6 +1,5 @@ package com.somemore.community.usecase.comment; -import com.somemore.community.domain.CommunityComment; import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; import java.util.UUID; diff --git a/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java b/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java index 21142d6b2..4c67544f1 100644 --- a/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java +++ b/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java @@ -12,7 +12,7 @@ import static org.assertj.core.api.Assertions.assertThat; @Transactional -public class CommunityCommentRepositoryTest extends IntegrationTestSupport { +class CommunityCommentRepositoryTest extends IntegrationTestSupport { @Autowired CommunityCommentRepository communityCommentRepository; 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 2aab170de..f0676adb2 100644 --- a/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java +++ b/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java @@ -14,7 +14,7 @@ import static org.assertj.core.api.Assertions.assertThat; -public class CreateCommunityCommentServiceTest extends IntegrationTestSupport { +class CreateCommunityCommentServiceTest extends IntegrationTestSupport { @Autowired private CreateCommunityCommentService createCommunityCommentService; From 0be3598afd33409ebe0304d39413defa0d083504 Mon Sep 17 00:00:00 2001 From: seojin Yoon <90759319+7zrv@users.noreply.github.com> Date: Thu, 28 Nov 2024 14:36:34 +0900 Subject: [PATCH 07/25] =?UTF-8?q?Feature/36=20s3=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#66)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 이미지 업로드 기능 구현 - aws s3 연동을 위한 의존성 추가 - 환경변수 추가 - S3 연결을 위한 config 클래스 구현 - 서비스 레이어에 이미지 업로드 기능 구현 - 업로드 실패 예외와 예외 메세지 추 - test.yml에 테스트에 필요한 환경변수 추가 - 테스트 코드 작성및 검증 완료 * chore: 환경변수 추가 - cicd workflow 에 이미지 업로드 관련 환경변수 추가 - appication.yml에 이미지 업로드 관련 환경변수 이름 변경 * feat: 이미지 파일 검증 기능 구현 - 이미지 크기를 8MB로 제한 - 이미지의 크기 초과를 검증하는 기능 구현 - 이미지의 확장자명을 검증하는 기능 구현 - 이미지 업로드시 검증 기능들을 수행하도록 수정 - 전역 예외처리 핸들러에 이미지 업로드 예외 추가 - 예외 메세지 추가 - 테스트 코드 작성및 검증 완 * fix: 코드 리뷰 사항 반영 - BASE_URL을 S3_BASE_URL라는 더 명시적인 이름으로 변경 - ImageUploadUtils private 생성자의 예외처리 메세지를 ExceptionMessage에 등록하여 사용하도록 수정 - 이미지 업로드 메서드의 내부 기능을 메서드로 추출하여 가독성 향상 - ImageUploadUtils의 일부 기능의 접근 제어자를 private으로 수정 - 테스트 코드의 when, then을 더 명확하게 분 --- .github/workflows/CD.yml | 5 ++ .github/workflows/CI.yml | 5 ++ build.gradle | 4 +- .../somemore/global/configure/S3Config.java | 45 ++++++++++ .../global/exception/ExceptionMessage.java | 5 ++ .../exception/ImageUploadException.java | 8 ++ .../handler/GlobalExceptionHandler.java | 14 +++ .../dto/ImageUploadRequestDto.java | 8 ++ .../service/ImageUploadService.java | 63 ++++++++++++++ .../usecase/ImageUploadUseCase.java | 7 ++ .../imageupload/util/ImageUploadUtils.java | 27 ++++++ .../DefaultImageUploadValidator.java | 39 +++++++++ .../validator/ImageUploadValidator.java | 9 ++ src/main/resources/application.yml | 20 +++++ .../service/ImageUploadServiceTest.java | 79 +++++++++++++++++ .../util/ImageUploadUtilsTest.java | 84 ++++++++++++++++++ .../DefaultImageUploadValidatorTest.java | 86 +++++++++++++++++++ src/test/resources/application-test.yml | 14 +++ 18 files changed, 521 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/somemore/global/configure/S3Config.java create mode 100644 src/main/java/com/somemore/global/exception/ImageUploadException.java create mode 100644 src/main/java/com/somemore/imageupload/dto/ImageUploadRequestDto.java create mode 100644 src/main/java/com/somemore/imageupload/service/ImageUploadService.java create mode 100644 src/main/java/com/somemore/imageupload/usecase/ImageUploadUseCase.java create mode 100644 src/main/java/com/somemore/imageupload/util/ImageUploadUtils.java create mode 100644 src/main/java/com/somemore/imageupload/validator/DefaultImageUploadValidator.java create mode 100644 src/main/java/com/somemore/imageupload/validator/ImageUploadValidator.java create mode 100644 src/test/java/com/somemore/imageupload/service/ImageUploadServiceTest.java create mode 100644 src/test/java/com/somemore/imageupload/util/ImageUploadUtilsTest.java create mode 100644 src/test/java/com/somemore/imageupload/validator/DefaultImageUploadValidatorTest.java diff --git a/.github/workflows/CD.yml b/.github/workflows/CD.yml index dabaf0779..5dee87723 100644 --- a/.github/workflows/CD.yml +++ b/.github/workflows/CD.yml @@ -27,6 +27,11 @@ jobs: JWT_SECRET: ${{ secrets.JWT_SECRET }} FRONT_URL: ${{secrets.FRONT_URL}} BACK_URL: ${{secrets.BACK_URL}} + BUCKET_NAME: ${{secrets.BUCKET_NAME}} + BUCKET_REGION: ${{secrets.BUCKET_REGION}} + IMG_BASE_URL: ${{secrets.BASE_URL}} + S3_ACCESS_KEY: ${{secrets.S3_ACCESS_KEY}} + S3_SECRET_KEY: ${{secrets.S3_SECRET_KEY}} steps: - name: Github Repository 파일 불러오기 diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 26939d2b9..629520d89 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -35,6 +35,11 @@ jobs: JWT_SECRET: ${{ secrets.JWT_SECRET }} FRONT_URL: ${{secrets.FRONT_URL}} BACK_URL: ${{secrets.BACK_URL}} + BUCKET_NAME: ${{secrets.BUCKET_NAME}} + BUCKET_REGION: ${{secrets.BUCKET_REGION}} + IMG_BASE_URL: ${{secrets.BASE_URL}} + S3_ACCESS_KEY: ${{secrets.S3_ACCESS_KEY}} + S3_SECRET_KEY: ${{secrets.S3_SECRET_KEY}} steps: diff --git a/build.gradle b/build.gradle index c49448165..ebb137d36 100644 --- a/build.gradle +++ b/build.gradle @@ -52,6 +52,9 @@ dependencies { runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6' + // AWS + implementation(platform("software.amazon.awssdk:bom:2.29.20")) + implementation("software.amazon.awssdk:s3") // Web Layer implementation 'org.springframework.boot:spring-boot-starter-web' @@ -61,7 +64,6 @@ dependencies { annotationProcessor 'org.projectlombok:lombok' implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.6.0' - //test testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' diff --git a/src/main/java/com/somemore/global/configure/S3Config.java b/src/main/java/com/somemore/global/configure/S3Config.java new file mode 100644 index 000000000..b58ef6755 --- /dev/null +++ b/src/main/java/com/somemore/global/configure/S3Config.java @@ -0,0 +1,45 @@ +package com.somemore.global.configure; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.AwsCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.presigner.S3Presigner; + +@Configuration +public class S3Config { + @Value("${cloud.aws.credentials.access-key}") + private String accessKey; + + @Value("${cloud.aws.credentials.secret-key}") + private String secretKey; + + @Value("${cloud.aws.region.static}") + private String region; + + @Bean + public AwsCredentials basicAWSCredentials() { + return AwsBasicCredentials.create(accessKey, secretKey); + } + + @Bean + public S3Presigner s3Presigner(AwsCredentials awsCredentials) { + return S3Presigner.builder() + .region(Region.of(region)) + .credentialsProvider(StaticCredentialsProvider.create(awsCredentials)) + .build(); + } + + @Bean + public S3Client s3Client(AwsCredentials awsCredentials) { + return S3Client.builder() + .region(Region.of(region)) + .credentialsProvider(StaticCredentialsProvider.create(awsCredentials)) + .build(); + } + +} diff --git a/src/main/java/com/somemore/global/exception/ExceptionMessage.java b/src/main/java/com/somemore/global/exception/ExceptionMessage.java index 2c3b040c7..de2ac538b 100644 --- a/src/main/java/com/somemore/global/exception/ExceptionMessage.java +++ b/src/main/java/com/somemore/global/exception/ExceptionMessage.java @@ -14,6 +14,11 @@ public enum ExceptionMessage { NOT_EXISTS_LOCATION("존재하지 않는 위치 ID 입니다."), NOT_EXISTS_RECRUIT_BOARD("존재하지 않는 봉사 모집글 ID 입니다."), UNAUTHORIZED_RECRUIT_BOARD("자신이 작성한 봉사 모집글이 아닙니다."), + UPLOAD_FAILED("파일 업로드에 실패했습니다."), + INVALID_FILE_TYPE("지원하지 않는 파일 형식입니다."), + FILE_SIZE_EXCEEDED("파일 크기가 허용된 한도를 초과했습니다."), + EMPTY_FILE("파일이 존재하지 않습니다."), + INSTANTIATION_NOT_ALLOWED("인스턴스화 할 수 없는 클래스 입니다.") ; private final String message; diff --git a/src/main/java/com/somemore/global/exception/ImageUploadException.java b/src/main/java/com/somemore/global/exception/ImageUploadException.java new file mode 100644 index 000000000..d314407ea --- /dev/null +++ b/src/main/java/com/somemore/global/exception/ImageUploadException.java @@ -0,0 +1,8 @@ +package com.somemore.global.exception; + +public class ImageUploadException extends RuntimeException{ + + public ImageUploadException(String message) { + super(message); + } +} diff --git a/src/main/java/com/somemore/global/handler/GlobalExceptionHandler.java b/src/main/java/com/somemore/global/handler/GlobalExceptionHandler.java index 742719d0d..3f6cc0736 100644 --- a/src/main/java/com/somemore/global/handler/GlobalExceptionHandler.java +++ b/src/main/java/com/somemore/global/handler/GlobalExceptionHandler.java @@ -2,10 +2,13 @@ import com.somemore.global.exception.BadRequestException; +import com.somemore.global.exception.ImageUploadException; +import org.springframework.data.crossstore.ChangeSetPersister; import org.springframework.http.HttpStatus; import org.springframework.http.ProblemDetail; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; @@ -25,4 +28,15 @@ ProblemDetail handleBadRequestException(final BadRequestException e) { return problemDetail; } + @ExceptionHandler(ImageUploadException.class) + ProblemDetail handleImageUploadException(final ImageUploadException e) { + + ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, e.getMessage()); + + problemDetail.setTitle("이미지 업로드 실패"); + problemDetail.setDetail("업로드 중 문제가 발생했습니다. 파일 크기나 형식이 올바른지 확인해 주세요."); + + return problemDetail; + } + } diff --git a/src/main/java/com/somemore/imageupload/dto/ImageUploadRequestDto.java b/src/main/java/com/somemore/imageupload/dto/ImageUploadRequestDto.java new file mode 100644 index 000000000..8cc01de84 --- /dev/null +++ b/src/main/java/com/somemore/imageupload/dto/ImageUploadRequestDto.java @@ -0,0 +1,8 @@ +package com.somemore.imageupload.dto; + +import org.springframework.web.multipart.MultipartFile; + +public record ImageUploadRequestDto( + MultipartFile imageFile +) { +} diff --git a/src/main/java/com/somemore/imageupload/service/ImageUploadService.java b/src/main/java/com/somemore/imageupload/service/ImageUploadService.java new file mode 100644 index 000000000..1542ac30a --- /dev/null +++ b/src/main/java/com/somemore/imageupload/service/ImageUploadService.java @@ -0,0 +1,63 @@ +package com.somemore.imageupload.service; + +import com.somemore.global.exception.ImageUploadException; +import com.somemore.imageupload.dto.ImageUploadRequestDto; +import com.somemore.imageupload.usecase.ImageUploadUseCase; +import com.somemore.imageupload.util.ImageUploadUtils; +import com.somemore.imageupload.validator.ImageUploadValidator; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import software.amazon.awssdk.core.sync.RequestBody; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.model.PutObjectRequest; + +import java.io.IOException; + +import static com.somemore.global.exception.ExceptionMessage.UPLOAD_FAILED; + +@RequiredArgsConstructor +@Service +public class ImageUploadService implements ImageUploadUseCase { + + private final S3Client s3Client; + private final ImageUploadValidator imageUploadValidator; + + @Value("${cloud.aws.s3.bucket}") + private String bucket; + + @Value("${cloud.aws.s3.base-url}") + private String baseUrl; + + @Override + public String uploadImage(ImageUploadRequestDto requestDto) { + imageUploadValidator.validateFileSize(requestDto.imageFile()); + imageUploadValidator.validateFileType(requestDto.imageFile()); + + try { + return uploadToS3(requestDto.imageFile()); + } catch (IOException e) { + throw new ImageUploadException(UPLOAD_FAILED.getMessage()); + } + } + + private String uploadToS3(MultipartFile file) throws IOException { + String fileName = ImageUploadUtils.generateUniqueFileName(file.getOriginalFilename()); + + PutObjectRequest request = createPutObjectRequest(file, fileName); + + s3Client.putObject(request, RequestBody.fromInputStream(file.getInputStream(), file.getSize())); + + return ImageUploadUtils.generateS3Url(baseUrl, fileName); + } + + private PutObjectRequest createPutObjectRequest(MultipartFile file, String fileName) { + return PutObjectRequest.builder() + .bucket(bucket) + .key(fileName) + .contentType(file.getContentType()) + .build(); + } + +} diff --git a/src/main/java/com/somemore/imageupload/usecase/ImageUploadUseCase.java b/src/main/java/com/somemore/imageupload/usecase/ImageUploadUseCase.java new file mode 100644 index 000000000..acfd3ed2c --- /dev/null +++ b/src/main/java/com/somemore/imageupload/usecase/ImageUploadUseCase.java @@ -0,0 +1,7 @@ +package com.somemore.imageupload.usecase; + +import com.somemore.imageupload.dto.ImageUploadRequestDto; + +public interface ImageUploadUseCase { + String uploadImage(ImageUploadRequestDto requestDto); +} diff --git a/src/main/java/com/somemore/imageupload/util/ImageUploadUtils.java b/src/main/java/com/somemore/imageupload/util/ImageUploadUtils.java new file mode 100644 index 000000000..c72e2c5b0 --- /dev/null +++ b/src/main/java/com/somemore/imageupload/util/ImageUploadUtils.java @@ -0,0 +1,27 @@ +package com.somemore.imageupload.util; + +import java.util.UUID; + +import static com.somemore.global.exception.ExceptionMessage.INSTANTIATION_NOT_ALLOWED; + +public class ImageUploadUtils { + + private ImageUploadUtils() { + throw new UnsupportedOperationException(INSTANTIATION_NOT_ALLOWED.getMessage()); + } + + public static String generateUniqueFileName(String originalFileName) { + String uuid = UUID.randomUUID().toString(); + String fileExtension = extractFileExtension(originalFileName); + return uuid + fileExtension; + } + + private static String extractFileExtension(String fileName) { + return fileName.substring(fileName.lastIndexOf(".")); + } + + public static String generateS3Url(String baseUrl, String fileName) { + return String.format("%s/%s", baseUrl, fileName); + } + +} diff --git a/src/main/java/com/somemore/imageupload/validator/DefaultImageUploadValidator.java b/src/main/java/com/somemore/imageupload/validator/DefaultImageUploadValidator.java new file mode 100644 index 000000000..865dd2844 --- /dev/null +++ b/src/main/java/com/somemore/imageupload/validator/DefaultImageUploadValidator.java @@ -0,0 +1,39 @@ +package com.somemore.imageupload.validator; + +import com.somemore.global.exception.ImageUploadException; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import static com.somemore.global.exception.ExceptionMessage.*; + +@Component +public class DefaultImageUploadValidator implements ImageUploadValidator { + + private static final long MAX_FILE_SIZE = 8L * 1024 * 1024; // 8MB + + public void validateFileSize(MultipartFile file) { + if (file == null || file.isEmpty()) { + throw new ImageUploadException(EMPTY_FILE.getMessage()); + } + + if (file.getSize() > MAX_FILE_SIZE) { + throw new ImageUploadException(FILE_SIZE_EXCEEDED.getMessage()); + } + } + + public void validateFileType(MultipartFile file) { + String contentType = file.getContentType(); + if (!isAllowedImageType(contentType)) { + throw new ImageUploadException(INVALID_FILE_TYPE.getMessage()); + } + } + + private boolean isAllowedImageType(String contentType) { + return contentType != null && ( + contentType.equals("image/jpeg") || + contentType.equals("image/png") || + contentType.equals("image/gif") || + contentType.equals("image/webp") + ); + } +} diff --git a/src/main/java/com/somemore/imageupload/validator/ImageUploadValidator.java b/src/main/java/com/somemore/imageupload/validator/ImageUploadValidator.java new file mode 100644 index 000000000..2481c5d48 --- /dev/null +++ b/src/main/java/com/somemore/imageupload/validator/ImageUploadValidator.java @@ -0,0 +1,9 @@ +package com.somemore.imageupload.validator; + +import org.springframework.web.multipart.MultipartFile; + +public interface ImageUploadValidator { + + void validateFileSize(MultipartFile file); + void validateFileType(MultipartFile file); +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 73394baa0..6621c5d18 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,6 +2,20 @@ app: front-url: ${FRONT_URL} back-url: ${BACK_URL} +# AWS S3 +cloud: + aws: + credentials: + access-key: ${S3_ACCESS_KEY} + secret-key: ${S3_SECRET_KEY} + region: + static: ${BUCKET_REGION} + s3: + bucket: ${BUCKET_NAME} + base-url: ${IMG_BASE_URL} + stack: + auto: false + spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver @@ -47,6 +61,12 @@ spring: locale: ko_KR locale-resolver: fixed + servlet: + multipart: + max-file-size: 8MB + max-request-size: 8MB + + #swagger springdoc: swagger-ui: diff --git a/src/test/java/com/somemore/imageupload/service/ImageUploadServiceTest.java b/src/test/java/com/somemore/imageupload/service/ImageUploadServiceTest.java new file mode 100644 index 000000000..31e2fbfd6 --- /dev/null +++ b/src/test/java/com/somemore/imageupload/service/ImageUploadServiceTest.java @@ -0,0 +1,79 @@ +package com.somemore.imageupload.service; + +import com.somemore.IntegrationTestSupport; +import com.somemore.global.exception.ImageUploadException; +import com.somemore.imageupload.dto.ImageUploadRequestDto; +import com.somemore.imageupload.validator.ImageUploadValidator; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.web.multipart.MultipartFile; +import software.amazon.awssdk.core.sync.RequestBody; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.model.PutObjectRequest; + +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class ImageUploadServiceTest extends IntegrationTestSupport { + + @Mock + private S3Client s3Client; + + @Mock + private ImageUploadValidator imageUploadValidator; + + @InjectMocks + private ImageUploadService imageUploadService; + + @Mock + private MultipartFile multipartFile; + + @BeforeEach + void setUp() throws IOException { + ReflectionTestUtils.setField(imageUploadService, "bucket", "test-bucket"); + ReflectionTestUtils.setField(imageUploadService, "baseUrl", "https://amazonaws.com/"); + + when(multipartFile.getOriginalFilename()).thenReturn("testImage.jpg"); + when(multipartFile.getContentType()).thenReturn("image/jpeg"); + when(multipartFile.getInputStream()).thenReturn(mock(InputStream.class)); + when(multipartFile.getSize()).thenReturn(1000L); + } + + @DisplayName("업로드 요청 이미지를 S3에 업로드 할 수 있다.") + @Test + void testUploadImage_success() { + // given + ImageUploadRequestDto requestDto = new ImageUploadRequestDto(multipartFile); + + when(s3Client.putObject(any(PutObjectRequest.class), any(RequestBody.class))) + .thenReturn(null); + + // when + String result = imageUploadService.uploadImage(requestDto); + + // then + verify(s3Client, times(1)).putObject(any(PutObjectRequest.class), any(RequestBody.class)); + assertNotNull(result); + assertTrue(result.startsWith("https://amazonaws.com/")); + assertTrue(result.endsWith(".jpg")); + } + + @DisplayName("이미지 형식이 올바르지 않다면 업로드 할 수 없다.") + @Test + void testUploadImage_failure() throws IOException { + // given + when(multipartFile.getInputStream()).thenThrow(new IOException()); + + ImageUploadRequestDto requestDto = new ImageUploadRequestDto(multipartFile); + + // when, then + assertThrows(ImageUploadException.class, () -> imageUploadService.uploadImage(requestDto)); + } +} diff --git a/src/test/java/com/somemore/imageupload/util/ImageUploadUtilsTest.java b/src/test/java/com/somemore/imageupload/util/ImageUploadUtilsTest.java new file mode 100644 index 000000000..15180389b --- /dev/null +++ b/src/test/java/com/somemore/imageupload/util/ImageUploadUtilsTest.java @@ -0,0 +1,84 @@ +package com.somemore.imageupload.util; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import static org.junit.jupiter.api.Assertions.*; + +class ImageUploadUtilsTest { + + @Test + void privateConstructorShouldThrowException() throws Exception { + // given + Constructor constructor = ImageUploadUtils.class.getDeclaredConstructor(); + constructor.setAccessible(true); + + // when + InvocationTargetException exception = assertThrows(InvocationTargetException.class, constructor::newInstance); + + // then + assertThrows(UnsupportedOperationException.class, () -> { throw exception.getCause(); }); + } + + @DisplayName("이미지 업로드시 유일한 이미지 이름을 만들어줄 수 있다.") + @Test + void testGenerateUniqueFileName() { + //given + String fileName = "image.png"; + + //when + String uniqueName = ImageUploadUtils.generateUniqueFileName(fileName); + + //then + assertTrue(uniqueName.endsWith(".png")); + assertNotEquals(fileName, uniqueName); + } + + @DisplayName("유니크한 파일 이름을 생성할 때 UUID는 정상적으로 생성된다.") + @Test + void testGenerateUniqueFileName_uuid() { + // given + String fileName = "image.png"; + + // when + String uniqueName = ImageUploadUtils.generateUniqueFileName(fileName); + + // then + assertNotNull(uniqueName); + assertTrue(uniqueName.contains("-")); + assertTrue(uniqueName.endsWith(".png")); + } + + + @DisplayName("이미지의 주소를 반환할 수 있다.") + @Test + void testGenerateS3Url() { + //given + String baseUrl = "https://amazonaws.com"; + String fileName = "unique-image.png"; + + //when + String url = ImageUploadUtils.generateS3Url(baseUrl, fileName); + + //then + assertEquals("https://amazonaws.com/unique-image.png", url); + } + + @DisplayName("baseUrl이 빈 문자열일 경우 URL을 생성할 수 있다.") + @Test + void testGenerateS3Url_emptyBaseUrl() { + // given + String baseUrl = ""; + String fileName = "unique-image.png"; + + // when + String url = ImageUploadUtils.generateS3Url(baseUrl, fileName); + + // then + assertEquals("/unique-image.png", url); + } + +} \ No newline at end of file diff --git a/src/test/java/com/somemore/imageupload/validator/DefaultImageUploadValidatorTest.java b/src/test/java/com/somemore/imageupload/validator/DefaultImageUploadValidatorTest.java new file mode 100644 index 000000000..03c2d6b0e --- /dev/null +++ b/src/test/java/com/somemore/imageupload/validator/DefaultImageUploadValidatorTest.java @@ -0,0 +1,86 @@ +package com.somemore.imageupload.validator; + +import com.somemore.global.exception.ImageUploadException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.web.multipart.MultipartFile; + +import static org.junit.jupiter.api.Assertions.*; + +class DefaultImageUploadValidatorTest { + + private DefaultImageUploadValidator imageUploadValidator; + + @BeforeEach + void setUp() { + // given + imageUploadValidator = new DefaultImageUploadValidator(); + } + + @Test + @DisplayName("파일이 비어있으면 예외가 발생한다.") + void shouldThrowExceptionWhenFileIsEmpty() { + //given + MultipartFile emptyFile = new MockMultipartFile("file", new byte[0]); + + //when + Throwable exception = assertThrows(ImageUploadException.class, () -> imageUploadValidator.validateFileSize(emptyFile)); + + //then + assertEquals(ImageUploadException.class, exception.getClass()); + } + + @Test + @DisplayName("파일 크기가 최대 8MB를 초과하는 경우, 예외가 발생한다.") + void shouldThrowExceptionWhenFileSizeExceeded() { + // given + MultipartFile largeFile = new MockMultipartFile("file", "largeImage.jpg", "image/jpeg", new byte[9 * 1024 * 1024]); + + // when + Throwable exception = assertThrows(ImageUploadException.class, () -> imageUploadValidator.validateFileSize(largeFile)); + + // then + assertEquals(ImageUploadException.class, exception.getClass()); + } + + @Test + @DisplayName("유효한 이미지 타입(JPEG) 파일은, 검증에 통과한다.") + void shouldNotThrowExceptionWhenFileTypeIsValidJpeg() { + // given + MultipartFile validFile = new MockMultipartFile("file", "validImage.jpg", "image/jpeg", new byte[1024]); + + // when + imageUploadValidator.validateFileType(validFile); + + // then + assertDoesNotThrow(() -> imageUploadValidator.validateFileType(validFile)); + } + + @Test + @DisplayName("유효하지 않은 이미지 타입 파일이 있을 경우, 예외가 발생한다.") + void shouldThrowExceptionWhenFileTypeIsInvalid() { + // given + MultipartFile invalidFile = new MockMultipartFile("file", "invalidFile.pdf", "application/pdf", new byte[1024]); + + // when + Throwable exception = assertThrows(ImageUploadException.class, () -> imageUploadValidator.validateFileType(invalidFile)); + + // then + assertEquals(ImageUploadException.class, exception.getClass()); + } + + @Test + @DisplayName("파일 타입이 올바르지 않을 경우, 예외가 발생한다.") + void shouldThrowExceptionWhenFileTypeIsNull() { + // given + MultipartFile nullContentTypeFile = new MockMultipartFile("file", "noContentTypeFile.jpg", null, new byte[1024]); + + // when + Throwable exception = assertThrows(ImageUploadException.class, () -> imageUploadValidator.validateFileType(nullContentTypeFile)); + + // then + assertEquals(ImageUploadException.class, exception.getClass()); + } +} diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml index fab7dd965..50d9922c6 100644 --- a/src/test/resources/application-test.yml +++ b/src/test/resources/application-test.yml @@ -44,3 +44,17 @@ server: charset: UTF-8 enabled: true force: true + +cloud: + aws: + credentials: + access-key: test-access-key + secret-key: test-secret-key + region: + static: ap-northeast-2 + s3: + bucket: somemore + base-url: https://somemore-image.s3.ap-northeast-2.amazonaws.com + stack: + auto: false + From f68bb02ba4f19b96ea1e07bb44b88d9680bb0f9a Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 16:06:48 +0900 Subject: [PATCH 08/25] =?UTF-8?q?test(community):=20=EC=BB=A4=EB=AE=A4?= =?UTF-8?q?=EB=8B=88=ED=8B=B0=20=EB=8C=93=EA=B8=80=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - repository 테스트에 findById 테스트 추가 - service 테스트에 대댓글 예외 테스트 추가 --- .../CommunityCommentRepositoryTest.java | 29 +++++++++- .../CreateCommunityCommentServiceTest.java | 53 +++++++++++++++---- 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java b/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java index 4c67544f1..0f0625189 100644 --- a/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java +++ b/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java @@ -7,6 +7,8 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; @@ -38,7 +40,7 @@ void createCommunityComment() { assertThat(savedComment.getParentCommentId()).isNull(); } - @DisplayName("커뮤니티 게시글에 대댓글을 생성할 수 있다. (Repository)") + @DisplayName("댓글에 대댓글을 생성할 수 있다. (Repository)") @Test void createCommunityCommentReply() { @@ -59,4 +61,29 @@ void createCommunityCommentReply() { assertThat(savedComment.getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); assertThat(savedComment.getParentCommentId()).isEqualTo(1L); } + + @DisplayName("댓글을 id로 조회할 수 있다. (Repository)") + @Test + void findCommunityCommentById() { + + //given + UUID writerId = UUID.randomUUID(); + + CommunityComment communityComment = CommunityComment.builder() + .writerId(writerId) + .content("커뮤니티 댓글 테스트 내용") + .parentCommentId(null) + .build(); + + CommunityComment savedComment = communityCommentRepository.save(communityComment); + + //when + Optional comment = communityCommentRepository.findById(savedComment.getId()); + + //then + assertThat(comment).isPresent(); + assertThat(comment.get().getWriterId()).isEqualTo(writerId); + assertThat(comment.get().getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); + assertThat(comment.get().getParentCommentId()).isNull(); + } } 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 f0676adb2..36350d830 100644 --- a/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java +++ b/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java @@ -4,6 +4,9 @@ import com.somemore.community.domain.CommunityComment; import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; import com.somemore.community.repository.comment.CommunityCommentRepository; +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.DisplayName; import org.junit.jupiter.api.Test; @@ -13,6 +16,7 @@ import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; class CreateCommunityCommentServiceTest extends IntegrationTestSupport { @@ -33,12 +37,13 @@ void createCommunityCommentWithDto() { //given CommunityCommentCreateRequestDto dto = CommunityCommentCreateRequestDto.builder() .content("커뮤니티 댓글 테스트 내용") + .parentCommentId(null) .build(); UUID writerId = UUID.randomUUID(); //when - Long commentId = createCommunityCommentService.CreateCommunityComment(dto, writerId, null); + Long commentId = createCommunityCommentService.createCommunityComment(dto, writerId); //then Optional communityComment = communityCommentRepository.findById(commentId); @@ -50,27 +55,53 @@ void createCommunityCommentWithDto() { assertThat(communityComment.get().getParentCommentId()).isNull(); } - @DisplayName("커뮤니티 게시글에 대댓글을 등록한다.") + @DisplayName("댓글에 대댓글을 등록한다.") @Test - void createCommunityCommenReplytWithDto() { + void createCommunityCommentRelyWithDto() { //given - CommunityCommentCreateRequestDto dto = CommunityCommentCreateRequestDto.builder() + CommunityCommentCreateRequestDto commentDto = CommunityCommentCreateRequestDto.builder() .content("커뮤니티 댓글 테스트 내용") + .parentCommentId(null) .build(); UUID writerId = UUID.randomUUID(); + Long commentId = createCommunityCommentService.createCommunityComment(commentDto, writerId); + + CommunityCommentCreateRequestDto replyDto = CommunityCommentCreateRequestDto.builder() + .content("커뮤니티 대댓글 테스트 내용") + .parentCommentId(commentId) + .build(); //when - Long commentId = createCommunityCommentService.CreateCommunityComment(dto, writerId, 2L); + Long replyCommentId = createCommunityCommentService.createCommunityComment(replyDto, writerId); //then - Optional communityComment = communityCommentRepository.findById(commentId); + Optional communityCommentReply = communityCommentRepository.findById(replyCommentId); - assertThat(communityComment).isPresent(); - assertThat(communityComment.get().getId()).isEqualTo(commentId); - assertThat(communityComment.get().getWriterId()).isEqualTo(writerId); - assertThat(communityComment.get().getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); - assertThat(communityComment.get().getParentCommentId()).isEqualTo(2L); + assertThat(communityCommentReply).isPresent(); + assertThat(communityCommentReply.get().getId()).isEqualTo(replyCommentId); + assertThat(communityCommentReply.get().getWriterId()).isEqualTo(writerId); + assertThat(communityCommentReply.get().getContent()).isEqualTo("커뮤니티 대댓글 테스트 내용"); + assertThat(communityCommentReply.get().getParentCommentId()).isEqualTo(commentId); + } + + @DisplayName("삭제된 댓글에 대댓글을 등록할 때 예외를 던진다.") + @Test + void createCommunityCommentRelyWithDeletedParentId() { + + //given + CommunityCommentCreateRequestDto replyDto = CommunityCommentCreateRequestDto.builder() + .content("커뮤니티 대댓글 테스트 내용") + .parentCommentId(2L) + .build(); + + //when + ThrowableAssert.ThrowingCallable callable = () -> createCommunityCommentService.createCommunityComment(replyDto, UUID.randomUUID()); + + //then + assertThatExceptionOfType(BadRequestException.class) + .isThrownBy(callable) + .withMessage(ExceptionMessage.NOT_EXISTS_COMMUNITY_COMMENT.getMessage()); } } From f265514074a4678634717c5de3a4837a5943ef15 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 16:07:57 +0900 Subject: [PATCH 09/25] =?UTF-8?q?chore(community):=20=EC=86=8C=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EB=A1=9C=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/somemore/community/domain/CommunityComment.java | 2 +- .../usecase/comment/CreateCommunityCommentUseCase.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/somemore/community/domain/CommunityComment.java b/src/main/java/com/somemore/community/domain/CommunityComment.java index a55f8cdb8..8e92e1884 100644 --- a/src/main/java/com/somemore/community/domain/CommunityComment.java +++ b/src/main/java/com/somemore/community/domain/CommunityComment.java @@ -14,7 +14,7 @@ @Getter @NoArgsConstructor(access = PROTECTED) @Entity -@Table(name = "Community_comment") +@Table(name = "community_comment") public class CommunityComment extends BaseEntity { @Id diff --git a/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java b/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java index 823d3acce..3def6667f 100644 --- a/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java +++ b/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java @@ -5,8 +5,7 @@ import java.util.UUID; public interface CreateCommunityCommentUseCase { - Long CreateCommunityComment( + Long createCommunityComment( CommunityCommentCreateRequestDto requestDto, - UUID writerId, - Long parentCommunityId); + UUID writerId); } From 10a0dbbcf6b091e22be065d4180bb741994a0726 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 16:08:59 +0900 Subject: [PATCH 10/25] =?UTF-8?q?fix(community):=20=EC=BB=A4=EB=AE=A4?= =?UTF-8?q?=EB=8B=88=ED=8B=B0=20=EB=8C=93=EA=B8=80=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?requestDto=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - parentCommentId Dto 필드로 수정 --- .../dto/request/CommunityCommentCreateRequestDto.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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 b15202fd4..4366779a0 100644 --- a/src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java +++ b/src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.somemore.community.domain.CommunityComment; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotBlank; import lombok.Builder; @@ -14,9 +15,12 @@ public record CommunityCommentCreateRequestDto( @Schema(description = "커뮤니티 댓글 내용", example = "저도 함께 하고 싶습니다.") @NotBlank(message = "댓글 내용은 필수 값입니다.") - String content + String content, + @Schema(description = "부모 댓글의 ID", example = "1234", nullable = true) + @Nullable + Long parentCommentId ) { - public CommunityComment toEntity(UUID writerId, Long parentCommentId) { + public CommunityComment toEntity(UUID writerId) { return CommunityComment.builder() .writerId(writerId) .content(content) From 3151a8b2d9b89bf4c8f5e9fea5fb2140ed1a0b37 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 16:09:39 +0900 Subject: [PATCH 11/25] =?UTF-8?q?feat(community):=20=EC=BB=A4=EB=AE=A4?= =?UTF-8?q?=EB=8B=88=ED=8B=B0=20=EB=8C=93=EA=B8=80=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=EB=B0=8F=20=EB=A9=94?= =?UTF-8?q?=EC=84=B8=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/CreateCommunityCommentService.java | 14 ++++++++++---- .../global/exception/ExceptionMessage.java | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) 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 95ea80e9a..250d56d8d 100644 --- a/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java +++ b/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java @@ -4,12 +4,15 @@ import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; import com.somemore.community.repository.comment.CommunityCommentRepository; import com.somemore.community.usecase.comment.CreateCommunityCommentUseCase; +import com.somemore.global.exception.BadRequestException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.UUID; +import static com.somemore.global.exception.ExceptionMessage.NOT_EXISTS_COMMUNITY_COMMENT; + @RequiredArgsConstructor @Transactional @Service @@ -18,12 +21,15 @@ public class CreateCommunityCommentService implements CreateCommunityCommentUseC private final CommunityCommentRepository communityCommentRepository; @Override - public Long CreateCommunityComment(CommunityCommentCreateRequestDto requestDto, UUID writerId, Long parentCommunityId) { + public Long createCommunityComment(CommunityCommentCreateRequestDto requestDto, UUID writerId) { - CommunityComment communityComment = requestDto.toEntity(writerId, parentCommunityId); + CommunityComment communityComment = requestDto.toEntity(writerId); - communityCommentRepository.save(communityComment); + if (communityComment.getParentCommentId() != null) { + communityCommentRepository.findById(communityComment.getParentCommentId()) + .orElseThrow(() -> new BadRequestException(NOT_EXISTS_COMMUNITY_COMMENT.getMessage())); + } - return communityComment.getId(); + return communityCommentRepository.save(communityComment).getId(); } } diff --git a/src/main/java/com/somemore/global/exception/ExceptionMessage.java b/src/main/java/com/somemore/global/exception/ExceptionMessage.java index 2c3b040c7..3a10ed541 100644 --- a/src/main/java/com/somemore/global/exception/ExceptionMessage.java +++ b/src/main/java/com/somemore/global/exception/ExceptionMessage.java @@ -11,6 +11,7 @@ public enum ExceptionMessage { NOT_EXISTS_CENTER("존재하지 않는 기관 ID 입니다."), NOT_EXISTS_COMMUNITY_BOARD("존재하지 않는 게시글 입니다."), UNAUTHORIZED_COMMUNITY_BOARD("해당 게시글에 권한이 없습니다."), + NOT_EXISTS_COMMUNITY_COMMENT("존재하지 않는 댓글 입니다."), NOT_EXISTS_LOCATION("존재하지 않는 위치 ID 입니다."), NOT_EXISTS_RECRUIT_BOARD("존재하지 않는 봉사 모집글 ID 입니다."), UNAUTHORIZED_RECRUIT_BOARD("자신이 작성한 봉사 모집글이 아닙니다."), From 21e7a2a78a7dc1b2c17df37a1844e0fd308a9f02 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 16:37:59 +0900 Subject: [PATCH 12/25] =?UTF-8?q?refactor(community):=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ServiceTest 오타 수정 - validateParentCommentExists 메서드 추출 --- .../comment/CreateCommunityCommentService.java | 14 +++++++++----- .../comment/CreateCommunityCommentServiceTest.java | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) 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 250d56d8d..92e49f001 100644 --- a/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java +++ b/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java @@ -22,14 +22,18 @@ public class CreateCommunityCommentService implements CreateCommunityCommentUseC @Override public Long createCommunityComment(CommunityCommentCreateRequestDto requestDto, UUID writerId) { - CommunityComment communityComment = requestDto.toEntity(writerId); - if (communityComment.getParentCommentId() != null) { - communityCommentRepository.findById(communityComment.getParentCommentId()) - .orElseThrow(() -> new BadRequestException(NOT_EXISTS_COMMUNITY_COMMENT.getMessage())); - } + validateParentCommentExists(communityComment.getParentCommentId()); return communityCommentRepository.save(communityComment).getId(); } + + private void validateParentCommentExists(Long parentCommentId) { + if (parentCommentId != null) { + communityCommentRepository.findById(parentCommentId) + .orElseThrow(() -> new BadRequestException(NOT_EXISTS_COMMUNITY_COMMENT.getMessage())); + } + } + } 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 36350d830..bc955770c 100644 --- a/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java +++ b/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java @@ -88,7 +88,7 @@ void createCommunityCommentRelyWithDto() { @DisplayName("삭제된 댓글에 대댓글을 등록할 때 예외를 던진다.") @Test - void createCommunityCommentRelyWithDeletedParentId() { + void createCommunityCommentReplyWithDeletedParentId() { //given CommunityCommentCreateRequestDto replyDto = CommunityCommentCreateRequestDto.builder() From c5d8e3c5c8f0059a5a743d9bb2efbf8cdb7b6b99 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 11:25:45 +0900 Subject: [PATCH 13/25] =?UTF-8?q?test(community):=20communityComment=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommunityCommentRepositoryTest.java | 62 +++++++++++++++ .../CreateCommunityCommentServiceTest.java | 76 +++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java create mode 100644 src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java diff --git a/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java b/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java new file mode 100644 index 000000000..21142d6b2 --- /dev/null +++ b/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java @@ -0,0 +1,62 @@ +package com.somemore.community.repository; + +import com.somemore.IntegrationTestSupport; +import com.somemore.community.domain.CommunityComment; +import com.somemore.community.repository.comment.CommunityCommentRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +@Transactional +public class CommunityCommentRepositoryTest extends IntegrationTestSupport { + @Autowired + CommunityCommentRepository communityCommentRepository; + + @DisplayName("커뮤니티 게시글에 댓글을 생성할 수 있다. (Repository)") + @Test + void createCommunityComment() { + + //given + UUID writerId = UUID.randomUUID(); + + CommunityComment communityComment = CommunityComment.builder() + .writerId(writerId) + .content("커뮤니티 댓글 테스트 내용") + .parentCommentId(null) + .build(); + + //when + CommunityComment savedComment = communityCommentRepository.save(communityComment); + + //then + assertThat(savedComment.getWriterId()).isEqualTo(writerId); + assertThat(savedComment.getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); + assertThat(savedComment.getParentCommentId()).isNull(); + } + + @DisplayName("커뮤니티 게시글에 대댓글을 생성할 수 있다. (Repository)") + @Test + void createCommunityCommentReply() { + + //given + UUID writerId = UUID.randomUUID(); + + CommunityComment communityComment = CommunityComment.builder() + .writerId(writerId) + .content("커뮤니티 댓글 테스트 내용") + .parentCommentId(1L) + .build(); + + //when + CommunityComment savedComment = communityCommentRepository.save(communityComment); + + //then + assertThat(savedComment.getWriterId()).isEqualTo(writerId); + assertThat(savedComment.getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); + assertThat(savedComment.getParentCommentId()).isEqualTo(1L); + } +} diff --git a/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java b/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java new file mode 100644 index 000000000..2aab170de --- /dev/null +++ b/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java @@ -0,0 +1,76 @@ +package com.somemore.community.service.comment; + +import com.somemore.IntegrationTestSupport; +import com.somemore.community.domain.CommunityComment; +import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; +import com.somemore.community.repository.comment.CommunityCommentRepository; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Optional; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CreateCommunityCommentServiceTest extends IntegrationTestSupport { + + @Autowired + private CreateCommunityCommentService createCommunityCommentService; + @Autowired + private CommunityCommentRepository communityCommentRepository; + + @AfterEach + void tearDown() { + communityCommentRepository.deleteAllInBatch(); + } + + @DisplayName("커뮤니티 게시글에 댓글을 등록한다.") + @Test + void createCommunityCommentWithDto() { + + //given + CommunityCommentCreateRequestDto dto = CommunityCommentCreateRequestDto.builder() + .content("커뮤니티 댓글 테스트 내용") + .build(); + + UUID writerId = UUID.randomUUID(); + + //when + Long commentId = createCommunityCommentService.CreateCommunityComment(dto, writerId, null); + + //then + Optional communityComment = communityCommentRepository.findById(commentId); + + assertThat(communityComment).isPresent(); + assertThat(communityComment.get().getId()).isEqualTo(commentId); + assertThat(communityComment.get().getWriterId()).isEqualTo(writerId); + assertThat(communityComment.get().getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); + assertThat(communityComment.get().getParentCommentId()).isNull(); + } + + @DisplayName("커뮤니티 게시글에 대댓글을 등록한다.") + @Test + void createCommunityCommenReplytWithDto() { + + //given + CommunityCommentCreateRequestDto dto = CommunityCommentCreateRequestDto.builder() + .content("커뮤니티 댓글 테스트 내용") + .build(); + + UUID writerId = UUID.randomUUID(); + + //when + Long commentId = createCommunityCommentService.CreateCommunityComment(dto, writerId, 2L); + + //then + Optional communityComment = communityCommentRepository.findById(commentId); + + assertThat(communityComment).isPresent(); + assertThat(communityComment.get().getId()).isEqualTo(commentId); + assertThat(communityComment.get().getWriterId()).isEqualTo(writerId); + assertThat(communityComment.get().getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); + assertThat(communityComment.get().getParentCommentId()).isEqualTo(2L); + } +} From dbaf67e5dd3b91a2de23c21d954ab48e55c4e1ee Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 11:28:03 +0900 Subject: [PATCH 14/25] =?UTF-8?q?feat(community):=20communityComment=20Ent?= =?UTF-8?q?ity,=20Repository=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../community/domain/CommunityComment.java | 41 +++++++++++++++++++ .../CommunityCommentJpaRepository.java | 7 ++++ .../comment/CommunityCommentRepository.java | 11 +++++ .../CommunityCommentRepositoryImpl.java | 37 +++++++++++++++++ .../somemore/domains/CommunityComment.java | 28 ------------- 5 files changed, 96 insertions(+), 28 deletions(-) create mode 100644 src/main/java/com/somemore/community/domain/CommunityComment.java create mode 100644 src/main/java/com/somemore/community/repository/comment/CommunityCommentJpaRepository.java create mode 100644 src/main/java/com/somemore/community/repository/comment/CommunityCommentRepository.java create mode 100644 src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java delete mode 100644 src/main/java/com/somemore/domains/CommunityComment.java diff --git a/src/main/java/com/somemore/community/domain/CommunityComment.java b/src/main/java/com/somemore/community/domain/CommunityComment.java new file mode 100644 index 000000000..a55f8cdb8 --- /dev/null +++ b/src/main/java/com/somemore/community/domain/CommunityComment.java @@ -0,0 +1,41 @@ +package com.somemore.community.domain; + +import com.somemore.global.common.BaseEntity; +import jakarta.persistence.*; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +import static lombok.AccessLevel.PROTECTED; + + +@Getter +@NoArgsConstructor(access = PROTECTED) +@Entity +@Table(name = "Community_comment") +public class CommunityComment extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", nullable = false) + private Long id; + + @Column(name = "writer_id", nullable = false, length = 16) + private UUID writerId; + + @Lob + @Column(name = "content", nullable = false) + private String content; + + @Column(name = "parent_comment_id") + private Long parentCommentId; + + @Builder + public CommunityComment(UUID writerId, String content, Long parentCommentId) { + this.writerId = writerId; + this.content = content; + this.parentCommentId = parentCommentId; + } +} \ No newline at end of file diff --git a/src/main/java/com/somemore/community/repository/comment/CommunityCommentJpaRepository.java b/src/main/java/com/somemore/community/repository/comment/CommunityCommentJpaRepository.java new file mode 100644 index 000000000..fd02cad53 --- /dev/null +++ b/src/main/java/com/somemore/community/repository/comment/CommunityCommentJpaRepository.java @@ -0,0 +1,7 @@ +package com.somemore.community.repository.comment; + +import com.somemore.community.domain.CommunityComment; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CommunityCommentJpaRepository extends JpaRepository { +} diff --git a/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepository.java b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepository.java new file mode 100644 index 000000000..f38f5af58 --- /dev/null +++ b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepository.java @@ -0,0 +1,11 @@ +package com.somemore.community.repository.comment; + +import com.somemore.community.domain.CommunityComment; + +import java.util.Optional; + +public interface CommunityCommentRepository { + CommunityComment save(CommunityComment communityComment); + Optional findById(Long id); + void deleteAllInBatch(); +} diff --git a/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java new file mode 100644 index 000000000..12da16d85 --- /dev/null +++ b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java @@ -0,0 +1,37 @@ +package com.somemore.community.repository.comment; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import com.somemore.community.domain.CommunityComment; +import com.somemore.community.domain.QCommunityBoard; +import com.somemore.community.domain.QCommunityComment; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@RequiredArgsConstructor +@Repository +public class CommunityCommentRepositoryImpl implements CommunityCommentRepository { + + private final JPAQueryFactory queryFactory; + private final CommunityCommentJpaRepository communityCommentJpaRepository; + + @Override + public CommunityComment save(CommunityComment communityComment) { + return communityCommentJpaRepository.save(communityComment); + } + + @Override + public Optional findById(Long id) { + QCommunityComment communityComment = QCommunityComment.communityComment; + + return Optional.ofNullable(queryFactory + .selectFrom(communityComment) + .where(communityComment.id.eq(id) + .and(communityComment.deleted.eq(false))) + .fetchOne()); + } + + @Override + public void deleteAllInBatch() { communityCommentJpaRepository.deleteAllInBatch(); } +} diff --git a/src/main/java/com/somemore/domains/CommunityComment.java b/src/main/java/com/somemore/domains/CommunityComment.java deleted file mode 100644 index 423975fbd..000000000 --- a/src/main/java/com/somemore/domains/CommunityComment.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.somemore.domains; - -import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; - -import java.util.UUID; - -@Getter -@Setter -@Entity -@Table(name = "Community_comment") -public class CommunityComment { - @Id - @GeneratedValue(strategy = GenerationType.UUID) - private UUID id; - - @Column(name = "writer_id", nullable = false, length = 16) - private String writerId; - - @Lob - @Column(name = "content", nullable = false) - private String content; - - @Column(name = "parent_comment_id") - private Long parentCommentId; - -} \ No newline at end of file From 3c306dcf1862186501fc4d92f1ee0d3bf4fc32a7 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 11:29:06 +0900 Subject: [PATCH 15/25] =?UTF-8?q?feat(community):=20communityComment=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20RequestDto,=20Usecase=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20=EB=B0=8F=20Service=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommunityCommentCreateRequestDto.java | 26 +++++++++++++++++ .../CreateCommunityCommentService.java | 29 +++++++++++++++++++ .../CreateCommunityCommentUseCase.java | 13 +++++++++ 3 files changed, 68 insertions(+) create mode 100644 src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java create mode 100644 src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java create mode 100644 src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java diff --git a/src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java b/src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java new file mode 100644 index 000000000..b15202fd4 --- /dev/null +++ b/src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java @@ -0,0 +1,26 @@ +package com.somemore.community.dto.request; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.somemore.community.domain.CommunityComment; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Builder; + +import java.util.UUID; + +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +@Builder +public record CommunityCommentCreateRequestDto( + @Schema(description = "커뮤니티 댓글 내용", example = "저도 함께 하고 싶습니다.") + @NotBlank(message = "댓글 내용은 필수 값입니다.") + String content +) { + public CommunityComment toEntity(UUID writerId, Long parentCommentId) { + return CommunityComment.builder() + .writerId(writerId) + .content(content) + .parentCommentId(parentCommentId) + .build(); + } +} diff --git a/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java b/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java new file mode 100644 index 000000000..95ea80e9a --- /dev/null +++ b/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java @@ -0,0 +1,29 @@ +package com.somemore.community.service.comment; + +import com.somemore.community.domain.CommunityComment; +import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; +import com.somemore.community.repository.comment.CommunityCommentRepository; +import com.somemore.community.usecase.comment.CreateCommunityCommentUseCase; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.UUID; + +@RequiredArgsConstructor +@Transactional +@Service +public class CreateCommunityCommentService implements CreateCommunityCommentUseCase { + + private final CommunityCommentRepository communityCommentRepository; + + @Override + public Long CreateCommunityComment(CommunityCommentCreateRequestDto requestDto, UUID writerId, Long parentCommunityId) { + + CommunityComment communityComment = requestDto.toEntity(writerId, parentCommunityId); + + communityCommentRepository.save(communityComment); + + return communityComment.getId(); + } +} diff --git a/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java b/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java new file mode 100644 index 000000000..5c6224877 --- /dev/null +++ b/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java @@ -0,0 +1,13 @@ +package com.somemore.community.usecase.comment; + +import com.somemore.community.domain.CommunityComment; +import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; + +import java.util.UUID; + +public interface CreateCommunityCommentUseCase { + Long CreateCommunityComment( + CommunityCommentCreateRequestDto requestDto, + UUID writerId, + Long parentCommunityId); +} From f4a5f6b6f3bf13790d3151a1841d89c7e84d829a Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 11:30:20 +0900 Subject: [PATCH 16/25] =?UTF-8?q?refactor(community):=20CommunityBoardRepo?= =?UTF-8?q?sitory=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommunityBoardRepositoryImpl.java} | 4 ++-- ...yRepositoryTest.java => CommunityBoardRepositoryTest.java} | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) rename src/main/java/com/somemore/community/repository/{CommunityRepositoryImpl.java => board/CommunityBoardRepositoryImpl.java} (94%) rename src/test/java/com/somemore/community/repository/{CommunityRepositoryTest.java => CommunityBoardRepositoryTest.java} (98%) diff --git a/src/main/java/com/somemore/community/repository/CommunityRepositoryImpl.java b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java similarity index 94% rename from src/main/java/com/somemore/community/repository/CommunityRepositoryImpl.java rename to src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java index 26ec5360e..ad1d79924 100644 --- a/src/main/java/com/somemore/community/repository/CommunityRepositoryImpl.java +++ b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java @@ -1,4 +1,4 @@ -package com.somemore.community.repository; +package com.somemore.community.repository.board; import com.querydsl.core.types.Projections; import com.querydsl.jpa.impl.JPAQuery; @@ -16,7 +16,7 @@ @RequiredArgsConstructor @Repository -public class CommunityRepositoryImpl implements CommunityBoardRepository { +public class CommunityBoardRepositoryImpl implements CommunityBoardRepository { private final JPAQueryFactory queryFactory; private final CommunityBoardJpaRepository communityBoardJpaRepository; diff --git a/src/test/java/com/somemore/community/repository/CommunityRepositoryTest.java b/src/test/java/com/somemore/community/repository/CommunityBoardRepositoryTest.java similarity index 98% rename from src/test/java/com/somemore/community/repository/CommunityRepositoryTest.java rename to src/test/java/com/somemore/community/repository/CommunityBoardRepositoryTest.java index f39083074..2f6fdbd52 100644 --- a/src/test/java/com/somemore/community/repository/CommunityRepositoryTest.java +++ b/src/test/java/com/somemore/community/repository/CommunityBoardRepositoryTest.java @@ -4,6 +4,7 @@ import com.somemore.auth.oauth.OAuthProvider; import com.somemore.community.domain.CommunityBoard; import com.somemore.community.domain.CommunityBoardView; +import com.somemore.community.repository.board.CommunityBoardRepository; import com.somemore.volunteer.domain.Volunteer; import com.somemore.volunteer.repository.VolunteerRepository; import org.junit.jupiter.api.DisplayName; @@ -18,7 +19,7 @@ import static org.assertj.core.api.Assertions.assertThat; @Transactional -class CommunityRepositoryTest extends IntegrationTestSupport { +class CommunityBoardRepositoryTest extends IntegrationTestSupport { @Autowired private CommunityBoardRepository communityBoardRepository; From 0f23e4a64ac078a84b6fe8ce8f1d9284c54cc7c7 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 11:30:41 +0900 Subject: [PATCH 17/25] =?UTF-8?q?refactor(community):=20community=20board/?= =?UTF-8?q?comment=20=ED=8F=B4=EB=8D=94=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{ => board}/CommunityBoardJpaRepository.java | 2 +- .../repository/{ => board}/CommunityBoardRepository.java | 2 +- .../service/{ => board}/CommunityBoardQueryService.java | 6 +++--- .../service/{ => board}/CreateCommunityBoardService.java | 6 +++--- .../service/{ => board}/DeleteCommunityBoardService.java | 6 +++--- .../service/{ => board}/UpdateCommunityBoardService.java | 6 +++--- .../usecase/{ => board}/CommunityBoardQueryUseCase.java | 2 +- .../usecase/{ => board}/CreateCommunityBoardUseCase.java | 2 +- .../usecase/{ => board}/DeleteCommunityBoardUseCase.java | 2 +- .../usecase/{ => board}/UpdateCommunityBoardUseCase.java | 2 +- .../{ => board}/CommunityBoardQueryServiceTest.java | 8 ++++---- .../{ => board}/CreateCommunityBoardServiceTest.java | 4 ++-- .../{ => board}/DeleteCommunityBoardServiceTest.java | 8 ++++---- .../{ => board}/UpdateCommunityBoardServiceTest.java | 6 +++--- 14 files changed, 31 insertions(+), 31 deletions(-) rename src/main/java/com/somemore/community/repository/{ => board}/CommunityBoardJpaRepository.java (81%) rename src/main/java/com/somemore/community/repository/{ => board}/CommunityBoardRepository.java (90%) rename src/main/java/com/somemore/community/service/{ => board}/CommunityBoardQueryService.java (91%) rename src/main/java/com/somemore/community/service/{ => board}/CreateCommunityBoardService.java (81%) rename src/main/java/com/somemore/community/service/{ => board}/DeleteCommunityBoardService.java (88%) rename src/main/java/com/somemore/community/service/{ => board}/UpdateCommunityBoardService.java (88%) rename src/main/java/com/somemore/community/usecase/{ => board}/CommunityBoardQueryUseCase.java (91%) rename src/main/java/com/somemore/community/usecase/{ => board}/CreateCommunityBoardUseCase.java (85%) rename src/main/java/com/somemore/community/usecase/{ => board}/DeleteCommunityBoardUseCase.java (73%) rename src/main/java/com/somemore/community/usecase/{ => board}/UpdateCommunityBoardUseCase.java (87%) rename src/test/java/com/somemore/community/service/{ => board}/CommunityBoardQueryServiceTest.java (96%) rename src/test/java/com/somemore/community/service/{ => board}/CreateCommunityBoardServiceTest.java (96%) rename src/test/java/com/somemore/community/service/{ => board}/DeleteCommunityBoardServiceTest.java (92%) rename src/test/java/com/somemore/community/service/{ => board}/UpdateCommunityBoardServiceTest.java (95%) diff --git a/src/main/java/com/somemore/community/repository/CommunityBoardJpaRepository.java b/src/main/java/com/somemore/community/repository/board/CommunityBoardJpaRepository.java similarity index 81% rename from src/main/java/com/somemore/community/repository/CommunityBoardJpaRepository.java rename to src/main/java/com/somemore/community/repository/board/CommunityBoardJpaRepository.java index ce59211b9..79b03cd1c 100644 --- a/src/main/java/com/somemore/community/repository/CommunityBoardJpaRepository.java +++ b/src/main/java/com/somemore/community/repository/board/CommunityBoardJpaRepository.java @@ -1,4 +1,4 @@ -package com.somemore.community.repository; +package com.somemore.community.repository.board; import com.somemore.community.domain.CommunityBoard; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/com/somemore/community/repository/CommunityBoardRepository.java b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepository.java similarity index 90% rename from src/main/java/com/somemore/community/repository/CommunityBoardRepository.java rename to src/main/java/com/somemore/community/repository/board/CommunityBoardRepository.java index f7df7bbd5..3340735a5 100644 --- a/src/main/java/com/somemore/community/repository/CommunityBoardRepository.java +++ b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepository.java @@ -1,4 +1,4 @@ -package com.somemore.community.repository; +package com.somemore.community.repository.board; import com.somemore.community.domain.CommunityBoard; import com.somemore.community.domain.CommunityBoardView; diff --git a/src/main/java/com/somemore/community/service/CommunityBoardQueryService.java b/src/main/java/com/somemore/community/service/board/CommunityBoardQueryService.java similarity index 91% rename from src/main/java/com/somemore/community/service/CommunityBoardQueryService.java rename to src/main/java/com/somemore/community/service/board/CommunityBoardQueryService.java index e451949ff..98d45143f 100644 --- a/src/main/java/com/somemore/community/service/CommunityBoardQueryService.java +++ b/src/main/java/com/somemore/community/service/board/CommunityBoardQueryService.java @@ -1,11 +1,11 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import com.somemore.community.domain.CommunityBoard; import com.somemore.community.domain.CommunityBoardView; import com.somemore.community.dto.response.CommunityBoardGetDetailResponseDto; import com.somemore.community.dto.response.CommunityBoardGetResponseDto; -import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.CommunityBoardQueryUseCase; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.community.usecase.board.CommunityBoardQueryUseCase; import com.somemore.global.exception.BadRequestException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/somemore/community/service/CreateCommunityBoardService.java b/src/main/java/com/somemore/community/service/board/CreateCommunityBoardService.java similarity index 81% rename from src/main/java/com/somemore/community/service/CreateCommunityBoardService.java rename to src/main/java/com/somemore/community/service/board/CreateCommunityBoardService.java index 07ad1d456..61bcf1767 100644 --- a/src/main/java/com/somemore/community/service/CreateCommunityBoardService.java +++ b/src/main/java/com/somemore/community/service/board/CreateCommunityBoardService.java @@ -1,9 +1,9 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import com.somemore.community.domain.CommunityBoard; import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; -import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.CreateCommunityBoardUseCase; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.community.usecase.board.CreateCommunityBoardUseCase; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/com/somemore/community/service/DeleteCommunityBoardService.java b/src/main/java/com/somemore/community/service/board/DeleteCommunityBoardService.java similarity index 88% rename from src/main/java/com/somemore/community/service/DeleteCommunityBoardService.java rename to src/main/java/com/somemore/community/service/board/DeleteCommunityBoardService.java index 79c735bf9..ed9ff1424 100644 --- a/src/main/java/com/somemore/community/service/DeleteCommunityBoardService.java +++ b/src/main/java/com/somemore/community/service/board/DeleteCommunityBoardService.java @@ -1,8 +1,8 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import com.somemore.community.domain.CommunityBoard; -import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.DeleteCommunityBoardUseCase; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.community.usecase.board.DeleteCommunityBoardUseCase; import com.somemore.global.exception.BadRequestException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/somemore/community/service/UpdateCommunityBoardService.java b/src/main/java/com/somemore/community/service/board/UpdateCommunityBoardService.java similarity index 88% rename from src/main/java/com/somemore/community/service/UpdateCommunityBoardService.java rename to src/main/java/com/somemore/community/service/board/UpdateCommunityBoardService.java index ef3f96c36..89a5dfb84 100644 --- a/src/main/java/com/somemore/community/service/UpdateCommunityBoardService.java +++ b/src/main/java/com/somemore/community/service/board/UpdateCommunityBoardService.java @@ -1,9 +1,9 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import com.somemore.community.domain.CommunityBoard; import com.somemore.community.dto.request.CommunityBoardUpdateRequestDto; -import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.UpdateCommunityBoardUseCase; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.community.usecase.board.UpdateCommunityBoardUseCase; import com.somemore.global.exception.BadRequestException; import java.util.UUID; diff --git a/src/main/java/com/somemore/community/usecase/CommunityBoardQueryUseCase.java b/src/main/java/com/somemore/community/usecase/board/CommunityBoardQueryUseCase.java similarity index 91% rename from src/main/java/com/somemore/community/usecase/CommunityBoardQueryUseCase.java rename to src/main/java/com/somemore/community/usecase/board/CommunityBoardQueryUseCase.java index 2b4da6312..70987a033 100644 --- a/src/main/java/com/somemore/community/usecase/CommunityBoardQueryUseCase.java +++ b/src/main/java/com/somemore/community/usecase/board/CommunityBoardQueryUseCase.java @@ -1,4 +1,4 @@ -package com.somemore.community.usecase; +package com.somemore.community.usecase.board; import com.somemore.community.dto.response.CommunityBoardGetDetailResponseDto; import com.somemore.community.dto.response.CommunityBoardGetResponseDto; diff --git a/src/main/java/com/somemore/community/usecase/CreateCommunityBoardUseCase.java b/src/main/java/com/somemore/community/usecase/board/CreateCommunityBoardUseCase.java similarity index 85% rename from src/main/java/com/somemore/community/usecase/CreateCommunityBoardUseCase.java rename to src/main/java/com/somemore/community/usecase/board/CreateCommunityBoardUseCase.java index 2e0c3828f..6df8878da 100644 --- a/src/main/java/com/somemore/community/usecase/CreateCommunityBoardUseCase.java +++ b/src/main/java/com/somemore/community/usecase/board/CreateCommunityBoardUseCase.java @@ -1,4 +1,4 @@ -package com.somemore.community.usecase; +package com.somemore.community.usecase.board; import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; diff --git a/src/main/java/com/somemore/community/usecase/DeleteCommunityBoardUseCase.java b/src/main/java/com/somemore/community/usecase/board/DeleteCommunityBoardUseCase.java similarity index 73% rename from src/main/java/com/somemore/community/usecase/DeleteCommunityBoardUseCase.java rename to src/main/java/com/somemore/community/usecase/board/DeleteCommunityBoardUseCase.java index d2f26500e..345936db9 100644 --- a/src/main/java/com/somemore/community/usecase/DeleteCommunityBoardUseCase.java +++ b/src/main/java/com/somemore/community/usecase/board/DeleteCommunityBoardUseCase.java @@ -1,4 +1,4 @@ -package com.somemore.community.usecase; +package com.somemore.community.usecase.board; import java.util.UUID; diff --git a/src/main/java/com/somemore/community/usecase/UpdateCommunityBoardUseCase.java b/src/main/java/com/somemore/community/usecase/board/UpdateCommunityBoardUseCase.java similarity index 87% rename from src/main/java/com/somemore/community/usecase/UpdateCommunityBoardUseCase.java rename to src/main/java/com/somemore/community/usecase/board/UpdateCommunityBoardUseCase.java index e8690b283..4014f5fe3 100644 --- a/src/main/java/com/somemore/community/usecase/UpdateCommunityBoardUseCase.java +++ b/src/main/java/com/somemore/community/usecase/board/UpdateCommunityBoardUseCase.java @@ -1,4 +1,4 @@ -package com.somemore.community.usecase; +package com.somemore.community.usecase.board; import com.somemore.community.dto.request.CommunityBoardUpdateRequestDto; diff --git a/src/test/java/com/somemore/community/service/CommunityBoardQueryServiceTest.java b/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java similarity index 96% rename from src/test/java/com/somemore/community/service/CommunityBoardQueryServiceTest.java rename to src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java index 3d82d4281..e8c72be10 100644 --- a/src/test/java/com/somemore/community/service/CommunityBoardQueryServiceTest.java +++ b/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java @@ -1,4 +1,4 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import com.somemore.IntegrationTestSupport; import com.somemore.auth.oauth.OAuthProvider; @@ -7,9 +7,9 @@ import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; import com.somemore.community.dto.response.CommunityBoardGetDetailResponseDto; import com.somemore.community.dto.response.CommunityBoardGetResponseDto; -import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.CreateCommunityBoardUseCase; -import com.somemore.community.usecase.DeleteCommunityBoardUseCase; +import com.somemore.community.repository.board.CommunityBoardRepository; +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 com.somemore.volunteer.domain.Volunteer; diff --git a/src/test/java/com/somemore/community/service/CreateCommunityBoardServiceTest.java b/src/test/java/com/somemore/community/service/board/CreateCommunityBoardServiceTest.java similarity index 96% rename from src/test/java/com/somemore/community/service/CreateCommunityBoardServiceTest.java rename to src/test/java/com/somemore/community/service/board/CreateCommunityBoardServiceTest.java index d373da46a..ec9db956b 100644 --- a/src/test/java/com/somemore/community/service/CreateCommunityBoardServiceTest.java +++ b/src/test/java/com/somemore/community/service/board/CreateCommunityBoardServiceTest.java @@ -1,11 +1,11 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import static org.assertj.core.api.Assertions.assertThat; import com.somemore.IntegrationTestSupport; import com.somemore.community.domain.CommunityBoard; import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; -import com.somemore.community.repository.CommunityBoardRepository; +import com.somemore.community.repository.board.CommunityBoardRepository; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/somemore/community/service/DeleteCommunityBoardServiceTest.java b/src/test/java/com/somemore/community/service/board/DeleteCommunityBoardServiceTest.java similarity index 92% rename from src/test/java/com/somemore/community/service/DeleteCommunityBoardServiceTest.java rename to src/test/java/com/somemore/community/service/board/DeleteCommunityBoardServiceTest.java index e72667431..8cc6a566e 100644 --- a/src/test/java/com/somemore/community/service/DeleteCommunityBoardServiceTest.java +++ b/src/test/java/com/somemore/community/service/board/DeleteCommunityBoardServiceTest.java @@ -1,13 +1,13 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import com.somemore.IntegrationTestSupport; import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; -import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.CreateCommunityBoardUseCase; -import com.somemore.community.usecase.CommunityBoardQueryUseCase; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.community.usecase.board.CreateCommunityBoardUseCase; +import com.somemore.community.usecase.board.CommunityBoardQueryUseCase; import com.somemore.global.exception.BadRequestException; import com.somemore.global.exception.ExceptionMessage; import org.assertj.core.api.ThrowableAssert; diff --git a/src/test/java/com/somemore/community/service/UpdateCommunityBoardServiceTest.java b/src/test/java/com/somemore/community/service/board/UpdateCommunityBoardServiceTest.java similarity index 95% rename from src/test/java/com/somemore/community/service/UpdateCommunityBoardServiceTest.java rename to src/test/java/com/somemore/community/service/board/UpdateCommunityBoardServiceTest.java index 06bd1de86..5e7f30264 100644 --- a/src/test/java/com/somemore/community/service/UpdateCommunityBoardServiceTest.java +++ b/src/test/java/com/somemore/community/service/board/UpdateCommunityBoardServiceTest.java @@ -1,4 +1,4 @@ -package com.somemore.community.service; +package com.somemore.community.service.board; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -7,8 +7,8 @@ import com.somemore.community.domain.CommunityBoard; import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; import com.somemore.community.dto.request.CommunityBoardUpdateRequestDto; -import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.CreateCommunityBoardUseCase; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.community.usecase.board.CreateCommunityBoardUseCase; import com.somemore.global.exception.BadRequestException; import com.somemore.global.exception.ExceptionMessage; import org.assertj.core.api.ThrowableAssert; From b43a5e651917252eab2009fef21c97a932a1c9e0 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 11:36:48 +0900 Subject: [PATCH 18/25] =?UTF-8?q?chore(community):=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20import=20=EB=B0=8F=20public=20=ED=82=A4?= =?UTF-8?q?=EC=9B=8C=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/comment/CommunityCommentRepositoryImpl.java | 1 - .../usecase/comment/CreateCommunityCommentUseCase.java | 1 - .../community/repository/CommunityCommentRepositoryTest.java | 2 +- .../service/comment/CreateCommunityCommentServiceTest.java | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java index 12da16d85..9d2cee7ba 100644 --- a/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java +++ b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java @@ -2,7 +2,6 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import com.somemore.community.domain.CommunityComment; -import com.somemore.community.domain.QCommunityBoard; import com.somemore.community.domain.QCommunityComment; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; diff --git a/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java b/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java index 5c6224877..823d3acce 100644 --- a/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java +++ b/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java @@ -1,6 +1,5 @@ package com.somemore.community.usecase.comment; -import com.somemore.community.domain.CommunityComment; import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; import java.util.UUID; diff --git a/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java b/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java index 21142d6b2..4c67544f1 100644 --- a/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java +++ b/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java @@ -12,7 +12,7 @@ import static org.assertj.core.api.Assertions.assertThat; @Transactional -public class CommunityCommentRepositoryTest extends IntegrationTestSupport { +class CommunityCommentRepositoryTest extends IntegrationTestSupport { @Autowired CommunityCommentRepository communityCommentRepository; 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 2aab170de..f0676adb2 100644 --- a/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java +++ b/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java @@ -14,7 +14,7 @@ import static org.assertj.core.api.Assertions.assertThat; -public class CreateCommunityCommentServiceTest extends IntegrationTestSupport { +class CreateCommunityCommentServiceTest extends IntegrationTestSupport { @Autowired private CreateCommunityCommentService createCommunityCommentService; From 7835bb2e31c80eb38f73989771d478c2c08d3600 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 16:06:48 +0900 Subject: [PATCH 19/25] =?UTF-8?q?test(community):=20=EC=BB=A4=EB=AE=A4?= =?UTF-8?q?=EB=8B=88=ED=8B=B0=20=EB=8C=93=EA=B8=80=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - repository 테스트에 findById 테스트 추가 - service 테스트에 대댓글 예외 테스트 추가 --- .../CommunityCommentRepositoryTest.java | 29 +++++++++- .../CreateCommunityCommentServiceTest.java | 53 +++++++++++++++---- 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java b/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java index 4c67544f1..0f0625189 100644 --- a/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java +++ b/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java @@ -7,6 +7,8 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; @@ -38,7 +40,7 @@ void createCommunityComment() { assertThat(savedComment.getParentCommentId()).isNull(); } - @DisplayName("커뮤니티 게시글에 대댓글을 생성할 수 있다. (Repository)") + @DisplayName("댓글에 대댓글을 생성할 수 있다. (Repository)") @Test void createCommunityCommentReply() { @@ -59,4 +61,29 @@ void createCommunityCommentReply() { assertThat(savedComment.getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); assertThat(savedComment.getParentCommentId()).isEqualTo(1L); } + + @DisplayName("댓글을 id로 조회할 수 있다. (Repository)") + @Test + void findCommunityCommentById() { + + //given + UUID writerId = UUID.randomUUID(); + + CommunityComment communityComment = CommunityComment.builder() + .writerId(writerId) + .content("커뮤니티 댓글 테스트 내용") + .parentCommentId(null) + .build(); + + CommunityComment savedComment = communityCommentRepository.save(communityComment); + + //when + Optional comment = communityCommentRepository.findById(savedComment.getId()); + + //then + assertThat(comment).isPresent(); + assertThat(comment.get().getWriterId()).isEqualTo(writerId); + assertThat(comment.get().getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); + assertThat(comment.get().getParentCommentId()).isNull(); + } } 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 f0676adb2..36350d830 100644 --- a/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java +++ b/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java @@ -4,6 +4,9 @@ import com.somemore.community.domain.CommunityComment; import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; import com.somemore.community.repository.comment.CommunityCommentRepository; +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.DisplayName; import org.junit.jupiter.api.Test; @@ -13,6 +16,7 @@ import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; class CreateCommunityCommentServiceTest extends IntegrationTestSupport { @@ -33,12 +37,13 @@ void createCommunityCommentWithDto() { //given CommunityCommentCreateRequestDto dto = CommunityCommentCreateRequestDto.builder() .content("커뮤니티 댓글 테스트 내용") + .parentCommentId(null) .build(); UUID writerId = UUID.randomUUID(); //when - Long commentId = createCommunityCommentService.CreateCommunityComment(dto, writerId, null); + Long commentId = createCommunityCommentService.createCommunityComment(dto, writerId); //then Optional communityComment = communityCommentRepository.findById(commentId); @@ -50,27 +55,53 @@ void createCommunityCommentWithDto() { assertThat(communityComment.get().getParentCommentId()).isNull(); } - @DisplayName("커뮤니티 게시글에 대댓글을 등록한다.") + @DisplayName("댓글에 대댓글을 등록한다.") @Test - void createCommunityCommenReplytWithDto() { + void createCommunityCommentRelyWithDto() { //given - CommunityCommentCreateRequestDto dto = CommunityCommentCreateRequestDto.builder() + CommunityCommentCreateRequestDto commentDto = CommunityCommentCreateRequestDto.builder() .content("커뮤니티 댓글 테스트 내용") + .parentCommentId(null) .build(); UUID writerId = UUID.randomUUID(); + Long commentId = createCommunityCommentService.createCommunityComment(commentDto, writerId); + + CommunityCommentCreateRequestDto replyDto = CommunityCommentCreateRequestDto.builder() + .content("커뮤니티 대댓글 테스트 내용") + .parentCommentId(commentId) + .build(); //when - Long commentId = createCommunityCommentService.CreateCommunityComment(dto, writerId, 2L); + Long replyCommentId = createCommunityCommentService.createCommunityComment(replyDto, writerId); //then - Optional communityComment = communityCommentRepository.findById(commentId); + Optional communityCommentReply = communityCommentRepository.findById(replyCommentId); - assertThat(communityComment).isPresent(); - assertThat(communityComment.get().getId()).isEqualTo(commentId); - assertThat(communityComment.get().getWriterId()).isEqualTo(writerId); - assertThat(communityComment.get().getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); - assertThat(communityComment.get().getParentCommentId()).isEqualTo(2L); + assertThat(communityCommentReply).isPresent(); + assertThat(communityCommentReply.get().getId()).isEqualTo(replyCommentId); + assertThat(communityCommentReply.get().getWriterId()).isEqualTo(writerId); + assertThat(communityCommentReply.get().getContent()).isEqualTo("커뮤니티 대댓글 테스트 내용"); + assertThat(communityCommentReply.get().getParentCommentId()).isEqualTo(commentId); + } + + @DisplayName("삭제된 댓글에 대댓글을 등록할 때 예외를 던진다.") + @Test + void createCommunityCommentRelyWithDeletedParentId() { + + //given + CommunityCommentCreateRequestDto replyDto = CommunityCommentCreateRequestDto.builder() + .content("커뮤니티 대댓글 테스트 내용") + .parentCommentId(2L) + .build(); + + //when + ThrowableAssert.ThrowingCallable callable = () -> createCommunityCommentService.createCommunityComment(replyDto, UUID.randomUUID()); + + //then + assertThatExceptionOfType(BadRequestException.class) + .isThrownBy(callable) + .withMessage(ExceptionMessage.NOT_EXISTS_COMMUNITY_COMMENT.getMessage()); } } From 6c0def62455e6e25cfc7170773d28b06b7d5da11 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 16:07:57 +0900 Subject: [PATCH 20/25] =?UTF-8?q?chore(community):=20=EC=86=8C=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EB=A1=9C=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/somemore/community/domain/CommunityComment.java | 2 +- .../usecase/comment/CreateCommunityCommentUseCase.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/somemore/community/domain/CommunityComment.java b/src/main/java/com/somemore/community/domain/CommunityComment.java index a55f8cdb8..8e92e1884 100644 --- a/src/main/java/com/somemore/community/domain/CommunityComment.java +++ b/src/main/java/com/somemore/community/domain/CommunityComment.java @@ -14,7 +14,7 @@ @Getter @NoArgsConstructor(access = PROTECTED) @Entity -@Table(name = "Community_comment") +@Table(name = "community_comment") public class CommunityComment extends BaseEntity { @Id diff --git a/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java b/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java index 823d3acce..3def6667f 100644 --- a/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java +++ b/src/main/java/com/somemore/community/usecase/comment/CreateCommunityCommentUseCase.java @@ -5,8 +5,7 @@ import java.util.UUID; public interface CreateCommunityCommentUseCase { - Long CreateCommunityComment( + Long createCommunityComment( CommunityCommentCreateRequestDto requestDto, - UUID writerId, - Long parentCommunityId); + UUID writerId); } From 62aa1e58613aaf5e0ff310636bfe9d6aca8a0bd5 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 16:08:59 +0900 Subject: [PATCH 21/25] =?UTF-8?q?fix(community):=20=EC=BB=A4=EB=AE=A4?= =?UTF-8?q?=EB=8B=88=ED=8B=B0=20=EB=8C=93=EA=B8=80=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?requestDto=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - parentCommentId Dto 필드로 수정 --- .../dto/request/CommunityCommentCreateRequestDto.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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 b15202fd4..4366779a0 100644 --- a/src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java +++ b/src/main/java/com/somemore/community/dto/request/CommunityCommentCreateRequestDto.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.somemore.community.domain.CommunityComment; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotBlank; import lombok.Builder; @@ -14,9 +15,12 @@ public record CommunityCommentCreateRequestDto( @Schema(description = "커뮤니티 댓글 내용", example = "저도 함께 하고 싶습니다.") @NotBlank(message = "댓글 내용은 필수 값입니다.") - String content + String content, + @Schema(description = "부모 댓글의 ID", example = "1234", nullable = true) + @Nullable + Long parentCommentId ) { - public CommunityComment toEntity(UUID writerId, Long parentCommentId) { + public CommunityComment toEntity(UUID writerId) { return CommunityComment.builder() .writerId(writerId) .content(content) From 01656ce4cfd74997e85688371c5e9ddae3d0ffbb Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 16:09:39 +0900 Subject: [PATCH 22/25] =?UTF-8?q?feat(community):=20=EC=BB=A4=EB=AE=A4?= =?UTF-8?q?=EB=8B=88=ED=8B=B0=20=EB=8C=93=EA=B8=80=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=EB=B0=8F=20=EB=A9=94?= =?UTF-8?q?=EC=84=B8=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/CreateCommunityCommentService.java | 14 ++++++++++---- .../global/exception/ExceptionMessage.java | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) 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 95ea80e9a..250d56d8d 100644 --- a/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java +++ b/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java @@ -4,12 +4,15 @@ import com.somemore.community.dto.request.CommunityCommentCreateRequestDto; import com.somemore.community.repository.comment.CommunityCommentRepository; import com.somemore.community.usecase.comment.CreateCommunityCommentUseCase; +import com.somemore.global.exception.BadRequestException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.UUID; +import static com.somemore.global.exception.ExceptionMessage.NOT_EXISTS_COMMUNITY_COMMENT; + @RequiredArgsConstructor @Transactional @Service @@ -18,12 +21,15 @@ public class CreateCommunityCommentService implements CreateCommunityCommentUseC private final CommunityCommentRepository communityCommentRepository; @Override - public Long CreateCommunityComment(CommunityCommentCreateRequestDto requestDto, UUID writerId, Long parentCommunityId) { + public Long createCommunityComment(CommunityCommentCreateRequestDto requestDto, UUID writerId) { - CommunityComment communityComment = requestDto.toEntity(writerId, parentCommunityId); + CommunityComment communityComment = requestDto.toEntity(writerId); - communityCommentRepository.save(communityComment); + if (communityComment.getParentCommentId() != null) { + communityCommentRepository.findById(communityComment.getParentCommentId()) + .orElseThrow(() -> new BadRequestException(NOT_EXISTS_COMMUNITY_COMMENT.getMessage())); + } - return communityComment.getId(); + return communityCommentRepository.save(communityComment).getId(); } } diff --git a/src/main/java/com/somemore/global/exception/ExceptionMessage.java b/src/main/java/com/somemore/global/exception/ExceptionMessage.java index de2ac538b..1e5b3f8b2 100644 --- a/src/main/java/com/somemore/global/exception/ExceptionMessage.java +++ b/src/main/java/com/somemore/global/exception/ExceptionMessage.java @@ -11,6 +11,7 @@ public enum ExceptionMessage { NOT_EXISTS_CENTER("존재하지 않는 기관 ID 입니다."), NOT_EXISTS_COMMUNITY_BOARD("존재하지 않는 게시글 입니다."), UNAUTHORIZED_COMMUNITY_BOARD("해당 게시글에 권한이 없습니다."), + NOT_EXISTS_COMMUNITY_COMMENT("존재하지 않는 댓글 입니다."), NOT_EXISTS_LOCATION("존재하지 않는 위치 ID 입니다."), NOT_EXISTS_RECRUIT_BOARD("존재하지 않는 봉사 모집글 ID 입니다."), UNAUTHORIZED_RECRUIT_BOARD("자신이 작성한 봉사 모집글이 아닙니다."), From b12b77193e4739cfdf901210bccabd0d41a86165 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 16:37:59 +0900 Subject: [PATCH 23/25] =?UTF-8?q?refactor(community):=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ServiceTest 오타 수정 - validateParentCommentExists 메서드 추출 --- .../comment/CreateCommunityCommentService.java | 14 +++++++++----- .../comment/CreateCommunityCommentServiceTest.java | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) 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 250d56d8d..92e49f001 100644 --- a/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java +++ b/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java @@ -22,14 +22,18 @@ public class CreateCommunityCommentService implements CreateCommunityCommentUseC @Override public Long createCommunityComment(CommunityCommentCreateRequestDto requestDto, UUID writerId) { - CommunityComment communityComment = requestDto.toEntity(writerId); - if (communityComment.getParentCommentId() != null) { - communityCommentRepository.findById(communityComment.getParentCommentId()) - .orElseThrow(() -> new BadRequestException(NOT_EXISTS_COMMUNITY_COMMENT.getMessage())); - } + validateParentCommentExists(communityComment.getParentCommentId()); return communityCommentRepository.save(communityComment).getId(); } + + private void validateParentCommentExists(Long parentCommentId) { + if (parentCommentId != null) { + communityCommentRepository.findById(parentCommentId) + .orElseThrow(() -> new BadRequestException(NOT_EXISTS_COMMUNITY_COMMENT.getMessage())); + } + } + } 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 36350d830..bc955770c 100644 --- a/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java +++ b/src/test/java/com/somemore/community/service/comment/CreateCommunityCommentServiceTest.java @@ -88,7 +88,7 @@ void createCommunityCommentRelyWithDto() { @DisplayName("삭제된 댓글에 대댓글을 등록할 때 예외를 던진다.") @Test - void createCommunityCommentRelyWithDeletedParentId() { + void createCommunityCommentReplyWithDeletedParentId() { //given CommunityCommentCreateRequestDto replyDto = CommunityCommentCreateRequestDto.builder() From d1caba655abe2d43d21432759dc87ffc754a161d Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 17:23:48 +0900 Subject: [PATCH 24/25] =?UTF-8?q?feat(community):=20=EC=BB=A4=EB=AE=A4?= =?UTF-8?q?=EB=8B=88=ED=8B=B0=20=EB=8C=93=EA=B8=80=20=EC=A1=B4=EC=9E=AC=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B0=8F=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/CommunityCommentRepository.java | 1 + .../CommunityCommentRepositoryImpl.java | 13 +++++++++++ .../CreateCommunityCommentService.java | 6 ++--- .../CommunityCommentRepositoryTest.java | 22 +++++++++++++++++++ 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepository.java b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepository.java index f38f5af58..07722e607 100644 --- a/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepository.java +++ b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepository.java @@ -7,5 +7,6 @@ public interface CommunityCommentRepository { CommunityComment save(CommunityComment communityComment); Optional findById(Long id); + boolean existsById(Long id); void deleteAllInBatch(); } diff --git a/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java index 9d2cee7ba..93578f694 100644 --- a/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java +++ b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java @@ -7,6 +7,7 @@ import org.springframework.stereotype.Repository; import java.util.Optional; +import java.util.UUID; @RequiredArgsConstructor @Repository @@ -31,6 +32,18 @@ public Optional findById(Long id) { .fetchOne()); } + @Override + public boolean existsById(Long id) { + QCommunityComment communityComment = QCommunityComment.communityComment; + + return queryFactory + .selectOne() + .from(communityComment) + .where(communityComment.id.eq(id) + .and(communityComment.deleted.eq(false))) + .fetchFirst() != null; + } + @Override public void deleteAllInBatch() { communityCommentJpaRepository.deleteAllInBatch(); } } 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 92e49f001..e6da18066 100644 --- a/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java +++ b/src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java @@ -30,10 +30,8 @@ public Long createCommunityComment(CommunityCommentCreateRequestDto requestDto, } private void validateParentCommentExists(Long parentCommentId) { - if (parentCommentId != null) { - communityCommentRepository.findById(parentCommentId) - .orElseThrow(() -> new BadRequestException(NOT_EXISTS_COMMUNITY_COMMENT.getMessage())); + if (parentCommentId != null && !communityCommentRepository.existsById(parentCommentId)) { + throw new BadRequestException(NOT_EXISTS_COMMUNITY_COMMENT.getMessage()); } } - } diff --git a/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java b/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java index 0f0625189..e3ba059d5 100644 --- a/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java +++ b/src/test/java/com/somemore/community/repository/CommunityCommentRepositoryTest.java @@ -86,4 +86,26 @@ void findCommunityCommentById() { assertThat(comment.get().getContent()).isEqualTo("커뮤니티 댓글 테스트 내용"); assertThat(comment.get().getParentCommentId()).isNull(); } + + @DisplayName("댓글 id로 댓글이 존재하는지 확인할 수 있다.") + @Test + void existsById() { + + //given + UUID writerId = UUID.randomUUID(); + + CommunityComment communityComment = CommunityComment.builder() + .writerId(writerId) + .content("커뮤니티 댓글 테스트 내용") + .parentCommentId(null) + .build(); + + CommunityComment savedComment = communityCommentRepository.save(communityComment); + + //when + boolean isExist = communityCommentRepository.existsById(savedComment.getId()); + + //then + assertThat(isExist).isTrue(); + } } From f7d34789b97cfabd348cdcec444f915bab87eb23 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Thu, 28 Nov 2024 17:26:33 +0900 Subject: [PATCH 25/25] =?UTF-8?q?chore(community):=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20import=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/comment/CommunityCommentRepositoryImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java index 93578f694..8a6199f65 100644 --- a/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java +++ b/src/main/java/com/somemore/community/repository/comment/CommunityCommentRepositoryImpl.java @@ -7,7 +7,6 @@ import org.springframework.stereotype.Repository; import java.util.Optional; -import java.util.UUID; @RequiredArgsConstructor @Repository