From b243928d5292a685ed846d8d48bfb9d6d79a7196 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Mon, 28 Aug 2023 20:52:29 +0900 Subject: [PATCH 01/23] =?UTF-8?q?refactor:=20HOT=5FPOST=5FLIKES=5FTHRESHOL?= =?UTF-8?q?D=20MagicNumber=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ssafsound/batch/config/PostBatchConfig.java | 4 +++- .../ssafy/ssafsound/batch/tasklet/PostTasklet.java | 7 +++---- .../domain/post/service/PostConstantProvider.java | 14 ++++++++++++++ .../ssafsound/domain/post/service/PostService.java | 6 ++---- .../ssafsound/global/config/MagicNumberConfig.java | 3 ++- 5 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/ssafy/ssafsound/domain/post/service/PostConstantProvider.java diff --git a/src/main/java/com/ssafy/ssafsound/batch/config/PostBatchConfig.java b/src/main/java/com/ssafy/ssafsound/batch/config/PostBatchConfig.java index 5a04a4698..9c65eb14c 100644 --- a/src/main/java/com/ssafy/ssafsound/batch/config/PostBatchConfig.java +++ b/src/main/java/com/ssafy/ssafsound/batch/config/PostBatchConfig.java @@ -1,6 +1,7 @@ package com.ssafy.ssafsound.batch.config; import com.ssafy.ssafsound.batch.tasklet.PostTasklet; +import com.ssafy.ssafsound.domain.post.service.PostConstantProvider; import com.ssafy.ssafsound.domain.post.service.PostService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -21,6 +22,7 @@ public class PostBatchConfig { private final JobBuilderFactory jobBuilderFactory; private final StepBuilderFactory stepBuilderFactory; private final PostService postService; + private final PostConstantProvider postConstantProvider; @Bean @@ -40,6 +42,6 @@ public Step deleteHotPostStep() { @Bean public Tasklet deleteHotPostTasklet() { - return new PostTasklet(postService); + return new PostTasklet(postService, postConstantProvider); } } diff --git a/src/main/java/com/ssafy/ssafsound/batch/tasklet/PostTasklet.java b/src/main/java/com/ssafy/ssafsound/batch/tasklet/PostTasklet.java index 6abf4f422..77d2bf103 100644 --- a/src/main/java/com/ssafy/ssafsound/batch/tasklet/PostTasklet.java +++ b/src/main/java/com/ssafy/ssafsound/batch/tasklet/PostTasklet.java @@ -1,5 +1,6 @@ package com.ssafy.ssafsound.batch.tasklet; +import com.ssafy.ssafsound.domain.post.service.PostConstantProvider; import com.ssafy.ssafsound.domain.post.service.PostService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -10,14 +11,12 @@ import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.batch.repeat.RepeatStatus; -import org.springframework.beans.factory.annotation.Value; @Slf4j @RequiredArgsConstructor public class PostTasklet implements Tasklet, StepExecutionListener { - @Value("${spring.constant.post.HOT_POST_LIKES_THRESHOLD}") - private Long HOT_POST_LIKES_THRESHOLD; private final PostService postService; + private final PostConstantProvider postConstantProvider; @Override public void beforeStep(StepExecution stepExecution) { @@ -25,7 +24,7 @@ public void beforeStep(StepExecution stepExecution) { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) { - postService.deleteHotPostsUnderThreshold(HOT_POST_LIKES_THRESHOLD); + postService.deleteHotPostsUnderThreshold(postConstantProvider.getHOT_POST_LIKES_THRESHOLD()); return RepeatStatus.FINISHED; } diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostConstantProvider.java b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostConstantProvider.java new file mode 100644 index 000000000..e660258ee --- /dev/null +++ b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostConstantProvider.java @@ -0,0 +1,14 @@ +package com.ssafy.ssafsound.domain.post.service; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.ConstructorBinding; + +@Getter +@RequiredArgsConstructor +@ConfigurationProperties(prefix = "spring.constant.post") +@ConstructorBinding +public class PostConstantProvider { + private final Long HOT_POST_LIKES_THRESHOLD; +} diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java index c89be1bd5..39952af1b 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java @@ -19,7 +19,6 @@ import com.ssafy.ssafsound.infra.storage.service.AwsS3StorageService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -29,8 +28,6 @@ @Slf4j @RequiredArgsConstructor public class PostService { - @Value("${spring.constant.post.HOT_POST_LIKES_THRESHOLD}") - private Long HOT_POST_LIKES_THRESHOLD; private final BoardRepository boardRepository; private final MemberRepository memberRepository; @@ -41,6 +38,7 @@ public class PostService { private final PostScrapRepository postScrapRepository; private final PostImageRepository postImageRepository; private final AwsS3StorageService awsS3StorageService; + private final PostConstantProvider postConstantProvider; @Transactional(readOnly = true) public GetPostResDto findPosts(GetPostReqDto getPostReqDto) { @@ -109,7 +107,7 @@ private void deleteLike(PostLike postLike) { private boolean isSelectedHotPost(Long postId) { - return postLikeRepository.countByPostId(postId) >= HOT_POST_LIKES_THRESHOLD; + return postLikeRepository.countByPostId(postId) >= postConstantProvider.getHOT_POST_LIKES_THRESHOLD(); } private void saveHotPost(Long postId) { diff --git a/src/main/java/com/ssafy/ssafsound/global/config/MagicNumberConfig.java b/src/main/java/com/ssafy/ssafsound/global/config/MagicNumberConfig.java index 890b7e6df..8fb96db6e 100644 --- a/src/main/java/com/ssafy/ssafsound/global/config/MagicNumberConfig.java +++ b/src/main/java/com/ssafy/ssafsound/global/config/MagicNumberConfig.java @@ -2,12 +2,13 @@ import com.ssafy.ssafsound.domain.member.service.MemberConstantProvider; import com.ssafy.ssafsound.domain.member.service.SemesterConstantProvider; +import com.ssafy.ssafsound.domain.post.service.PostConstantProvider; import lombok.RequiredArgsConstructor; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; @Configuration -@EnableConfigurationProperties({MemberConstantProvider.class, SemesterConstantProvider.class}) +@EnableConfigurationProperties({MemberConstantProvider.class, SemesterConstantProvider.class, PostConstantProvider.class}) @RequiredArgsConstructor public class MagicNumberConfig { } From de17d93dd222105bea480bd335730fab55651013 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Mon, 4 Sep 2023 23:10:03 +0900 Subject: [PATCH 02/23] =?UTF-8?q?fix:=20=EC=9D=B5=EB=AA=85=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=EC=9D=BC=20=EB=95=8C=20ssafyInfo=EC=97=90=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=EA=B0=80=20=EB=93=A4=EC=96=B4=EC=9E=88?= =?UTF-8?q?=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ssafy/ssafsound/domain/member/dto/AuthorElement.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/ssafy/ssafsound/domain/member/dto/AuthorElement.java b/src/main/java/com/ssafy/ssafsound/domain/member/dto/AuthorElement.java index 039e59ff9..165ff6814 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/member/dto/AuthorElement.java +++ b/src/main/java/com/ssafy/ssafsound/domain/member/dto/AuthorElement.java @@ -29,9 +29,9 @@ public AuthorElement(Member member, Boolean anonymity, Long number) { public AuthorElement(Member member, Boolean anonymity) { this.memberId = anonymity? -1 : member.getId(); this.nickname = anonymity? "익명" : member.getNickname(); - this.memberRole = member.getRole().getRoleType(); - this.ssafyMember = member.getSsafyMember(); - this.isMajor = member.getMajor(); - this.ssafyInfo = SSAFYInfo.from(member); + this.memberRole = anonymity? null : member.getRole().getRoleType(); + this.ssafyMember = anonymity? null : member.getSsafyMember(); + this.isMajor = anonymity? null : member.getMajor(); + this.ssafyInfo = anonymity? null : SSAFYInfo.from(member); } } From 4d81e4329e7c145de02bf1c63c99a0dc0c9993c8 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Tue, 5 Sep 2023 19:34:45 +0900 Subject: [PATCH 03/23] =?UTF-8?q?fix:=20GetPostReqDto=20build=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/dto/GetPostReqDto.java | 2 + .../domain/post/service/PostServiceTest.java | 159 ++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/dto/GetPostReqDto.java b/src/main/java/com/ssafy/ssafsound/domain/post/dto/GetPostReqDto.java index 2155a9c29..ae7150abe 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/dto/GetPostReqDto.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/dto/GetPostReqDto.java @@ -1,5 +1,6 @@ package com.ssafy.ssafsound.domain.post.dto; +import lombok.Builder; import lombok.Getter; import lombok.Setter; @@ -7,6 +8,7 @@ @Getter @Setter +@Builder public class GetPostReqDto { private Long boardId; private Long cursor; diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java new file mode 100644 index 000000000..c472afdc2 --- /dev/null +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -0,0 +1,159 @@ +package com.ssafy.ssafsound.domain.post.service; + +import com.ssafy.ssafsound.domain.board.repository.BoardRepository; +import com.ssafy.ssafsound.domain.member.repository.MemberRepository; +import com.ssafy.ssafsound.domain.post.domain.Post; +import com.ssafy.ssafsound.domain.post.dto.GetPostReqDto; +import com.ssafy.ssafsound.domain.post.dto.GetPostResDto; +import com.ssafy.ssafsound.domain.post.repository.*; +import com.ssafy.ssafsound.infra.storage.service.AwsS3StorageService; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static com.ssafy.ssafsound.global.util.fixture.PostFixture.POST_FIXTURE1; +import static com.ssafy.ssafsound.global.util.fixture.PostFixture.POST_FIXTURE2; +import static org.mockito.BDDMockito.given; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(MockitoExtension.class) +class PostServiceTest { + + @Mock + private BoardRepository boardRepository; + + @Mock + private MemberRepository memberRepository; + + @Mock + private PostRepository postRepository; + + @Mock + private PostLikeRepository postLikeRepository; + + @Mock + private HotPostRepository hotPostRepository; + + @Mock + private PostScrapRepository postScrapRepository; + + @Mock + private PostReportRepository postReportRepository; + + @Mock + private PostImageRepository postImageRepository; + + @Mock + private AwsS3StorageService awsS3StorageService; + + @Mock + private PostConstantProvider postConstantProvider; + + @InjectMocks + private PostService postService; + + + @Test + @DisplayName("정상적인 BoardId, Cursor, Size가 주어졌다면 게시글 목록 조회가 성공합니다.") + void Given_BoardIdAndCursorAndSize_When_findPosts_Then_Success() { + GetPostReqDto getPostReqDto = GetPostReqDto.builder() + .boardId(1L) + .cursor(-1L) + .size(10) + .build(); + + List posts = List.of(POST_FIXTURE1, POST_FIXTURE2); + + // given + given(boardRepository.existsById(getPostReqDto.getBoardId())).willReturn(true); + given(postRepository.findWithDetailsByBoardId(getPostReqDto.getBoardId(), getPostReqDto.getCursor(), getPostReqDto.getSize())).willReturn(posts); + + // when + GetPostResDto getPostResDto = postService.findPosts(getPostReqDto); + + // then + assertAll( + () -> assertThat(getPostResDto.getPosts()).hasSize(2), + () -> assertThat(getPostResDto.getPosts()) + .extracting("title") + .containsExactly(POST_FIXTURE1.getTitle(), POST_FIXTURE2.getTitle()), + () -> assertThat(getPostResDto.getPosts()) + .extracting("boardTitle") + .containsExactly(POST_FIXTURE1.getBoard().getTitle(), POST_FIXTURE2.getBoard().getTitle()) +// () -> assertThat(response.getTitle()).isEqualTo(post.getTitle()), +// () -> assertThat(response.getContent()).isEqualTo(post.getContent()), +// () -> assertThat(response.isAuthorized()).isFalse(), +// () -> assertThat(response.isModified()).isFalse(), +// () -> assertThat(response.getCreatedAt()).isNotNull(), +// () -> assertThat(response.getBoardId()).isEqualTo(postBoard.getBoard().getId()) + ); + + // verify + } + + @Test + @DisplayName("존재하지 않은 BoardId가 주어졌다면 게시글 목록 조회가 실패합니다.") + void Given_BoardId_When_findPosts_Then_Fail() { + + } + + @Test + @DisplayName("최소값 보다 작은 Size가 주어졌다면 게시글 목록 조회가 실패합니다.") + void Given_Size_When_findPosts_Then_Fail() { + + } + + @Test + void findPost() { + } + + @Test + void likePost() { + } + + @Test + void deleteHotPostsUnderThreshold() { + } + + @Test + void scrapPost() { + } + + @Test + void writePost() { + } + + @Test + void deletePost() { + } + + @Test + void updatePost() { + } + + @Test + void findHotPosts() { + } + + @Test + void findMyPosts() { + } + + @Test + void findMyScrapPosts() { + } + + @Test + void searchPosts() { + } + + @Test + void searchHotPosts() { + } +} \ No newline at end of file From b2b90c6725192ee2edc3dc5c86f3a1b890fa631b Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Tue, 5 Sep 2023 19:58:30 +0900 Subject: [PATCH 04/23] =?UTF-8?q?test:=20report=20=EA=B4=80=EB=A0=A8=20rep?= =?UTF-8?q?ository=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ssafy/ssafsound/domain/post/service/PostServiceTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index c472afdc2..ee4a22d0f 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -43,9 +43,6 @@ class PostServiceTest { @Mock private PostScrapRepository postScrapRepository; - @Mock - private PostReportRepository postReportRepository; - @Mock private PostImageRepository postImageRepository; From 24b7f73994554952f97b62013ea87a4140569c59 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Thu, 7 Sep 2023 20:07:57 +0900 Subject: [PATCH 05/23] =?UTF-8?q?test:=20=EC=A0=95=EC=83=81=EC=A0=81?= =?UTF-8?q?=EC=9D=B8=20BoardId,=20Cursor,=20Size=EA=B0=80=20=EC=A3=BC?= =?UTF-8?q?=EC=96=B4=EC=A1=8C=EB=8B=A4=EB=A9=B4=20=EA=B2=8C=EC=8B=9C?= =?UTF-8?q?=EA=B8=80=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=EA=B0=80=20?= =?UTF-8?q?=EC=84=B1=EA=B3=B5=ED=95=A9=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/service/PostServiceTest.java | 28 ++++--------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index ee4a22d0f..19ab1fcbc 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -21,6 +21,8 @@ import static org.mockito.BDDMockito.given; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; @ExtendWith(MockitoExtension.class) class PostServiceTest { @@ -72,26 +74,14 @@ void Given_BoardIdAndCursorAndSize_When_findPosts_Then_Success() { given(postRepository.findWithDetailsByBoardId(getPostReqDto.getBoardId(), getPostReqDto.getCursor(), getPostReqDto.getSize())).willReturn(posts); // when - GetPostResDto getPostResDto = postService.findPosts(getPostReqDto); + GetPostResDto response = postService.findPosts(getPostReqDto); // then - assertAll( - () -> assertThat(getPostResDto.getPosts()).hasSize(2), - () -> assertThat(getPostResDto.getPosts()) - .extracting("title") - .containsExactly(POST_FIXTURE1.getTitle(), POST_FIXTURE2.getTitle()), - () -> assertThat(getPostResDto.getPosts()) - .extracting("boardTitle") - .containsExactly(POST_FIXTURE1.getBoard().getTitle(), POST_FIXTURE2.getBoard().getTitle()) -// () -> assertThat(response.getTitle()).isEqualTo(post.getTitle()), -// () -> assertThat(response.getContent()).isEqualTo(post.getContent()), -// () -> assertThat(response.isAuthorized()).isFalse(), -// () -> assertThat(response.isModified()).isFalse(), -// () -> assertThat(response.getCreatedAt()).isNotNull(), -// () -> assertThat(response.getBoardId()).isEqualTo(postBoard.getBoard().getId()) - ); + assertThat(response).usingRecursiveComparison().isEqualTo(GetPostResDto.ofPosts(posts, getPostReqDto.getSize())); // verify + verify(boardRepository, times(1)).existsById(getPostReqDto.getBoardId()); + verify(postRepository, times(1)).findWithDetailsByBoardId(getPostReqDto.getBoardId(), getPostReqDto.getCursor(), getPostReqDto.getSize()); } @Test @@ -100,12 +90,6 @@ void Given_BoardId_When_findPosts_Then_Fail() { } - @Test - @DisplayName("최소값 보다 작은 Size가 주어졌다면 게시글 목록 조회가 실패합니다.") - void Given_Size_When_findPosts_Then_Fail() { - - } - @Test void findPost() { } From 06a131426a8e1b0d008cbd87845b81f4bff8a137 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Thu, 7 Sep 2023 20:29:35 +0900 Subject: [PATCH 06/23] =?UTF-8?q?test:=20=EC=A1=B4=EC=9E=AC=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EC=9D=80=20boardId=EA=B0=80=20=EC=A3=BC?= =?UTF-8?q?=EC=96=B4=EC=A1=8C=EB=8B=A4=EB=A9=B4=20=EA=B2=8C=EC=8B=9C?= =?UTF-8?q?=EA=B8=80=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20=EC=8B=A4?= =?UTF-8?q?=ED=8C=A8=ED=95=98=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/service/PostServiceTest.java | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index 19ab1fcbc..fb4387af7 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -1,5 +1,7 @@ package com.ssafy.ssafsound.domain.post.service; +import com.ssafy.ssafsound.domain.board.exception.BoardErrorInfo; +import com.ssafy.ssafsound.domain.board.exception.BoardException; import com.ssafy.ssafsound.domain.board.repository.BoardRepository; import com.ssafy.ssafsound.domain.member.repository.MemberRepository; import com.ssafy.ssafsound.domain.post.domain.Post; @@ -59,8 +61,9 @@ class PostServiceTest { @Test - @DisplayName("정상적인 BoardId, Cursor, Size가 주어졌다면 게시글 목록 조회가 성공합니다.") + @DisplayName("정상적인 boardId, cursor, size가 주어졌다면 게시글 목록 조회가 성공합니다.") void Given_BoardIdAndCursorAndSize_When_findPosts_Then_Success() { + // given GetPostReqDto getPostReqDto = GetPostReqDto.builder() .boardId(1L) .cursor(-1L) @@ -69,7 +72,6 @@ void Given_BoardIdAndCursorAndSize_When_findPosts_Then_Success() { List posts = List.of(POST_FIXTURE1, POST_FIXTURE2); - // given given(boardRepository.existsById(getPostReqDto.getBoardId())).willReturn(true); given(postRepository.findWithDetailsByBoardId(getPostReqDto.getBoardId(), getPostReqDto.getCursor(), getPostReqDto.getSize())).willReturn(posts); @@ -85,9 +87,23 @@ void Given_BoardIdAndCursorAndSize_When_findPosts_Then_Success() { } @Test - @DisplayName("존재하지 않은 BoardId가 주어졌다면 게시글 목록 조회가 실패합니다.") + @DisplayName("존재하지 않은 boardId가 주어졌다면 게시글 목록 조회가 실패합니다.") void Given_BoardId_When_findPosts_Then_Fail() { + // given + GetPostReqDto getPostReqDto = GetPostReqDto.builder() + .boardId(100L) + .cursor(-1L) + .size(10) + .build(); + + given(boardRepository.existsById(getPostReqDto.getBoardId())).willReturn(false); + + // when, then + BoardException exception = assertThrows(BoardException.class, () -> postService.findPosts(getPostReqDto)); + assertEquals(BoardErrorInfo.NO_BOARD, exception.getInfo()); + // verify + verify(boardRepository, times(1)).existsById(getPostReqDto.getBoardId()); } @Test From 133596f27c423e3df2aeb408e4a72bcf2691b39e Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Wed, 13 Sep 2023 20:50:04 +0900 Subject: [PATCH 07/23] =?UTF-8?q?test:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=8B=9C=20=EC=9C=A0=ED=9A=A8=ED=95=9C=20postId=EC=99=80=20log?= =?UTF-8?q?inMemberId=EA=B0=80=20=EC=A3=BC=EC=96=B4=EC=A1=8C=EB=8B=A4?= =?UTF-8?q?=EB=A9=B4=20=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EC=83=81=EC=84=B8=20?= =?UTF-8?q?=EB=B3=B4=EA=B8=B0=EA=B0=80=20=EC=84=B1=EA=B3=B5=ED=95=A9?= =?UTF-8?q?=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/service/PostServiceTest.java | 283 +++++++++++------- 1 file changed, 174 insertions(+), 109 deletions(-) diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index fb4387af7..6606d2f66 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -1,156 +1,221 @@ package com.ssafy.ssafsound.domain.post.service; +import static com.ssafy.ssafsound.global.util.fixture.PostFixture.*; +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.BDDMockito.*; + +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + import com.ssafy.ssafsound.domain.board.exception.BoardErrorInfo; import com.ssafy.ssafsound.domain.board.exception.BoardException; import com.ssafy.ssafsound.domain.board.repository.BoardRepository; +import com.ssafy.ssafsound.domain.member.domain.Member; import com.ssafy.ssafsound.domain.member.repository.MemberRepository; import com.ssafy.ssafsound.domain.post.domain.Post; +import com.ssafy.ssafsound.domain.post.dto.GetPostDetailResDto; import com.ssafy.ssafsound.domain.post.dto.GetPostReqDto; import com.ssafy.ssafsound.domain.post.dto.GetPostResDto; -import com.ssafy.ssafsound.domain.post.repository.*; +import com.ssafy.ssafsound.domain.post.repository.HotPostRepository; +import com.ssafy.ssafsound.domain.post.repository.PostImageRepository; +import com.ssafy.ssafsound.domain.post.repository.PostLikeRepository; +import com.ssafy.ssafsound.domain.post.repository.PostRepository; +import com.ssafy.ssafsound.domain.post.repository.PostScrapRepository; +import com.ssafy.ssafsound.global.util.fixture.MemberFixture; import com.ssafy.ssafsound.infra.storage.service.AwsS3StorageService; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.util.List; - -import static com.ssafy.ssafsound.global.util.fixture.PostFixture.POST_FIXTURE1; -import static com.ssafy.ssafsound.global.util.fixture.PostFixture.POST_FIXTURE2; -import static org.mockito.BDDMockito.given; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; @ExtendWith(MockitoExtension.class) class PostServiceTest { - @Mock - private BoardRepository boardRepository; + @Mock + private BoardRepository boardRepository; + + @Mock + private MemberRepository memberRepository; + + @Mock + private PostRepository postRepository; + + @Mock + private PostLikeRepository postLikeRepository; + + @Mock + private HotPostRepository hotPostRepository; + + @Mock + private PostScrapRepository postScrapRepository; + + @Mock + private PostImageRepository postImageRepository; + + @Mock + private AwsS3StorageService awsS3StorageService; + + @Mock + private PostConstantProvider postConstantProvider; + + @InjectMocks + private PostService postService; + + @Test + @DisplayName("유효한 boardId, cursor, size가 주어졌다면 게시글 목록 조회가 성공합니다.") + void Given_BoardIdAndCursorAndSize_When_findPosts_Then_Success() { + // given + GetPostReqDto getPostReqDto = GetPostReqDto.builder() + .boardId(1L) + .cursor(-1L) + .size(10) + .build(); + + List posts = List.of(POST_FIXTURE1, POST_FIXTURE2); + + given(boardRepository.existsById(getPostReqDto.getBoardId())).willReturn(true); + given(postRepository.findWithDetailsByBoardId(getPostReqDto.getBoardId(), getPostReqDto.getCursor(), + getPostReqDto.getSize())).willReturn(posts); + + // when + GetPostResDto response = postService.findPosts(getPostReqDto); + + // then + assertThat(response).usingRecursiveComparison() + .isEqualTo(GetPostResDto.ofPosts(posts, getPostReqDto.getSize())); + + // verify + verify(boardRepository, times(1)).existsById(getPostReqDto.getBoardId()); + verify(postRepository, times(1)).findWithDetailsByBoardId(getPostReqDto.getBoardId(), getPostReqDto.getCursor(), + getPostReqDto.getSize()); + } + + @Test + @DisplayName("유효하지 않은 boardId가 주어졌다면 게시글 목록 조회에 예외를 발생합니다.") + void Given_BoardId_When_findPosts_Then_Fail() { + // given + GetPostReqDto getPostReqDto = GetPostReqDto.builder() + .boardId(100L) + .cursor(-1L) + .size(10) + .build(); + + given(boardRepository.existsById(getPostReqDto.getBoardId())).willReturn(false); + + // when, then + BoardException exception = assertThrows(BoardException.class, () -> postService.findPosts(getPostReqDto)); + assertEquals(BoardErrorInfo.NO_BOARD, exception.getInfo()); - @Mock - private MemberRepository memberRepository; + // verify + verify(boardRepository, times(1)).existsById(getPostReqDto.getBoardId()); + } - @Mock - private PostRepository postRepository; + @Test + @DisplayName("로그인 시 유효한 postId와 loginMemberId가 주어졌다면 게시글 상세 보기가 성공합니다.") + void Given_PostIdAndLoginMemberId_When_findPost_Then_Success() { + // given + Post post = POST_FIXTURE1; + Member member = MemberFixture.GENERAL_MEMBER; - @Mock - private PostLikeRepository postLikeRepository; + given(postRepository.findWithMemberAndPostImageFetchById(post.getId())).willReturn(Optional.of(post)); + given(memberRepository.findById(member.getId())).willReturn(Optional.of(member)); - @Mock - private HotPostRepository hotPostRepository; + // when + GetPostDetailResDto response = postService.findPost(post.getId(), member.getId()); - @Mock - private PostScrapRepository postScrapRepository; + // then + assertThat(response).usingRecursiveComparison() + .isEqualTo(GetPostDetailResDto.of(post, member)); - @Mock - private PostImageRepository postImageRepository; + // verify + verify(postRepository, times(1)).findWithMemberAndPostImageFetchById(post.getId()); + verify(memberRepository, times(1)).findById(member.getId()); + } - @Mock - private AwsS3StorageService awsS3StorageService; + @Test + @DisplayName("비 로그인 시 유효한 postId가 주어졌다면 게시글 상세 보기가 성공합니다.") + void Given_PostId_When_findPost_Then_Success() { + // given - @Mock - private PostConstantProvider postConstantProvider; + // when - @InjectMocks - private PostService postService; + // then + // verify - @Test - @DisplayName("정상적인 boardId, cursor, size가 주어졌다면 게시글 목록 조회가 성공합니다.") - void Given_BoardIdAndCursorAndSize_When_findPosts_Then_Success() { - // given - GetPostReqDto getPostReqDto = GetPostReqDto.builder() - .boardId(1L) - .cursor(-1L) - .size(10) - .build(); + } - List posts = List.of(POST_FIXTURE1, POST_FIXTURE2); + @Test + @DisplayName("유효하지 않은 postId가 주어졌다면 게시글 상세보기에 예외를 발생합니다.") + void Given_InvalidPostId_When_findPost_Then_Success() { + // given - given(boardRepository.existsById(getPostReqDto.getBoardId())).willReturn(true); - given(postRepository.findWithDetailsByBoardId(getPostReqDto.getBoardId(), getPostReqDto.getCursor(), getPostReqDto.getSize())).willReturn(posts); + // when - // when - GetPostResDto response = postService.findPosts(getPostReqDto); + // then - // then - assertThat(response).usingRecursiveComparison().isEqualTo(GetPostResDto.ofPosts(posts, getPostReqDto.getSize())); + // verify - // verify - verify(boardRepository, times(1)).existsById(getPostReqDto.getBoardId()); - verify(postRepository, times(1)).findWithDetailsByBoardId(getPostReqDto.getBoardId(), getPostReqDto.getCursor(), getPostReqDto.getSize()); - } + } - @Test - @DisplayName("존재하지 않은 boardId가 주어졌다면 게시글 목록 조회가 실패합니다.") - void Given_BoardId_When_findPosts_Then_Fail() { - // given - GetPostReqDto getPostReqDto = GetPostReqDto.builder() - .boardId(100L) - .cursor(-1L) - .size(10) - .build(); + @Test + @DisplayName("로그인 시 유효하지 않은 loginMemberId가 주어졌다면 게시글 상세보기에 예외를 발생합니다.") + void Given_InvalidLoginMemberId_When_findPost_Then_Success() { + // given - given(boardRepository.existsById(getPostReqDto.getBoardId())).willReturn(false); + // when - // when, then - BoardException exception = assertThrows(BoardException.class, () -> postService.findPosts(getPostReqDto)); - assertEquals(BoardErrorInfo.NO_BOARD, exception.getInfo()); + // then - // verify - verify(boardRepository, times(1)).existsById(getPostReqDto.getBoardId()); - } + // verify - @Test - void findPost() { - } + } - @Test - void likePost() { - } + @Test + void likePost() { + } - @Test - void deleteHotPostsUnderThreshold() { - } + @Test + void deleteHotPostsUnderThreshold() { + } - @Test - void scrapPost() { - } + @Test + void scrapPost() { + } - @Test - void writePost() { - } + @Test + void writePost() { + } - @Test - void deletePost() { - } + @Test + void deletePost() { + } - @Test - void updatePost() { - } + @Test + void updatePost() { + } - @Test - void findHotPosts() { - } + @Test + void findHotPosts() { + } - @Test - void findMyPosts() { - } + @Test + void findMyPosts() { + } - @Test - void findMyScrapPosts() { - } + @Test + void findMyScrapPosts() { + } - @Test - void searchPosts() { - } + @Test + void searchPosts() { + } - @Test - void searchHotPosts() { - } + @Test + void searchHotPosts() { + } } \ No newline at end of file From 446ac13e8398dcc11b9c78a70de0d8c12a1f583e Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 18:05:31 +0900 Subject: [PATCH 08/23] =?UTF-8?q?test:=20=EB=B9=84=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EC=8B=9C=20=EC=9C=A0=ED=9A=A8=ED=95=9C=20postId?= =?UTF-8?q?=EA=B0=80=20=EC=A3=BC=EC=96=B4=EC=A1=8C=EB=8B=A4=EB=A9=B4=20?= =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EC=83=81=EC=84=B8=20=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0=EA=B0=80=20=EC=84=B1=EA=B3=B5=ED=95=A9=EB=8B=88?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ssafsound/domain/post/service/PostServiceTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index 6606d2f66..6cf863b90 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -140,12 +140,19 @@ void Given_PostIdAndLoginMemberId_When_findPost_Then_Success() { @DisplayName("비 로그인 시 유효한 postId가 주어졌다면 게시글 상세 보기가 성공합니다.") void Given_PostId_When_findPost_Then_Success() { // given + Post post = POST_FIXTURE1; + + given(postRepository.findWithMemberAndPostImageFetchById(post.getId())).willReturn(Optional.of(post)); // when + GetPostDetailResDto response = postService.findPost(post.getId(), null); // then + assertThat(response).usingRecursiveComparison() + .isEqualTo(GetPostDetailResDto.of(post, null)); // verify + verify(postRepository, times(1)).findWithMemberAndPostImageFetchById(post.getId()); } From bae0223260051baa89899a21cb6171786b6c06cf Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 18:14:16 +0900 Subject: [PATCH 09/23] =?UTF-8?q?test:=20=EC=9C=A0=ED=9A=A8=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EC=9D=80=20postId=EA=B0=80=20=EC=A3=BC?= =?UTF-8?q?=EC=96=B4=EC=A1=8C=EB=8B=A4=EB=A9=B4=20=EA=B2=8C=EC=8B=9C?= =?UTF-8?q?=EA=B8=80=20=EC=83=81=EC=84=B8=EB=B3=B4=EA=B8=B0=EC=97=90=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EB=A5=BC=20=EB=B0=9C=EC=83=9D=ED=95=A9?= =?UTF-8?q?=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/service/PostServiceTest.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index 6cf863b90..7b0d85b7c 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -24,6 +24,8 @@ import com.ssafy.ssafsound.domain.post.dto.GetPostDetailResDto; import com.ssafy.ssafsound.domain.post.dto.GetPostReqDto; import com.ssafy.ssafsound.domain.post.dto.GetPostResDto; +import com.ssafy.ssafsound.domain.post.exception.PostErrorInfo; +import com.ssafy.ssafsound.domain.post.exception.PostException; import com.ssafy.ssafsound.domain.post.repository.HotPostRepository; import com.ssafy.ssafsound.domain.post.repository.PostImageRepository; import com.ssafy.ssafsound.domain.post.repository.PostLikeRepository; @@ -160,13 +162,16 @@ void Given_PostId_When_findPost_Then_Success() { @DisplayName("유효하지 않은 postId가 주어졌다면 게시글 상세보기에 예외를 발생합니다.") void Given_InvalidPostId_When_findPost_Then_Success() { // given + Long postId = 100L; - // when + given(postRepository.findWithMemberAndPostImageFetchById(postId)).willReturn(Optional.empty()); - // then + // when, then + PostException exception = assertThrows(PostException.class, () -> postService.findPost(postId, null)); + assertEquals(PostErrorInfo.NOT_FOUND_POST, exception.getInfo()); // verify - + verify(postRepository, times(1)).findWithMemberAndPostImageFetchById(postId); } @Test From 36526e72f4127c342ba7fd7b7e7666ba57482718 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 18:19:44 +0900 Subject: [PATCH 10/23] =?UTF-8?q?test:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=8B=9C=20=EC=9C=A0=ED=9A=A8=ED=95=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EC=9D=80=20loginMemberId=EA=B0=80=20=EC=A3=BC=EC=96=B4?= =?UTF-8?q?=EC=A1=8C=EB=8B=A4=EB=A9=B4=20=EA=B2=8C=EC=8B=9C=EA=B8=80=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=EB=B3=B4=EA=B8=B0=EC=97=90=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EB=A5=BC=20=EB=B0=9C=EC=83=9D=ED=95=A9=EB=8B=88?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/service/PostServiceTest.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index 7b0d85b7c..41c7d118d 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -19,6 +19,8 @@ import com.ssafy.ssafsound.domain.board.exception.BoardException; import com.ssafy.ssafsound.domain.board.repository.BoardRepository; import com.ssafy.ssafsound.domain.member.domain.Member; +import com.ssafy.ssafsound.domain.member.exception.MemberErrorInfo; +import com.ssafy.ssafsound.domain.member.exception.MemberException; import com.ssafy.ssafsound.domain.member.repository.MemberRepository; import com.ssafy.ssafsound.domain.post.domain.Post; import com.ssafy.ssafsound.domain.post.dto.GetPostDetailResDto; @@ -178,13 +180,20 @@ void Given_InvalidPostId_When_findPost_Then_Success() { @DisplayName("로그인 시 유효하지 않은 loginMemberId가 주어졌다면 게시글 상세보기에 예외를 발생합니다.") void Given_InvalidLoginMemberId_When_findPost_Then_Success() { // given + Post post = POST_FIXTURE1; + Long memberId = 100L; - // when + given(postRepository.findWithMemberAndPostImageFetchById(post.getId())).willReturn(Optional.of(post)); + given(memberRepository.findById(memberId)).willReturn(Optional.empty()); - // then + // when, then + MemberException exception = assertThrows(MemberException.class, + () -> postService.findPost(post.getId(), memberId)); + assertEquals(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID, exception.getInfo()); // verify - + verify(postRepository, times(1)).findWithMemberAndPostImageFetchById(post.getId()); + verify(memberRepository, times(1)).findById(memberId); } @Test From 8b0528228cdbf5029fe388a419807949912ef070 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 19:19:02 +0900 Subject: [PATCH 11/23] =?UTF-8?q?fix:=20=EC=9C=A0=ED=9A=A8=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EC=9D=80=20=EA=B2=8C=EC=8B=9C=EA=B8=80?= =?UTF-8?q?=EC=9D=84=20=EC=A2=8B=EC=95=84=EC=9A=94=20=ED=95=98=EB=A9=B4=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ssafy/ssafsound/domain/post/service/PostService.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java index 39952af1b..1ce1de223 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java @@ -73,7 +73,10 @@ public PostCommonLikeResDto likePost(Long postId, Long loginMemberId) { Member loginMember = memberRepository.findById(loginMemberId) .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); - PostLike postLike = postLikeRepository.findByPostIdAndMemberId(postId, loginMember.getId()) + Post post = postRepository.findWithMemberAndPostImageFetchById(postId) + .orElseThrow(() -> new PostException(PostErrorInfo.NOT_FOUND_POST)); + + PostLike postLike = postLikeRepository.findByPostIdAndMemberId(post.getId(), loginMember.getId()) .orElse(null); Integer likeCount = postLikeRepository.countByPostId(postId); From c201d495eb4548d169fbcc860f6795a9281c5eb3 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 19:51:55 +0900 Subject: [PATCH 12/23] =?UTF-8?q?fix:=20Hot=EA=B2=8C=EC=8B=9C=EA=B8=80?= =?UTF-8?q?=EC=9D=B4=20=EC=A4=91=EB=B3=B5=EB=90=98=EC=96=B4=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=EB=90=98=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../post/repository/HotPostRepository.java | 1 + .../domain/post/service/PostService.java | 593 +++++++++--------- 2 files changed, 308 insertions(+), 286 deletions(-) diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/repository/HotPostRepository.java b/src/main/java/com/ssafy/ssafsound/domain/post/repository/HotPostRepository.java index b3eb0c15c..9fac8a45d 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/repository/HotPostRepository.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/repository/HotPostRepository.java @@ -23,4 +23,5 @@ public interface HotPostRepository extends JpaRepository, HotPost void deleteHotPostsUnderThreshold(@Param("threshold") Long threshold); Optional findByPostId(Long postId); + Boolean existsByPostId(Long postId); } diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java index 1ce1de223..77fa3f427 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java @@ -1,5 +1,10 @@ package com.ssafy.ssafsound.domain.post.service; +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + import com.ssafy.ssafsound.domain.board.domain.Board; import com.ssafy.ssafsound.domain.board.exception.BoardErrorInfo; import com.ssafy.ssafsound.domain.board.exception.BoardException; @@ -8,304 +13,320 @@ import com.ssafy.ssafsound.domain.member.exception.MemberErrorInfo; import com.ssafy.ssafsound.domain.member.exception.MemberException; import com.ssafy.ssafsound.domain.member.repository.MemberRepository; -import com.ssafy.ssafsound.domain.post.domain.*; +import com.ssafy.ssafsound.domain.post.domain.HotPost; +import com.ssafy.ssafsound.domain.post.domain.Post; +import com.ssafy.ssafsound.domain.post.domain.PostImage; +import com.ssafy.ssafsound.domain.post.domain.PostLike; +import com.ssafy.ssafsound.domain.post.domain.PostScrap; import com.ssafy.ssafsound.domain.post.dto.GetPostDetailResDto; +import com.ssafy.ssafsound.domain.post.dto.GetPostHotReqDto; +import com.ssafy.ssafsound.domain.post.dto.GetPostHotSearchReqDto; +import com.ssafy.ssafsound.domain.post.dto.GetPostMyReqDto; +import com.ssafy.ssafsound.domain.post.dto.GetPostReqDto; import com.ssafy.ssafsound.domain.post.dto.GetPostResDto; +import com.ssafy.ssafsound.domain.post.dto.GetPostSearchReqDto; +import com.ssafy.ssafsound.domain.post.dto.ImageInfo; +import com.ssafy.ssafsound.domain.post.dto.PostCommonLikeResDto; +import com.ssafy.ssafsound.domain.post.dto.PostIdElement; +import com.ssafy.ssafsound.domain.post.dto.PostPatchUpdateReqDto; +import com.ssafy.ssafsound.domain.post.dto.PostPostScrapResDto; +import com.ssafy.ssafsound.domain.post.dto.PostPostWriteReqDto; import com.ssafy.ssafsound.domain.post.exception.PostErrorInfo; import com.ssafy.ssafsound.domain.post.exception.PostException; -import com.ssafy.ssafsound.domain.post.repository.*; -import com.ssafy.ssafsound.domain.post.dto.*; +import com.ssafy.ssafsound.domain.post.repository.HotPostRepository; +import com.ssafy.ssafsound.domain.post.repository.PostImageRepository; +import com.ssafy.ssafsound.domain.post.repository.PostLikeRepository; +import com.ssafy.ssafsound.domain.post.repository.PostRepository; +import com.ssafy.ssafsound.domain.post.repository.PostScrapRepository; import com.ssafy.ssafsound.infra.exception.InfraException; import com.ssafy.ssafsound.infra.storage.service.AwsS3StorageService; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; @Service @Slf4j @RequiredArgsConstructor public class PostService { - private final BoardRepository boardRepository; - private final MemberRepository memberRepository; - - private final PostRepository postRepository; - private final PostLikeRepository postLikeRepository; - private final HotPostRepository hotPostRepository; - private final PostScrapRepository postScrapRepository; - private final PostImageRepository postImageRepository; - private final AwsS3StorageService awsS3StorageService; - private final PostConstantProvider postConstantProvider; - - @Transactional(readOnly = true) - public GetPostResDto findPosts(GetPostReqDto getPostReqDto) { - Long boardId = getPostReqDto.getBoardId(); - Long cursor = getPostReqDto.getCursor(); - int size = getPostReqDto.getSize(); - - if (!boardRepository.existsById(boardId)) { - throw new BoardException(BoardErrorInfo.NO_BOARD); - } - - List posts = postRepository.findWithDetailsByBoardId(boardId, cursor, size); - return GetPostResDto.ofPosts(posts, size); - } - - @Transactional(readOnly = true) - public GetPostDetailResDto findPost(Long postId, Long loginMemberId) { - Post post = postRepository.findWithMemberAndPostImageFetchById(postId) - .orElseThrow(() -> new PostException(PostErrorInfo.NOT_FOUND_POST)); - - if (loginMemberId != null) { - Member member = memberRepository.findById(loginMemberId) - .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); - return GetPostDetailResDto.of(post, member); - } - - return GetPostDetailResDto.of(post, null); - } - - @Transactional - public PostCommonLikeResDto likePost(Long postId, Long loginMemberId) { - Member loginMember = memberRepository.findById(loginMemberId) - .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); - - Post post = postRepository.findWithMemberAndPostImageFetchById(postId) - .orElseThrow(() -> new PostException(PostErrorInfo.NOT_FOUND_POST)); - - PostLike postLike = postLikeRepository.findByPostIdAndMemberId(post.getId(), loginMember.getId()) - .orElse(null); - - Integer likeCount = postLikeRepository.countByPostId(postId); - return togglePostLike(likeCount, postId, loginMember, postLike); - } - - private PostCommonLikeResDto togglePostLike(Integer likeCount, Long postId, Member loginMember, PostLike postLike) { - if (postLike != null) { - deleteLike(postLike); - return new PostCommonLikeResDto(likeCount - 1, false); - } - - saveLike(postId, loginMember); - if (isSelectedHotPost(postId)) { - saveHotPost(postId); - } - return new PostCommonLikeResDto(likeCount + 1, true); - } - - private void saveLike(Long postId, Member loginMember) { - PostLike postLike = PostLike.builder() - .post(postRepository.getReferenceById(postId)) - .member(loginMember) - .build(); - postLikeRepository.save(postLike); - } - - private void deleteLike(PostLike postLike) { - postLikeRepository.delete(postLike); - } - - - private boolean isSelectedHotPost(Long postId) { - return postLikeRepository.countByPostId(postId) >= postConstantProvider.getHOT_POST_LIKES_THRESHOLD(); - } - - private void saveHotPost(Long postId) { - HotPost hotPost = HotPost.builder() - .post(postRepository.findById(postId). - orElseThrow(() -> new PostException(PostErrorInfo.NOT_FOUND_POST))) - .build(); - hotPostRepository.save(hotPost); - } - - @Transactional - public void deleteHotPostsUnderThreshold(Long threshold) { - hotPostRepository.deleteHotPostsUnderThreshold(threshold); - } - - @Transactional - public PostPostScrapResDto scrapPost(Long postId, Long loginMemberId) { - Member loginMember = memberRepository.findById(loginMemberId) - .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); - - PostScrap postScrap = postScrapRepository.findByPostIdAndMemberId(postId, loginMember.getId()) - .orElse(null); - - Integer scrapCount = postScrapRepository.countByPostId(postId); - return togglePostScrap(scrapCount, postId, loginMember, postScrap); - } - - private PostPostScrapResDto togglePostScrap(Integer scrapCount, Long postId, Member loginMember, PostScrap postScrap) { - if (postScrap != null) { - deleteScrapIfAlreadyExists(postScrap); - return new PostPostScrapResDto(scrapCount - 1, false); - } - saveScrap(postId, loginMember); - return new PostPostScrapResDto(scrapCount + 1, true); - } - - private void saveScrap(Long postId, Member loginMember) { - PostScrap postScrap = PostScrap.builder() - .post(postRepository.getReferenceById(postId)) - .member(loginMember) - .build(); - postScrapRepository.save(postScrap); - } - - private void deleteScrapIfAlreadyExists(PostScrap postScrap) { - postScrapRepository.delete(postScrap); - } - - @Transactional - public PostIdElement writePost(Long boardId, Long loginMemberId, PostPostWriteReqDto postPostWriteReqDto) { - Board board = boardRepository.findById(boardId) - .orElseThrow(() -> new BoardException(BoardErrorInfo.NO_BOARD)); - - Member loginMember = memberRepository.findById(loginMemberId) - .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); - - List images = postPostWriteReqDto.getImages(); - - Post post = Post.builder() - .board(board) - .member(loginMember) - .title(postPostWriteReqDto.getTitle()) - .content(postPostWriteReqDto.getContent()) - .anonymity(postPostWriteReqDto.isAnonymity()) - .build(); - postRepository.save(post); - - if (images.size() > 0) { - for (ImageInfo image : images) { - PostImage postImage = PostImage.builder() - .post(post) - .imagePath(image.getImagePath()) - .imageUrl(image.getImageUrl()) - .build(); - postImageRepository.save(postImage); - } - } - return new PostIdElement(post.getId()); - } - - @Transactional - public PostIdElement deletePost(Long postId, Long loginMemberId) { - Post post = postRepository.findByIdWithMember(postId) - .orElseThrow(() -> new PostException(PostErrorInfo.NOT_FOUND_POST)); - - Member loginMember = memberRepository.findById(loginMemberId) - .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); - - if (!post.getMember().getId().equals(loginMember.getId())) { - throw new PostException((PostErrorInfo.UNAUTHORIZED_DELETE_POST)); - } - - deleteAllPostImages(post.getImages()); - postRepository.delete(post); - hotPostRepository.findByPostId(postId).ifPresent(hotPostRepository::delete); - return new PostIdElement(postId); - } - - private void deleteAllPostImages(List images) { - images.forEach(image -> { - try { - awsS3StorageService.deleteObject(image); - - } catch (InfraException e) { - log.error("이미지 삭제에 오류가 발생했습니다."); - } - postImageRepository.delete(image); - }); - } - - @Transactional - public PostIdElement updatePost(Long postId, Long loginMemberId, PostPatchUpdateReqDto postPatchUpdateReqDto) { - Post post = postRepository.findWithMemberAndPostImageFetchById(postId) - .orElseThrow(() -> new PostException(PostErrorInfo.NOT_FOUND_POST)); - - Member loginMember = memberRepository.findById(loginMemberId) - .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); - - if (!post.getMember().getId().equals(loginMember.getId())) { - throw new PostException(PostErrorInfo.UNAUTHORIZED_UPDATE_POST); - } - - post.updatePost(postPatchUpdateReqDto.getTitle(), postPatchUpdateReqDto.getContent(), postPatchUpdateReqDto.isAnonymity()); - postImageRepository.deleteAllInBatch(post.getImages()); - - List images = postPatchUpdateReqDto.getImages(); - if (images.size() > 0) { - for (ImageInfo image : images) { - PostImage postImage = PostImage.builder() - .post(post) - .imagePath(image.getImagePath()) - .imageUrl(image.getImageUrl()) - .build(); - postImageRepository.save(postImage); - } - } - return new PostIdElement(post.getId()); - } - - - @Transactional(readOnly = true) - public GetPostResDto findHotPosts(GetPostHotReqDto getPostHotReqDto) { - Long cursor = getPostHotReqDto.getCursor(); - int size = getPostHotReqDto.getSize(); - - List hotPosts = hotPostRepository.findHotPosts(cursor, size); - return GetPostResDto.ofHotPosts(hotPosts, size); - } - - @Transactional(readOnly = true) - public GetPostResDto findMyPosts(GetPostMyReqDto getPostMyReqDto, Long loginMemberId) { - Long cursor = getPostMyReqDto.getCursor(); - int size = getPostMyReqDto.getSize(); - - Member loginMember = memberRepository.findById(loginMemberId) - .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); - - List posts = postRepository.findWithDetailsByMemberId(loginMember.getId(), cursor, size); - return GetPostResDto.ofPosts(posts, size); - } - - @Transactional(readOnly = true) - public GetPostResDto findMyScrapPosts(GetPostMyReqDto getPostMyScrapReqDto, Long loginMemberId) { - Long cursor = getPostMyScrapReqDto.getCursor(); - int size = getPostMyScrapReqDto.getSize(); - - Member loginMember = memberRepository.findById(loginMemberId) - .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); - - List postScraps = postScrapRepository.findMyScrapPosts(loginMember.getId(), cursor, size); - return GetPostResDto.ofPostScraps(postScraps, size); - } - - @Transactional(readOnly = true) - public GetPostResDto searchPosts(GetPostSearchReqDto getPostSearchReqDto) { - Long boardId = getPostSearchReqDto.getBoardId(); - String keyword = getPostSearchReqDto.getKeyword(); - Long cursor = getPostSearchReqDto.getCursor(); - int size = getPostSearchReqDto.getSize(); - - if (!boardRepository.existsById(boardId)) { - throw new BoardException(BoardErrorInfo.NO_BOARD); - } - - List posts = postRepository.findWithDetailsFetchByBoardIdAndKeyword(boardId, keyword.replaceAll(" ", ""), cursor, size); - return GetPostResDto.ofPosts(posts, size); - } - - @Transactional(readOnly = true) - public GetPostResDto searchHotPosts(GetPostHotSearchReqDto getPostHotSearchReqDto) { - String keyword = getPostHotSearchReqDto.getKeyword(); - Long cursor = getPostHotSearchReqDto.getCursor(); - int size = getPostHotSearchReqDto.getSize(); - - List hotPosts = hotPostRepository.findHotPostsByKeyword(keyword.replaceAll(" ", ""), cursor, size); - return GetPostResDto.ofHotPosts(hotPosts, size); - } + private final BoardRepository boardRepository; + private final MemberRepository memberRepository; + + private final PostRepository postRepository; + private final PostLikeRepository postLikeRepository; + private final HotPostRepository hotPostRepository; + private final PostScrapRepository postScrapRepository; + private final PostImageRepository postImageRepository; + private final AwsS3StorageService awsS3StorageService; + private final PostConstantProvider postConstantProvider; + + @Transactional(readOnly = true) + public GetPostResDto findPosts(GetPostReqDto getPostReqDto) { + Long boardId = getPostReqDto.getBoardId(); + Long cursor = getPostReqDto.getCursor(); + int size = getPostReqDto.getSize(); + + if (!boardRepository.existsById(boardId)) { + throw new BoardException(BoardErrorInfo.NO_BOARD); + } + + List posts = postRepository.findWithDetailsByBoardId(boardId, cursor, size); + return GetPostResDto.ofPosts(posts, size); + } + + @Transactional(readOnly = true) + public GetPostDetailResDto findPost(Long postId, Long loginMemberId) { + Post post = postRepository.findWithMemberAndPostImageFetchById(postId) + .orElseThrow(() -> new PostException(PostErrorInfo.NOT_FOUND_POST)); + + if (loginMemberId != null) { + Member member = memberRepository.findById(loginMemberId) + .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); + return GetPostDetailResDto.of(post, member); + } + + return GetPostDetailResDto.of(post, null); + } + + @Transactional + public PostCommonLikeResDto likePost(Long postId, Long loginMemberId) { + Member loginMember = memberRepository.findById(loginMemberId) + .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); + + Post post = postRepository.findWithMemberAndPostImageFetchById(postId) + .orElseThrow(() -> new PostException(PostErrorInfo.NOT_FOUND_POST)); + + PostLike postLike = postLikeRepository.findByPostIdAndMemberId(post.getId(), loginMember.getId()) + .orElse(null); + + Integer likeCount = postLikeRepository.countByPostId(post.getId()); + return togglePostLike(likeCount, post, loginMember, postLike); + } + + private PostCommonLikeResDto togglePostLike(Integer likeCount, Post post, Member loginMember, PostLike postLike) { + if (postLike != null) { + deleteLike(postLike); + return new PostCommonLikeResDto(likeCount - 1, false); + } + + saveLike(post, loginMember); + if (isSelectedHotPost(likeCount, post)) { + saveHotPost(post); + } + return new PostCommonLikeResDto(likeCount + 1, true); + } + + private void saveLike(Post post, Member loginMember) { + PostLike postLike = PostLike.builder() + .post(post) + .member(loginMember) + .build(); + postLikeRepository.save(postLike); + } + + private void deleteLike(PostLike postLike) { + postLikeRepository.delete(postLike); + } + + private boolean isSelectedHotPost(Integer likeCount, Post post) { + return likeCount + 1 >= postConstantProvider.getHOT_POST_LIKES_THRESHOLD() && + !hotPostRepository.existsByPostId(post.getId()); + } + + private void saveHotPost(Post post) { + HotPost hotPost = HotPost.builder() + .post(post) + .build(); + hotPostRepository.save(hotPost); + } + + @Transactional + public void deleteHotPostsUnderThreshold(Long threshold) { + hotPostRepository.deleteHotPostsUnderThreshold(threshold); + } + + @Transactional + public PostPostScrapResDto scrapPost(Long postId, Long loginMemberId) { + Member loginMember = memberRepository.findById(loginMemberId) + .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); + + PostScrap postScrap = postScrapRepository.findByPostIdAndMemberId(postId, loginMember.getId()) + .orElse(null); + + Integer scrapCount = postScrapRepository.countByPostId(postId); + return togglePostScrap(scrapCount, postId, loginMember, postScrap); + } + + private PostPostScrapResDto togglePostScrap(Integer scrapCount, Long postId, Member loginMember, + PostScrap postScrap) { + if (postScrap != null) { + deleteScrapIfAlreadyExists(postScrap); + return new PostPostScrapResDto(scrapCount - 1, false); + } + saveScrap(postId, loginMember); + return new PostPostScrapResDto(scrapCount + 1, true); + } + + private void saveScrap(Long postId, Member loginMember) { + PostScrap postScrap = PostScrap.builder() + .post(postRepository.getReferenceById(postId)) + .member(loginMember) + .build(); + postScrapRepository.save(postScrap); + } + + private void deleteScrapIfAlreadyExists(PostScrap postScrap) { + postScrapRepository.delete(postScrap); + } + + @Transactional + public PostIdElement writePost(Long boardId, Long loginMemberId, PostPostWriteReqDto postPostWriteReqDto) { + Board board = boardRepository.findById(boardId) + .orElseThrow(() -> new BoardException(BoardErrorInfo.NO_BOARD)); + + Member loginMember = memberRepository.findById(loginMemberId) + .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); + + List images = postPostWriteReqDto.getImages(); + + Post post = Post.builder() + .board(board) + .member(loginMember) + .title(postPostWriteReqDto.getTitle()) + .content(postPostWriteReqDto.getContent()) + .anonymity(postPostWriteReqDto.isAnonymity()) + .build(); + postRepository.save(post); + + if (images.size() > 0) { + for (ImageInfo image : images) { + PostImage postImage = PostImage.builder() + .post(post) + .imagePath(image.getImagePath()) + .imageUrl(image.getImageUrl()) + .build(); + postImageRepository.save(postImage); + } + } + return new PostIdElement(post.getId()); + } + + @Transactional + public PostIdElement deletePost(Long postId, Long loginMemberId) { + Post post = postRepository.findByIdWithMember(postId) + .orElseThrow(() -> new PostException(PostErrorInfo.NOT_FOUND_POST)); + + Member loginMember = memberRepository.findById(loginMemberId) + .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); + + if (!post.getMember().getId().equals(loginMember.getId())) { + throw new PostException((PostErrorInfo.UNAUTHORIZED_DELETE_POST)); + } + + deleteAllPostImages(post.getImages()); + postRepository.delete(post); + hotPostRepository.findByPostId(postId).ifPresent(hotPostRepository::delete); + return new PostIdElement(postId); + } + + private void deleteAllPostImages(List images) { + images.forEach(image -> { + try { + awsS3StorageService.deleteObject(image); + + } catch (InfraException e) { + log.error("이미지 삭제에 오류가 발생했습니다."); + } + postImageRepository.delete(image); + }); + } + + @Transactional + public PostIdElement updatePost(Long postId, Long loginMemberId, PostPatchUpdateReqDto postPatchUpdateReqDto) { + Post post = postRepository.findWithMemberAndPostImageFetchById(postId) + .orElseThrow(() -> new PostException(PostErrorInfo.NOT_FOUND_POST)); + + Member loginMember = memberRepository.findById(loginMemberId) + .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); + + if (!post.getMember().getId().equals(loginMember.getId())) { + throw new PostException(PostErrorInfo.UNAUTHORIZED_UPDATE_POST); + } + + post.updatePost(postPatchUpdateReqDto.getTitle(), postPatchUpdateReqDto.getContent(), + postPatchUpdateReqDto.isAnonymity()); + postImageRepository.deleteAllInBatch(post.getImages()); + + List images = postPatchUpdateReqDto.getImages(); + if (images.size() > 0) { + for (ImageInfo image : images) { + PostImage postImage = PostImage.builder() + .post(post) + .imagePath(image.getImagePath()) + .imageUrl(image.getImageUrl()) + .build(); + postImageRepository.save(postImage); + } + } + return new PostIdElement(post.getId()); + } + + @Transactional(readOnly = true) + public GetPostResDto findHotPosts(GetPostHotReqDto getPostHotReqDto) { + Long cursor = getPostHotReqDto.getCursor(); + int size = getPostHotReqDto.getSize(); + + List hotPosts = hotPostRepository.findHotPosts(cursor, size); + return GetPostResDto.ofHotPosts(hotPosts, size); + } + + @Transactional(readOnly = true) + public GetPostResDto findMyPosts(GetPostMyReqDto getPostMyReqDto, Long loginMemberId) { + Long cursor = getPostMyReqDto.getCursor(); + int size = getPostMyReqDto.getSize(); + + Member loginMember = memberRepository.findById(loginMemberId) + .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); + + List posts = postRepository.findWithDetailsByMemberId(loginMember.getId(), cursor, size); + return GetPostResDto.ofPosts(posts, size); + } + + @Transactional(readOnly = true) + public GetPostResDto findMyScrapPosts(GetPostMyReqDto getPostMyScrapReqDto, Long loginMemberId) { + Long cursor = getPostMyScrapReqDto.getCursor(); + int size = getPostMyScrapReqDto.getSize(); + + Member loginMember = memberRepository.findById(loginMemberId) + .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); + + List postScraps = postScrapRepository.findMyScrapPosts(loginMember.getId(), cursor, size); + return GetPostResDto.ofPostScraps(postScraps, size); + } + + @Transactional(readOnly = true) + public GetPostResDto searchPosts(GetPostSearchReqDto getPostSearchReqDto) { + Long boardId = getPostSearchReqDto.getBoardId(); + String keyword = getPostSearchReqDto.getKeyword(); + Long cursor = getPostSearchReqDto.getCursor(); + int size = getPostSearchReqDto.getSize(); + + if (!boardRepository.existsById(boardId)) { + throw new BoardException(BoardErrorInfo.NO_BOARD); + } + + List posts = postRepository.findWithDetailsFetchByBoardIdAndKeyword(boardId, keyword.replaceAll(" ", ""), + cursor, size); + return GetPostResDto.ofPosts(posts, size); + } + + @Transactional(readOnly = true) + public GetPostResDto searchHotPosts(GetPostHotSearchReqDto getPostHotSearchReqDto) { + String keyword = getPostHotSearchReqDto.getKeyword(); + Long cursor = getPostHotSearchReqDto.getCursor(); + int size = getPostHotSearchReqDto.getSize(); + + List hotPosts = hotPostRepository.findHotPostsByKeyword(keyword.replaceAll(" ", ""), cursor, size); + return GetPostResDto.ofHotPosts(hotPosts, size); + } } From 99e544f4665fe83e9ea999c39937f58b6b3ed9e4 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 20:45:12 +0900 Subject: [PATCH 13/23] =?UTF-8?q?test:=20=EA=B2=8C=EC=8B=9C=EA=B8=80?= =?UTF-8?q?=EC=9D=84=20=EC=A2=8B=EC=95=84=EC=9A=94=20=ED=95=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EC=95=98=EB=8B=A4=EB=A9=B4=20=EC=A2=8B=EC=95=84?= =?UTF-8?q?=EC=9A=94=EA=B0=80=20=EC=A0=80=EC=9E=A5=EB=90=A9=EB=8B=88?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/domain/PostLike.java | 41 ++++++--- .../domain/post/service/PostService.java | 7 +- .../domain/post/service/PostServiceTest.java | 84 ++++++++++++++++++- 3 files changed, 113 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/domain/PostLike.java b/src/main/java/com/ssafy/ssafsound/domain/post/domain/PostLike.java index ebec106a6..283b75218 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/domain/PostLike.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/domain/PostLike.java @@ -1,31 +1,46 @@ package com.ssafy.ssafsound.domain.post.domain; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + import com.ssafy.ssafsound.domain.BaseTimeEntity; import com.ssafy.ssafsound.domain.member.domain.Member; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; - -@Entity(name="post_like") +@Entity(name = "post_like") @Getter @Builder @NoArgsConstructor @AllArgsConstructor public class PostLike extends BaseTimeEntity { - @Id - @Column(name = "post_like_id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; + @Id + @Column(name = "post_like_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id") + private Post post; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "post_id") - private Post post; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; + public static PostLike of(Post post, Member member) { + return PostLike.builder() + .post(post) + .member(member) + .build(); + } } diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java index 77fa3f427..687ad9758 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java @@ -93,7 +93,7 @@ public PostCommonLikeResDto likePost(Long postId, Long loginMemberId) { Member loginMember = memberRepository.findById(loginMemberId) .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); - Post post = postRepository.findWithMemberAndPostImageFetchById(postId) + Post post = postRepository.findById(postId) .orElseThrow(() -> new PostException(PostErrorInfo.NOT_FOUND_POST)); PostLike postLike = postLikeRepository.findByPostIdAndMemberId(post.getId(), loginMember.getId()) @@ -117,10 +117,7 @@ private PostCommonLikeResDto togglePostLike(Integer likeCount, Post post, Member } private void saveLike(Post post, Member loginMember) { - PostLike postLike = PostLike.builder() - .post(post) - .member(loginMember) - .build(); + PostLike postLike = PostLike.of(post, loginMember); postLikeRepository.save(postLike); } diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index 41c7d118d..47f615569 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -26,6 +26,7 @@ import com.ssafy.ssafsound.domain.post.dto.GetPostDetailResDto; import com.ssafy.ssafsound.domain.post.dto.GetPostReqDto; import com.ssafy.ssafsound.domain.post.dto.GetPostResDto; +import com.ssafy.ssafsound.domain.post.dto.PostCommonLikeResDto; import com.ssafy.ssafsound.domain.post.exception.PostErrorInfo; import com.ssafy.ssafsound.domain.post.exception.PostException; import com.ssafy.ssafsound.domain.post.repository.HotPostRepository; @@ -197,7 +198,88 @@ void Given_InvalidLoginMemberId_When_findPost_Then_Success() { } @Test - void likePost() { + @DisplayName("게시글을 좋아요 하지 않았다면 좋아요가 저장됩니다.") + void Given_PostIdAndLoginMemberId_When_SaveLikePost_Then_Success() { + // given + Post post = POST_FIXTURE1; + Member member = MemberFixture.GENERAL_MEMBER; + int likeCount = 4; + + given(postRepository.findById(post.getId())).willReturn(Optional.of(post)); + given(memberRepository.findById(member.getId())).willReturn(Optional.of(member)); + given(postLikeRepository.findByPostIdAndMemberId(post.getId(), member.getId())).willReturn(Optional.empty()); + given(postLikeRepository.countByPostId(post.getId())).willReturn(likeCount); + given(postConstantProvider.getHOT_POST_LIKES_THRESHOLD()).willReturn(10L); + + // when + PostCommonLikeResDto response = postService.likePost(post.getId(), member.getId()); + + // then + assertThat(response).usingRecursiveComparison() + .isEqualTo(new PostCommonLikeResDto(likeCount + 1, true)); + + // verify + verify(postRepository, times(1)).findById(post.getId()); + verify(memberRepository, times(1)).findById(member.getId()); + verify(postLikeRepository, times(1)).findByPostIdAndMemberId(post.getId(), member.getId()); + verify(postLikeRepository, times(1)).countByPostId(post.getId()); + verify(postConstantProvider, times(1)).getHOT_POST_LIKES_THRESHOLD(); + + verify(postLikeRepository, times(0)).delete(any()); + verify(hotPostRepository, times(0)).existsByPostId(any()); + } + + @Test + @DisplayName("게시글을 이미 좋아요 했다면 좋아요가 취소됩니다.") + void Given_PostIdAndLoginMemberId_When_DeleteLikePost_Then_Success() { + } + + @Test + @DisplayName("좋아요가 특정 개수를 달성했다면 Hot 게시글로 등록됩니다.") + void Given_PostIdAndLoginMemberId_When_SelectedHotPost_Then_Success() { + // given + + // when + + // then + + // verify + } + + @Test + @DisplayName("좋아요가 특정 개수를 달성했지만 이미 Hot 게시글이라면 등록되지 않습니다.") + void Given_PostIdAndLoginMemberId_When_AlreadyHotPost_Then_Success() { + // given + + // when + + // then + + // verify + } + + @Test + @DisplayName("유효하지 않은 loginMemberId가 주어졌다면 게시글 좋아요에 예외를 발생합니다.") + void Given_InvalidLoginMemberId_When_likePost_Then_Success() { + // given + + // when + + // then + + // verify + } + + @Test + @DisplayName("유효하지 않은 postId가 주어졌다면 게시글 좋아요에 예외를 발생합니다.") + void Given_InvalidPostId_When_likePost_Then_Success() { + // given + + // when + + // then + + // verify } @Test From 36005d726ee1b24930d5e38c092b1549a2a38e48 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 20:54:27 +0900 Subject: [PATCH 14/23] =?UTF-8?q?test:=20=EA=B2=8C=EC=8B=9C=EA=B8=80?= =?UTF-8?q?=EC=9D=84=20=EC=9D=B4=EB=AF=B8=20=EC=A2=8B=EC=95=84=EC=9A=94=20?= =?UTF-8?q?=ED=96=88=EB=8B=A4=EB=A9=B4=20=EC=A2=8B=EC=95=84=EC=9A=94?= =?UTF-8?q?=EA=B0=80=20=EC=B7=A8=EC=86=8C=EB=90=A9=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/service/PostServiceTest.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index 47f615569..afcb28ff8 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -23,6 +23,7 @@ import com.ssafy.ssafsound.domain.member.exception.MemberException; import com.ssafy.ssafsound.domain.member.repository.MemberRepository; import com.ssafy.ssafsound.domain.post.domain.Post; +import com.ssafy.ssafsound.domain.post.domain.PostLike; import com.ssafy.ssafsound.domain.post.dto.GetPostDetailResDto; import com.ssafy.ssafsound.domain.post.dto.GetPostReqDto; import com.ssafy.ssafsound.domain.post.dto.GetPostResDto; @@ -224,6 +225,7 @@ void Given_PostIdAndLoginMemberId_When_SaveLikePost_Then_Success() { verify(postLikeRepository, times(1)).findByPostIdAndMemberId(post.getId(), member.getId()); verify(postLikeRepository, times(1)).countByPostId(post.getId()); verify(postConstantProvider, times(1)).getHOT_POST_LIKES_THRESHOLD(); + verify(postLikeRepository, times(1)).save(any()); verify(postLikeRepository, times(0)).delete(any()); verify(hotPostRepository, times(0)).existsByPostId(any()); @@ -232,6 +234,35 @@ void Given_PostIdAndLoginMemberId_When_SaveLikePost_Then_Success() { @Test @DisplayName("게시글을 이미 좋아요 했다면 좋아요가 취소됩니다.") void Given_PostIdAndLoginMemberId_When_DeleteLikePost_Then_Success() { + // given + Post post = POST_FIXTURE1; + Member member = MemberFixture.GENERAL_MEMBER; + PostLike postLike = PostLike.of(post, member); + int likeCount = 4; + + given(postRepository.findById(post.getId())).willReturn(Optional.of(post)); + given(memberRepository.findById(member.getId())).willReturn(Optional.of(member)); + given(postLikeRepository.findByPostIdAndMemberId(post.getId(), member.getId())).willReturn( + Optional.of(postLike)); + given(postLikeRepository.countByPostId(post.getId())).willReturn(likeCount); + + // when + PostCommonLikeResDto response = postService.likePost(post.getId(), member.getId()); + + // then + assertThat(response).usingRecursiveComparison() + .isEqualTo(new PostCommonLikeResDto(likeCount - 1, false)); + + // verify + verify(postRepository, times(1)).findById(post.getId()); + verify(memberRepository, times(1)).findById(member.getId()); + verify(postLikeRepository, times(1)).findByPostIdAndMemberId(post.getId(), member.getId()); + verify(postLikeRepository, times(1)).countByPostId(post.getId()); + verify(postLikeRepository, times(1)).delete(any()); + + verify(postConstantProvider, times(0)).getHOT_POST_LIKES_THRESHOLD(); + verify(postLikeRepository, times(0)).save(any()); + verify(hotPostRepository, times(0)).existsByPostId(any()); } @Test From 35d35609143c8cc33d47697313d0d87da4d730cb Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 21:19:22 +0900 Subject: [PATCH 15/23] =?UTF-8?q?test:=20=EC=A2=8B=EC=95=84=EC=9A=94?= =?UTF-8?q?=EA=B0=80=20=ED=8A=B9=EC=A0=95=20=EA=B0=9C=EC=88=98=EB=A5=BC=20?= =?UTF-8?q?=EB=8B=AC=EC=84=B1=ED=96=88=EB=8B=A4=EB=A9=B4=20Hot=20=EA=B2=8C?= =?UTF-8?q?=EC=8B=9C=EA=B8=80=EB=A1=9C=20=EB=93=B1=EB=A1=9D=EB=90=A9?= =?UTF-8?q?=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ssafsound/domain/post/domain/HotPost.java | 33 +++++++++++++------ .../domain/post/service/PostService.java | 4 +-- .../domain/post/service/PostServiceTest.java | 30 ++++++++++++----- 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/domain/HotPost.java b/src/main/java/com/ssafy/ssafsound/domain/post/domain/HotPost.java index 815588207..921a0a45b 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/domain/HotPost.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/domain/HotPost.java @@ -1,26 +1,39 @@ package com.ssafy.ssafsound.domain.post.domain; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; + import com.ssafy.ssafsound.domain.BaseTimeEntity; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; - -@Entity(name="hot_post") +@Entity(name = "hot_post") @Getter @Builder @NoArgsConstructor @AllArgsConstructor public class HotPost extends BaseTimeEntity { - @Id - @Column(name = "hot_post_id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; + @Id + @Column(name = "hot_post_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToOne + @JoinColumn(name = "post_id") + private Post post; - @OneToOne - @JoinColumn(name = "post_id") - private Post post; + public static HotPost from(Post post) { + return HotPost.builder() + .post(post) + .build(); + } } diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java index 687ad9758..9631bde3e 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java @@ -131,9 +131,7 @@ private boolean isSelectedHotPost(Integer likeCount, Post post) { } private void saveHotPost(Post post) { - HotPost hotPost = HotPost.builder() - .post(post) - .build(); + HotPost hotPost = HotPost.from(post); hotPostRepository.save(hotPost); } diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index afcb28ff8..0ecc641b7 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -227,8 +227,7 @@ void Given_PostIdAndLoginMemberId_When_SaveLikePost_Then_Success() { verify(postConstantProvider, times(1)).getHOT_POST_LIKES_THRESHOLD(); verify(postLikeRepository, times(1)).save(any()); - verify(postLikeRepository, times(0)).delete(any()); - verify(hotPostRepository, times(0)).existsByPostId(any()); + verify(hotPostRepository, times(0)).save(any()); } @Test @@ -259,27 +258,42 @@ void Given_PostIdAndLoginMemberId_When_DeleteLikePost_Then_Success() { verify(postLikeRepository, times(1)).findByPostIdAndMemberId(post.getId(), member.getId()); verify(postLikeRepository, times(1)).countByPostId(post.getId()); verify(postLikeRepository, times(1)).delete(any()); - - verify(postConstantProvider, times(0)).getHOT_POST_LIKES_THRESHOLD(); - verify(postLikeRepository, times(0)).save(any()); - verify(hotPostRepository, times(0)).existsByPostId(any()); } @Test @DisplayName("좋아요가 특정 개수를 달성했다면 Hot 게시글로 등록됩니다.") - void Given_PostIdAndLoginMemberId_When_SelectedHotPost_Then_Success() { + void Given_PostIdAndLoginMemberId_When_NotExistsHotPost_Then_Success() { // given + Post post = POST_FIXTURE1; + Member member = MemberFixture.GENERAL_MEMBER; + int likeCount = 9; + + given(postRepository.findById(post.getId())).willReturn(Optional.of(post)); + given(memberRepository.findById(member.getId())).willReturn(Optional.of(member)); + given(postLikeRepository.findByPostIdAndMemberId(post.getId(), member.getId())).willReturn(Optional.empty()); + given(postLikeRepository.countByPostId(post.getId())).willReturn(likeCount); + given(postConstantProvider.getHOT_POST_LIKES_THRESHOLD()).willReturn(10L); // when + PostCommonLikeResDto response = postService.likePost(post.getId(), member.getId()); // then + assertThat(response).usingRecursiveComparison() + .isEqualTo(new PostCommonLikeResDto(likeCount + 1, true)); // verify + verify(postRepository, times(1)).findById(post.getId()); + verify(memberRepository, times(1)).findById(member.getId()); + verify(postLikeRepository, times(1)).findByPostIdAndMemberId(post.getId(), member.getId()); + verify(postLikeRepository, times(1)).countByPostId(post.getId()); + verify(postConstantProvider, times(1)).getHOT_POST_LIKES_THRESHOLD(); + verify(hotPostRepository, times(1)).save(any()); + verify(hotPostRepository, times(1)).existsByPostId(post.getId()); } @Test @DisplayName("좋아요가 특정 개수를 달성했지만 이미 Hot 게시글이라면 등록되지 않습니다.") - void Given_PostIdAndLoginMemberId_When_AlreadyHotPost_Then_Success() { + void Given_PostIdAndLoginMemberId_When_ExistsHotPost_Then_Success() { // given // when From ec317fffe5ba084e79caa50e9cfc9b92ce94d644 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 21:28:31 +0900 Subject: [PATCH 16/23] =?UTF-8?q?test:=20=EC=A2=8B=EC=95=84=EC=9A=94?= =?UTF-8?q?=EA=B0=80=20=ED=8A=B9=EC=A0=95=20=EA=B0=9C=EC=88=98=EB=A5=BC=20?= =?UTF-8?q?=EB=8B=AC=EC=84=B1=ED=96=88=EC=A7=80=EB=A7=8C=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=20Hot=20=EA=B2=8C=EC=8B=9C=EA=B8=80=EC=9D=B4=EB=9D=BC?= =?UTF-8?q?=EB=A9=B4=20=EB=93=B1=EB=A1=9D=EB=90=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EC=8A=B5=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/service/PostService.java | 2 +- .../domain/post/service/PostServiceTest.java | 24 ++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java index 9631bde3e..bd795ec01 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java @@ -126,7 +126,7 @@ private void deleteLike(PostLike postLike) { } private boolean isSelectedHotPost(Integer likeCount, Post post) { - return likeCount + 1 >= postConstantProvider.getHOT_POST_LIKES_THRESHOLD() && + return likeCount + 1 == postConstantProvider.getHOT_POST_LIKES_THRESHOLD() && !hotPostRepository.existsByPostId(post.getId()); } diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index 0ecc641b7..1d4a9c324 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -273,6 +273,7 @@ void Given_PostIdAndLoginMemberId_When_NotExistsHotPost_Then_Success() { given(postLikeRepository.findByPostIdAndMemberId(post.getId(), member.getId())).willReturn(Optional.empty()); given(postLikeRepository.countByPostId(post.getId())).willReturn(likeCount); given(postConstantProvider.getHOT_POST_LIKES_THRESHOLD()).willReturn(10L); + given(hotPostRepository.existsByPostId(post.getId())).willReturn(false); // when PostCommonLikeResDto response = postService.likePost(post.getId(), member.getId()); @@ -287,20 +288,41 @@ void Given_PostIdAndLoginMemberId_When_NotExistsHotPost_Then_Success() { verify(postLikeRepository, times(1)).findByPostIdAndMemberId(post.getId(), member.getId()); verify(postLikeRepository, times(1)).countByPostId(post.getId()); verify(postConstantProvider, times(1)).getHOT_POST_LIKES_THRESHOLD(); - verify(hotPostRepository, times(1)).save(any()); verify(hotPostRepository, times(1)).existsByPostId(post.getId()); + verify(hotPostRepository, times(1)).save(any()); } @Test @DisplayName("좋아요가 특정 개수를 달성했지만 이미 Hot 게시글이라면 등록되지 않습니다.") void Given_PostIdAndLoginMemberId_When_ExistsHotPost_Then_Success() { // given + Post post = POST_FIXTURE1; + Member member = MemberFixture.GENERAL_MEMBER; + int likeCount = 9; + + given(postRepository.findById(post.getId())).willReturn(Optional.of(post)); + given(memberRepository.findById(member.getId())).willReturn(Optional.of(member)); + given(postLikeRepository.findByPostIdAndMemberId(post.getId(), member.getId())).willReturn(Optional.empty()); + given(postLikeRepository.countByPostId(post.getId())).willReturn(likeCount); + given(postConstantProvider.getHOT_POST_LIKES_THRESHOLD()).willReturn(10L); + given(hotPostRepository.existsByPostId(post.getId())).willReturn(true); // when + PostCommonLikeResDto response = postService.likePost(post.getId(), member.getId()); // then + assertThat(response).usingRecursiveComparison() + .isEqualTo(new PostCommonLikeResDto(likeCount + 1, true)); // verify + verify(postRepository, times(1)).findById(post.getId()); + verify(memberRepository, times(1)).findById(member.getId()); + verify(postLikeRepository, times(1)).findByPostIdAndMemberId(post.getId(), member.getId()); + verify(postLikeRepository, times(1)).countByPostId(post.getId()); + verify(postConstantProvider, times(1)).getHOT_POST_LIKES_THRESHOLD(); + verify(hotPostRepository, times(1)).existsByPostId(post.getId()); + + verify(hotPostRepository, times(0)).save(any()); } @Test From 53bc96adbcae3952d3797a54d1288324a34bf300 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 21:39:06 +0900 Subject: [PATCH 17/23] =?UTF-8?q?test:=20=EC=9C=A0=ED=9A=A8=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EC=9D=80=20postId=20=EB=98=90=EB=8A=94=20?= =?UTF-8?q?loginMemberId=EA=B0=80=20=EC=A3=BC=EC=96=B4=EC=A1=8C=EB=8B=A4?= =?UTF-8?q?=EB=A9=B4=20=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EC=A2=8B=EC=95=84?= =?UTF-8?q?=EC=9A=94=EC=97=90=20=EC=98=88=EC=99=B8=EB=A5=BC=20=EB=B0=9C?= =?UTF-8?q?=EC=83=9D=ED=95=A9=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/service/PostServiceTest.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index 1d4a9c324..42719bcf1 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -329,24 +329,38 @@ void Given_PostIdAndLoginMemberId_When_ExistsHotPost_Then_Success() { @DisplayName("유효하지 않은 loginMemberId가 주어졌다면 게시글 좋아요에 예외를 발생합니다.") void Given_InvalidLoginMemberId_When_likePost_Then_Success() { // given + Post post = POST_FIXTURE1; + Long memberId = -1L; - // when + given(memberRepository.findById(memberId)).willReturn(Optional.empty()); - // then + // when, then + MemberException exception = assertThrows(MemberException.class, + () -> postService.likePost(post.getId(), memberId)); + assertEquals(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID, exception.getInfo()); // verify + verify(memberRepository, times(1)).findById(memberId); } @Test @DisplayName("유효하지 않은 postId가 주어졌다면 게시글 좋아요에 예외를 발생합니다.") void Given_InvalidPostId_When_likePost_Then_Success() { // given + Long postId = -1L; + Member member = MemberFixture.GENERAL_MEMBER; - // when + given(memberRepository.findById(member.getId())).willReturn(Optional.of(member)); + given(postRepository.findById(postId)).willReturn(Optional.empty()); - // then + // when, then + PostException exception = assertThrows(PostException.class, () -> postService.likePost(postId, member.getId())); + assertEquals(PostErrorInfo.NOT_FOUND_POST, exception.getInfo()); // verify + verify(memberRepository, times(1)).findById(member.getId()); + verify(postRepository, times(1)).findById(postId); + } @Test From f09e6991f4efd066c46cb267406914f839f3b9f2 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 21:45:19 +0900 Subject: [PATCH 18/23] =?UTF-8?q?fix:=20=EC=9C=A0=ED=9A=A8=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EC=9D=80=20=EA=B2=8C=EC=8B=9C=EA=B8=80?= =?UTF-8?q?=EC=9D=84=20=EC=8A=A4=ED=81=AC=EB=9E=A9=ED=96=88=EC=9D=84=20?= =?UTF-8?q?=EB=95=8C=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/domain/PostScrap.java | 41 +++++++++++++------ .../domain/post/service/PostService.java | 20 ++++----- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/domain/PostScrap.java b/src/main/java/com/ssafy/ssafsound/domain/post/domain/PostScrap.java index 9aeb43cf7..a214500e0 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/domain/PostScrap.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/domain/PostScrap.java @@ -1,30 +1,45 @@ package com.ssafy.ssafsound.domain.post.domain; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + import com.ssafy.ssafsound.domain.member.domain.Member; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; - -@Entity(name="post_scrap") +@Entity(name = "post_scrap") @Getter @Builder @NoArgsConstructor @AllArgsConstructor public class PostScrap { - @Id - @Column(name = "post_scrap_id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; + @Id + @Column(name = "post_scrap_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id") + private Post post; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "post_id") - private Post post; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; + public static PostScrap of(Post post, Member member) { + return PostScrap.builder() + .post(post) + .member(member) + .build(); + } } diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java index bd795ec01..310849c8b 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java @@ -145,28 +145,28 @@ public PostPostScrapResDto scrapPost(Long postId, Long loginMemberId) { Member loginMember = memberRepository.findById(loginMemberId) .orElseThrow(() -> new MemberException(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID)); - PostScrap postScrap = postScrapRepository.findByPostIdAndMemberId(postId, loginMember.getId()) + Post post = postRepository.findById(postId) + .orElseThrow(() -> new PostException(PostErrorInfo.NOT_FOUND_POST)); + + PostScrap postScrap = postScrapRepository.findByPostIdAndMemberId(post.getId(), loginMember.getId()) .orElse(null); - Integer scrapCount = postScrapRepository.countByPostId(postId); - return togglePostScrap(scrapCount, postId, loginMember, postScrap); + Integer scrapCount = postScrapRepository.countByPostId(post.getId()); + return togglePostScrap(scrapCount, post, loginMember, postScrap); } - private PostPostScrapResDto togglePostScrap(Integer scrapCount, Long postId, Member loginMember, + private PostPostScrapResDto togglePostScrap(Integer scrapCount, Post post, Member loginMember, PostScrap postScrap) { if (postScrap != null) { deleteScrapIfAlreadyExists(postScrap); return new PostPostScrapResDto(scrapCount - 1, false); } - saveScrap(postId, loginMember); + saveScrap(post, loginMember); return new PostPostScrapResDto(scrapCount + 1, true); } - private void saveScrap(Long postId, Member loginMember) { - PostScrap postScrap = PostScrap.builder() - .post(postRepository.getReferenceById(postId)) - .member(loginMember) - .build(); + private void saveScrap(Post post, Member loginMember) { + PostScrap postScrap = PostScrap.of(post, loginMember); postScrapRepository.save(postScrap); } From 8f3421802df124fd0b80c590dc46a5caab51c452 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 22:04:16 +0900 Subject: [PATCH 19/23] =?UTF-8?q?test:=20=EA=B2=8C=EC=8B=9C=EA=B8=80?= =?UTF-8?q?=EC=9D=84=20=EC=8A=A4=ED=81=AC=EB=9E=A9=20=ED=95=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EC=95=98=EB=8B=A4=EB=A9=B4=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=9E=A9=EC=9D=B4=20=EC=A0=80=EC=9E=A5=EB=90=A9=EB=8B=88?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/service/PostServiceTest.java | 63 ++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index 42719bcf1..019a5f9ee 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -28,6 +28,7 @@ import com.ssafy.ssafsound.domain.post.dto.GetPostReqDto; import com.ssafy.ssafsound.domain.post.dto.GetPostResDto; import com.ssafy.ssafsound.domain.post.dto.PostCommonLikeResDto; +import com.ssafy.ssafsound.domain.post.dto.PostPostScrapResDto; import com.ssafy.ssafsound.domain.post.exception.PostErrorInfo; import com.ssafy.ssafsound.domain.post.exception.PostException; import com.ssafy.ssafsound.domain.post.repository.HotPostRepository; @@ -360,15 +361,73 @@ void Given_InvalidPostId_When_likePost_Then_Success() { // verify verify(memberRepository, times(1)).findById(member.getId()); verify(postRepository, times(1)).findById(postId); + } + + @Test + @DisplayName("게시글을 스크랩 하지 않았다면 스크랩이 저장됩니다.") + void Given_PostIdAndLoginMemberId_When_SaveScrapPost_Then_Success() { + // given + Member member = MemberFixture.GENERAL_MEMBER; + Post post = POST_FIXTURE1; + int scrapCount = 10; + + given(memberRepository.findById(member.getId())).willReturn(Optional.of(member)); + given(postRepository.findById(post.getId())).willReturn(Optional.of(post)); + given(postScrapRepository.findByPostIdAndMemberId(post.getId(), member.getId())).willReturn(Optional.empty()); + given(postScrapRepository.countByPostId(post.getId())).willReturn(scrapCount); + + // when + PostPostScrapResDto response = postService.scrapPost(post.getId(), member.getId()); + + // then + assertThat(response).usingRecursiveComparison() + .isEqualTo(new PostPostScrapResDto(scrapCount + 1, true)); + + // verify + verify(memberRepository, times(1)).findById(member.getId()); + verify(postRepository, times(1)).findById(post.getId()); + verify(postScrapRepository, times(1)).findByPostIdAndMemberId(post.getId(), member.getId()); + verify(postScrapRepository, times(1)).countByPostId(post.getId()); + verify(postScrapRepository, times(1)).save(any()); + } + + @Test + @DisplayName("게시글을 이미 스크랩 했다면 스크랩이 취소됩니다.") + void Given_PostIdAndLoginMemberId_When_DeleteScrapPost_Then_Success() { + // given + + // when + + // then + + // verify } @Test - void deleteHotPostsUnderThreshold() { + @DisplayName("유효하지 않은 loginMemberId가 주어졌다면 게시글 스크랩에 예외를 발생합니다.") + void Given_InvalidLoginMemberId_When_scrapPost_Then_Success() { + // given + + // when + + // then + + // verify + } @Test - void scrapPost() { + @DisplayName("유효하지 않은 postId가 주어졌다면 게시글 스크랩에 예외를 발생합니다.") + void Given_InvalidPostId_When_scrapPost_Then_Success() { + // given + + // when + + // then + + // verify + } @Test From 239fece1b34bb0ce1547e8fc58b13e5d9f754115 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 22:06:28 +0900 Subject: [PATCH 20/23] =?UTF-8?q?test:=20=EA=B2=8C=EC=8B=9C=EA=B8=80?= =?UTF-8?q?=EC=9D=84=20=EC=9D=B4=EB=AF=B8=20=EC=8A=A4=ED=81=AC=EB=9E=A9=20?= =?UTF-8?q?=ED=96=88=EB=8B=A4=EB=A9=B4=20=EC=8A=A4=ED=81=AC=EB=9E=A9?= =?UTF-8?q?=EC=9D=B4=20=EC=B7=A8=EC=86=8C=EB=90=A9=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/service/PostServiceTest.java | 52 ++++++++++--------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index 019a5f9ee..0897d8f4d 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -24,6 +24,7 @@ import com.ssafy.ssafsound.domain.member.repository.MemberRepository; import com.ssafy.ssafsound.domain.post.domain.Post; import com.ssafy.ssafsound.domain.post.domain.PostLike; +import com.ssafy.ssafsound.domain.post.domain.PostScrap; import com.ssafy.ssafsound.domain.post.dto.GetPostDetailResDto; import com.ssafy.ssafsound.domain.post.dto.GetPostReqDto; import com.ssafy.ssafsound.domain.post.dto.GetPostResDto; @@ -76,11 +77,7 @@ class PostServiceTest { @DisplayName("유효한 boardId, cursor, size가 주어졌다면 게시글 목록 조회가 성공합니다.") void Given_BoardIdAndCursorAndSize_When_findPosts_Then_Success() { // given - GetPostReqDto getPostReqDto = GetPostReqDto.builder() - .boardId(1L) - .cursor(-1L) - .size(10) - .build(); + GetPostReqDto getPostReqDto = GetPostReqDto.builder().boardId(1L).cursor(-1L).size(10).build(); List posts = List.of(POST_FIXTURE1, POST_FIXTURE2); @@ -105,11 +102,7 @@ void Given_BoardIdAndCursorAndSize_When_findPosts_Then_Success() { @DisplayName("유효하지 않은 boardId가 주어졌다면 게시글 목록 조회에 예외를 발생합니다.") void Given_BoardId_When_findPosts_Then_Fail() { // given - GetPostReqDto getPostReqDto = GetPostReqDto.builder() - .boardId(100L) - .cursor(-1L) - .size(10) - .build(); + GetPostReqDto getPostReqDto = GetPostReqDto.builder().boardId(100L).cursor(-1L).size(10).build(); given(boardRepository.existsById(getPostReqDto.getBoardId())).willReturn(false); @@ -135,8 +128,7 @@ void Given_PostIdAndLoginMemberId_When_findPost_Then_Success() { GetPostDetailResDto response = postService.findPost(post.getId(), member.getId()); // then - assertThat(response).usingRecursiveComparison() - .isEqualTo(GetPostDetailResDto.of(post, member)); + assertThat(response).usingRecursiveComparison().isEqualTo(GetPostDetailResDto.of(post, member)); // verify verify(postRepository, times(1)).findWithMemberAndPostImageFetchById(post.getId()); @@ -155,8 +147,7 @@ void Given_PostId_When_findPost_Then_Success() { GetPostDetailResDto response = postService.findPost(post.getId(), null); // then - assertThat(response).usingRecursiveComparison() - .isEqualTo(GetPostDetailResDto.of(post, null)); + assertThat(response).usingRecursiveComparison().isEqualTo(GetPostDetailResDto.of(post, null)); // verify verify(postRepository, times(1)).findWithMemberAndPostImageFetchById(post.getId()); @@ -217,8 +208,7 @@ void Given_PostIdAndLoginMemberId_When_SaveLikePost_Then_Success() { PostCommonLikeResDto response = postService.likePost(post.getId(), member.getId()); // then - assertThat(response).usingRecursiveComparison() - .isEqualTo(new PostCommonLikeResDto(likeCount + 1, true)); + assertThat(response).usingRecursiveComparison().isEqualTo(new PostCommonLikeResDto(likeCount + 1, true)); // verify verify(postRepository, times(1)).findById(post.getId()); @@ -250,8 +240,7 @@ void Given_PostIdAndLoginMemberId_When_DeleteLikePost_Then_Success() { PostCommonLikeResDto response = postService.likePost(post.getId(), member.getId()); // then - assertThat(response).usingRecursiveComparison() - .isEqualTo(new PostCommonLikeResDto(likeCount - 1, false)); + assertThat(response).usingRecursiveComparison().isEqualTo(new PostCommonLikeResDto(likeCount - 1, false)); // verify verify(postRepository, times(1)).findById(post.getId()); @@ -280,8 +269,7 @@ void Given_PostIdAndLoginMemberId_When_NotExistsHotPost_Then_Success() { PostCommonLikeResDto response = postService.likePost(post.getId(), member.getId()); // then - assertThat(response).usingRecursiveComparison() - .isEqualTo(new PostCommonLikeResDto(likeCount + 1, true)); + assertThat(response).usingRecursiveComparison().isEqualTo(new PostCommonLikeResDto(likeCount + 1, true)); // verify verify(postRepository, times(1)).findById(post.getId()); @@ -312,8 +300,7 @@ void Given_PostIdAndLoginMemberId_When_ExistsHotPost_Then_Success() { PostCommonLikeResDto response = postService.likePost(post.getId(), member.getId()); // then - assertThat(response).usingRecursiveComparison() - .isEqualTo(new PostCommonLikeResDto(likeCount + 1, true)); + assertThat(response).usingRecursiveComparison().isEqualTo(new PostCommonLikeResDto(likeCount + 1, true)); // verify verify(postRepository, times(1)).findById(post.getId()); @@ -380,8 +367,7 @@ void Given_PostIdAndLoginMemberId_When_SaveScrapPost_Then_Success() { PostPostScrapResDto response = postService.scrapPost(post.getId(), member.getId()); // then - assertThat(response).usingRecursiveComparison() - .isEqualTo(new PostPostScrapResDto(scrapCount + 1, true)); + assertThat(response).usingRecursiveComparison().isEqualTo(new PostPostScrapResDto(scrapCount + 1, true)); // verify verify(memberRepository, times(1)).findById(member.getId()); @@ -395,13 +381,29 @@ void Given_PostIdAndLoginMemberId_When_SaveScrapPost_Then_Success() { @DisplayName("게시글을 이미 스크랩 했다면 스크랩이 취소됩니다.") void Given_PostIdAndLoginMemberId_When_DeleteScrapPost_Then_Success() { // given + Member member = MemberFixture.GENERAL_MEMBER; + Post post = POST_FIXTURE1; + PostScrap postScrap = PostScrap.of(post, member); + int scrapCount = 10; + + given(memberRepository.findById(member.getId())).willReturn(Optional.of(member)); + given(postRepository.findById(post.getId())).willReturn(Optional.of(post)); + given(postScrapRepository.findByPostIdAndMemberId(post.getId(), member.getId())).willReturn( + Optional.of(postScrap)); + given(postScrapRepository.countByPostId(post.getId())).willReturn(scrapCount); // when + PostPostScrapResDto response = postService.scrapPost(post.getId(), member.getId()); // then + assertThat(response).usingRecursiveComparison().isEqualTo(new PostPostScrapResDto(scrapCount - 1, false)); // verify - + verify(memberRepository, times(1)).findById(member.getId()); + verify(postRepository, times(1)).findById(post.getId()); + verify(postScrapRepository, times(1)).findByPostIdAndMemberId(post.getId(), member.getId()); + verify(postScrapRepository, times(1)).countByPostId(post.getId()); + verify(postScrapRepository, times(1)).delete(any()); } @Test From 96291baf673f14c099a579a677cee09d220eb613 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 22:09:34 +0900 Subject: [PATCH 21/23] =?UTF-8?q?test:=20=EC=9C=A0=ED=9A=A8=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EC=9D=80=20loginMemberId=EA=B0=80=20?= =?UTF-8?q?=EC=A3=BC=EC=96=B4=EC=A1=8C=EB=8B=A4=EB=A9=B4=20=EA=B2=8C?= =?UTF-8?q?=EC=8B=9C=EA=B8=80=20=EC=8A=A4=ED=81=AC=EB=9E=A9=EC=97=90=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EB=A5=BC=20=EB=B0=9C=EC=83=9D=ED=95=A9?= =?UTF-8?q?=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/service/PostServiceTest.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index 0897d8f4d..ee0bbe454 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -410,13 +410,18 @@ void Given_PostIdAndLoginMemberId_When_DeleteScrapPost_Then_Success() { @DisplayName("유효하지 않은 loginMemberId가 주어졌다면 게시글 스크랩에 예외를 발생합니다.") void Given_InvalidLoginMemberId_When_scrapPost_Then_Success() { // given + Long memberId = -101L; + Post post = POST_FIXTURE1; - // when + given(memberRepository.findById(memberId)).willReturn(Optional.empty()); - // then + // when, then + MemberException exception = assertThrows(MemberException.class, + () -> postService.scrapPost(post.getId(), memberId)); + assertEquals(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID, exception.getInfo()); // verify - + verify(memberRepository, times(1)).findById(memberId); } @Test From 379aab55332124c794bbe4acf267af41387341f6 Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 16 Sep 2023 22:12:07 +0900 Subject: [PATCH 22/23] =?UTF-8?q?test:=20=EC=9C=A0=ED=9A=A8=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EC=9D=80=20postId=EA=B0=80=20=EC=A3=BC?= =?UTF-8?q?=EC=96=B4=EC=A1=8C=EB=8B=A4=EB=A9=B4=20=EA=B2=8C=EC=8B=9C?= =?UTF-8?q?=EA=B8=80=20=EC=8A=A4=ED=81=AC=EB=9E=A9=EC=97=90=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EB=A5=BC=20=EB=B0=9C=EC=83=9D=ED=95=A9=EB=8B=88?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/service/PostServiceTest.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index ee0bbe454..31a1834a9 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -428,13 +428,20 @@ void Given_InvalidLoginMemberId_When_scrapPost_Then_Success() { @DisplayName("유효하지 않은 postId가 주어졌다면 게시글 스크랩에 예외를 발생합니다.") void Given_InvalidPostId_When_scrapPost_Then_Success() { // given + Member member = MemberFixture.MEMBER_JAMES; + Long postId = 101021242313L; - // when + given(memberRepository.findById(member.getId())).willReturn(Optional.of(member)); + given(postRepository.findById(postId)).willReturn(Optional.empty()); - // then + // when, then + PostException exception = assertThrows(PostException.class, + () -> postService.scrapPost(postId, member.getId())); + assertEquals(PostErrorInfo.NOT_FOUND_POST, exception.getInfo()); // verify - + verify(memberRepository, times(1)).findById(member.getId()); + verify(postRepository, times(1)).findById(postId); } @Test From edacb737717690a824f42edda1b69fad47845f3d Mon Sep 17 00:00:00 2001 From: jjuny7712 Date: Sat, 23 Sep 2023 18:28:59 +0900 Subject: [PATCH 23/23] =?UTF-8?q?fix:=20commentGroup=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81=20NativeQuery=EB=A1=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/comment/domain/Comment.java | 1 + .../comment/repository/CommentRepository.java | 28 ++++++++++++------- .../comment/service/CommentService.java | 3 +- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/ssafy/ssafsound/domain/comment/domain/Comment.java b/src/main/java/com/ssafy/ssafsound/domain/comment/domain/Comment.java index 9ce1c141f..694e4a90e 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/comment/domain/Comment.java +++ b/src/main/java/com/ssafy/ssafsound/domain/comment/domain/Comment.java @@ -1,6 +1,7 @@ package com.ssafy.ssafsound.domain.comment.domain; import com.ssafy.ssafsound.domain.BaseTimeEntity; +import com.ssafy.ssafsound.domain.comment.dto.PostCommentWriteReqDto; import com.ssafy.ssafsound.domain.member.domain.Member; import com.ssafy.ssafsound.domain.post.domain.Post; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/ssafy/ssafsound/domain/comment/repository/CommentRepository.java b/src/main/java/com/ssafy/ssafsound/domain/comment/repository/CommentRepository.java index 6d1074955..6adee2a36 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/comment/repository/CommentRepository.java +++ b/src/main/java/com/ssafy/ssafsound/domain/comment/repository/CommentRepository.java @@ -1,21 +1,29 @@ package com.ssafy.ssafsound.domain.comment.repository; -import com.ssafy.ssafsound.domain.comment.domain.Comment; -import org.springframework.data.domain.Pageable; +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import java.util.List; +import com.ssafy.ssafsound.domain.comment.domain.Comment; @Repository public interface CommentRepository extends JpaRepository { - @Query("SELECT c FROM comment c " + - "JOIN FETCH c.commentNumber " + - "JOIN FETCH c.member " + - "JOIN FETCH c.commentGroup g " + - "WHERE c.post.id = :postId " + - "ORDER BY g.id ") - List findAllPostIdWithDetailsFetchOrderByCommentGroupId(@Param("postId") Long postId); + @Query("SELECT c FROM comment c " + + "JOIN FETCH c.commentNumber " + + "JOIN FETCH c.member " + + "JOIN FETCH c.commentGroup g " + + "WHERE c.post.id = :postId " + + "ORDER BY g.id ") + List findAllPostIdWithDetailsFetchOrderByCommentGroupId(@Param("postId") Long postId); + + @Modifying + @Query(value = "update comment " + + "set comment_group = :id " + + "where comment_id = :id", nativeQuery = true) + void updateByCommentGroup(@Param("id") Long id); + } diff --git a/src/main/java/com/ssafy/ssafsound/domain/comment/service/CommentService.java b/src/main/java/com/ssafy/ssafsound/domain/comment/service/CommentService.java index 3d83b35d2..8ac19cfe4 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/comment/service/CommentService.java +++ b/src/main/java/com/ssafy/ssafsound/domain/comment/service/CommentService.java @@ -14,6 +14,7 @@ import com.ssafy.ssafsound.domain.member.exception.MemberErrorInfo; import com.ssafy.ssafsound.domain.member.exception.MemberException; import com.ssafy.ssafsound.domain.member.repository.MemberRepository; +import com.ssafy.ssafsound.domain.post.domain.Post; import com.ssafy.ssafsound.domain.post.dto.PostCommonLikeResDto; import com.ssafy.ssafsound.domain.post.exception.PostErrorInfo; import com.ssafy.ssafsound.domain.post.exception.PostException; @@ -69,7 +70,7 @@ public CommentIdElement writeComment(Long postId, Long loginMemberId, PostCommen .build(); comment = commentRepository.save(comment); - comment.setCommentGroup(comment); + commentRepository.updateByCommentGroup(comment.getId()); return new CommentIdElement(comment.getId()); }