diff --git a/src/main/java/com/chooz/post/application/DateCloseScheduler.java b/src/main/java/com/chooz/post/application/DateCloseScheduler.java index b5221aa..5d85ed0 100644 --- a/src/main/java/com/chooz/post/application/DateCloseScheduler.java +++ b/src/main/java/com/chooz/post/application/DateCloseScheduler.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; import java.util.List; @Slf4j @@ -18,9 +19,9 @@ public class DateCloseScheduler { private final PostRepository postRepository; @Transactional - @Scheduled(fixedDelay = 1000 * 60) + @Scheduled(fixedDelay = 1000) public void closePostsByDate() { - log.info("마감 스케줄링 시작"); + log.info("마감 스케줄링 시작 | 서버 시간: {}", LocalDateTime.now()); List postsNeedToClose = postRepository.findPostsNeedToClose(); postsNeedToClose.forEach(Post::close); log.info("총 {}개 게시글 마감", postsNeedToClose.size()); diff --git a/src/main/java/com/chooz/post/domain/CloseOption.java b/src/main/java/com/chooz/post/domain/CloseOption.java index d1f3dcc..2e15628 100644 --- a/src/main/java/com/chooz/post/domain/CloseOption.java +++ b/src/main/java/com/chooz/post/domain/CloseOption.java @@ -59,7 +59,7 @@ private static void validateVoterCloseType(Integer maxVoterCount) { } private static void validateDateCloseType(LocalDateTime closedAt) { - if (Objects.isNull(closedAt) || closedAt.isBefore(LocalDateTime.now().plusHours(1))) { + if (Objects.isNull(closedAt) || closedAt.isBefore(LocalDateTime.now().plusMinutes(59))) { throw new BadRequestException(ErrorCode.INVALID_DATE_CLOSE_OPTION); } } diff --git a/src/main/java/com/chooz/post/persistence/PostQueryDslRepository.java b/src/main/java/com/chooz/post/persistence/PostQueryDslRepository.java index 9f6d6fe..e2ad17b 100644 --- a/src/main/java/com/chooz/post/persistence/PostQueryDslRepository.java +++ b/src/main/java/com/chooz/post/persistence/PostQueryDslRepository.java @@ -122,7 +122,7 @@ public Slice findPostsWithVoteCountByUserId(Long userId, Long .select(new QPostWithVoteCount( post, JPAExpressions - .select(vote.userId.countDistinct()) + .select(vote.userId.count()) .from(vote) .where( vote.postId.eq(post.id), diff --git a/src/test/java/com/chooz/post/application/PostQueryServiceTest.java b/src/test/java/com/chooz/post/application/PostQueryServiceTest.java index d071888..4714a04 100644 --- a/src/test/java/com/chooz/post/application/PostQueryServiceTest.java +++ b/src/test/java/com/chooz/post/application/PostQueryServiceTest.java @@ -126,6 +126,89 @@ void findUserPosts2() throws Exception { ); } + @Test + @DisplayName("유저가 작성한 게시글 조회 - 중복 투표") + void findUserPosts_multiple() { + //given + User user = userRepository.save(UserFixture.createDefaultUser()); + Post post1 = postRepository.save(PostFixture.createPostBuilder() + .userId(user.getId()) + .pollOption(PostFixture.multiplePollOption()) + .build()); + Post post2 = postRepository.save(PostFixture.createPostBuilder() + .userId(user.getId()) + .pollOption(PostFixture.multiplePollOption()) + .build()); + //유저1 게시글1 선택지 1, 2 복수 투표 + voteRepository.save(VoteFixture.createDefaultVote(user.getId(), post1.getId(), post1.getPollChoices().get(0).getId())); + voteRepository.save(VoteFixture.createDefaultVote(user.getId(), post1.getId(), post1.getPollChoices().get(1).getId())); + + //유저1 게시글2 선택지 1 단일 투표 + voteRepository.save(VoteFixture.createDefaultVote(user.getId(), post2.getId(), post2.getPollChoices().get(0).getId())); + + //when + var response = postService.findUserPosts(user.getId(), null, 10); + + //then + List data = response.data(); + assertAll( + () -> assertThat(response.data()).hasSize(2), + () -> assertThat(response.hasNext()).isFalse(), + + () -> assertThat(data.getFirst().id()).isEqualTo(post2.getId()), + () -> assertThat(data.getFirst().title()).isEqualTo(post2.getTitle()), + + () -> assertThat(data.getFirst().postVoteInfo().mostVotedPollChoice().title()).isEqualTo(post2.getPollChoices().get(0).getTitle()), + () -> assertThat(data.getFirst().postVoteInfo().totalVoterCount()).isEqualTo(1), + () -> assertThat(data.getFirst().postVoteInfo().mostVotedPollChoice().voteCount()).isEqualTo(1), + () -> assertThat(data.getFirst().postVoteInfo().mostVotedPollChoice().voteRatio()).isEqualTo("100"), + + () -> assertThat(data.get(1).id()).isEqualTo(post1.getId()), + () -> assertThat(data.get(1).title()).isEqualTo(post1.getTitle()), + + () -> assertThat(data.get(1).postVoteInfo().mostVotedPollChoice().title()).isEqualTo(post1.getPollChoices().get(0).getTitle()), + () -> assertThat(data.get(1).postVoteInfo().totalVoterCount()).isEqualTo(2), + () -> assertThat(data.get(1).postVoteInfo().mostVotedPollChoice().voteCount()).isEqualTo(1), + () -> assertThat(data.get(1).postVoteInfo().mostVotedPollChoice().voteRatio()).isEqualTo("50") + ); + } + + @Test + @DisplayName("유저가 작성한 게시글 조회 - 중복 투표2") + void findUserPosts_multiple2() { + //given + User user = userRepository.save(UserFixture.createDefaultUser()); + User user2 = userRepository.save(UserFixture.createDefaultUser()); + Post post = postRepository.save(PostFixture.createPostBuilder() + .userId(user.getId()) + .pollOption(PostFixture.multiplePollOption()) + .build()); + //유저1 선택지 1, 2 복수 투표 + voteRepository.save(VoteFixture.createDefaultVote(user.getId(), post.getId(), post.getPollChoices().get(0).getId())); + voteRepository.save(VoteFixture.createDefaultVote(user.getId(), post.getId(), post.getPollChoices().get(1).getId())); + + //유저2 선택지 1 단일 투표 + voteRepository.save(VoteFixture.createDefaultVote(user.getId(), post.getId(), post.getPollChoices().get(0).getId())); + + //when + var response = postService.findUserPosts(user.getId(), null, 10); + + //then + List data = response.data(); + assertAll( + () -> assertThat(response.data()).hasSize(1), + () -> assertThat(response.hasNext()).isFalse(), + + () -> assertThat(data.getFirst().id()).isEqualTo(post.getId()), + () -> assertThat(data.getFirst().title()).isEqualTo(post.getTitle()), + + () -> assertThat(data.getFirst().postVoteInfo().mostVotedPollChoice().title()).isEqualTo(post.getPollChoices().get(0).getTitle()), + () -> assertThat(data.getFirst().postVoteInfo().totalVoterCount()).isEqualTo(3), + () -> assertThat(data.getFirst().postVoteInfo().mostVotedPollChoice().voteCount()).isEqualTo(2), + () -> assertThat(data.getFirst().postVoteInfo().mostVotedPollChoice().voteRatio()).isEqualTo("67") + ); + } + @Test @DisplayName("유저가 투표한 게시글 조회 - 커서 null인 경우") void findVotedPosts() throws Exception { @@ -151,38 +234,7 @@ void findVotedPosts() throws Exception { } @Test - @DisplayName("피드 조회 - 내 게시글 1개, 공개 게시글 15개, 투표 10개, 댓글 20개") - void findFeed() throws Exception { - //given - int size = 20; - User user1 = userRepository.save(createUserBuilder().build()); - User user2 = userRepository.save(createUserBuilder().build()); - - List publicPosts = createPostsWithScope(user2, Scope.PUBLIC, 15); - createPostsWithScope(user2, Scope.PRIVATE, 3); - Post myPost = postRepository.save(createPostBuilder().userId(user1.getId()).build()); - - createVotes(user1, publicPosts.getFirst(), 10); - createComments(user1, publicPosts.getFirst(), 20); - - List publicPostVotes = voteRepository.findByPostIdAndDeletedFalse(publicPosts.getFirst().getId()); - List publicPostComments = commentRepository.findByPostIdAndDeletedFalse(publicPosts.getFirst().getId()); - - //when - CursorBasePaginatedResponse response = postService.findFeed(user1.getId(), null, size); - - //then - assertAll( - () -> assertThat(response.data().size()).isEqualTo(16), - () -> assertThat(response.data().getLast().voterCount()).isEqualTo(1), - () -> assertThat(response.data().getLast().commentCount()).isEqualTo(publicPostComments.size()), - () -> assertThat(response.data().getLast().isAuthor()).isFalse(), - () -> assertThat(response.data().getFirst().isAuthor()).isTrue() - ); - } - - @Test - @DisplayName("투표 현황 조회 - 중복 투표") + @DisplayName("유저가 투표한 게시글 조회 - 중복 투표") void findVotedPosts_multiple() { //given User user = userRepository.save(UserFixture.createDefaultUser()); @@ -214,7 +266,7 @@ void findVotedPosts_multiple() { } @Test - @DisplayName("투표 현황 조회 - 중복 투표2") + @DisplayName("유저가 투표한 게시글 조회 - 중복 투표2") void findVotedPosts_multiple2() { //given User user = userRepository.save(UserFixture.createDefaultUser()); @@ -249,6 +301,37 @@ void findVotedPosts_multiple2() { ); } + @Test + @DisplayName("피드 조회 - 내 게시글 1개, 공개 게시글 15개, 투표 10개, 댓글 20개") + void findFeed() throws Exception { + //given + int size = 20; + User user1 = userRepository.save(createUserBuilder().build()); + User user2 = userRepository.save(createUserBuilder().build()); + + List publicPosts = createPostsWithScope(user2, Scope.PUBLIC, 15); + createPostsWithScope(user2, Scope.PRIVATE, 3); + Post myPost = postRepository.save(createPostBuilder().userId(user1.getId()).build()); + + createVotes(user1, publicPosts.getFirst(), 10); + createComments(user1, publicPosts.getFirst(), 20); + + List publicPostVotes = voteRepository.findByPostIdAndDeletedFalse(publicPosts.getFirst().getId()); + List publicPostComments = commentRepository.findByPostIdAndDeletedFalse(publicPosts.getFirst().getId()); + + //when + CursorBasePaginatedResponse response = postService.findFeed(user1.getId(), null, size); + + //then + assertAll( + () -> assertThat(response.data().size()).isEqualTo(16), + () -> assertThat(response.data().getLast().voterCount()).isEqualTo(1), + () -> assertThat(response.data().getLast().commentCount()).isEqualTo(publicPostComments.size()), + () -> assertThat(response.data().getLast().isAuthor()).isFalse(), + () -> assertThat(response.data().getFirst().isAuthor()).isTrue() + ); + } + private List createPosts(User user, int size) { List posts = new ArrayList<>(); for (int i = 0; i < size; i ++) {