From 332b0c81584c95ad9942ab34da73bab512a68403 Mon Sep 17 00:00:00 2001 From: habin Date: Wed, 8 May 2024 15:53:56 +0900 Subject: [PATCH 01/16] feat(interaction) like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit chore: LikeController Endpoint 정의 --- .../v1/common/config/RedisConfig.java | 10 ++++++ .../com/tune_fun/v1/common/config/Uris.java | 4 +++ .../v1/common/constant/Constants.java | 5 +++ .../v1/common/filter/MDCLoggingFilter.java | 2 +- .../adapter/input/rest/LikeController.java | 33 +++++++++++++++++++ .../input/usecase/LikeVotePaperUseCase.java | 10 ++++++ .../input/usecase/UnlikeVotePaperUseCase.java | 10 ++++++ .../port/output/DeleteLikePort.java | 4 +++ .../application/port/output/SaveLikePort.java | 4 +++ .../service/LikeVotePaperService.java | 23 +++++++++++++ .../service/UnlikeVotePaperService.java | 24 ++++++++++++++ .../service/GetVotePaperService.java | 1 - .../VoteBoundedContextDependencyRuleTest.java | 4 +++ 13 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java create mode 100644 src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/LikeVotePaperUseCase.java create mode 100644 src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java create mode 100644 src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java create mode 100644 src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveLikePort.java create mode 100644 src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java create mode 100644 src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java diff --git a/src/main/java/com/tune_fun/v1/common/config/RedisConfig.java b/src/main/java/com/tune_fun/v1/common/config/RedisConfig.java index f25d3954..964e77a1 100644 --- a/src/main/java/com/tune_fun/v1/common/config/RedisConfig.java +++ b/src/main/java/com/tune_fun/v1/common/config/RedisConfig.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.tune_fun.v1.account.adapter.output.persistence.jwt.AccessTokenRedisEntity; import com.tune_fun.v1.account.adapter.output.persistence.jwt.RefreshTokenRedisEntity; +import com.tune_fun.v1.common.constant.Constants; import com.tune_fun.v1.otp.adapter.output.persistence.OtpRedisEntity; import io.lettuce.core.RedisClient; import io.lettuce.core.RedisURI; @@ -25,7 +26,11 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; import java.time.Duration; +import java.util.HashMap; +import java.util.Map; +import static java.time.Duration.ofDays; +import static java.time.Duration.ofHours; import static org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair.fromSerializer; @Slf4j @@ -69,9 +74,14 @@ public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) .prefixCacheNameWith("Cache_") .entryTtl(Duration.ofMinutes(30)); + Map redisCacheConfigMap = new HashMap<>(); + redisCacheConfigMap.put(Constants.CacheNames.VOTE_PAPER, redisCacheConfiguration.entryTtl(ofHours(1))); + redisCacheConfigMap.put(Constants.CacheNames.VOTE_CHOICE, redisCacheConfiguration.entryTtl(ofDays(1))); + return RedisCacheManager.RedisCacheManagerBuilder .fromConnectionFactory(redisConnectionFactory) .cacheDefaults(redisCacheConfiguration) + .withInitialCacheConfigurations(redisCacheConfigMap) .build(); } diff --git a/src/main/java/com/tune_fun/v1/common/config/Uris.java b/src/main/java/com/tune_fun/v1/common/config/Uris.java index e421bac1..209124d7 100644 --- a/src/main/java/com/tune_fun/v1/common/config/Uris.java +++ b/src/main/java/com/tune_fun/v1/common/config/Uris.java @@ -64,6 +64,10 @@ private Uris() { public static final String REGISTER_VOTE = VOTE_ROOT + "/{votePaperId}" + "/register" + "/{voteChoiceId}"; + public static final String LIKE_ROOT = API_V1_ROOT + "/likes"; + + public static final String LIKE_VOTE_PAPER = LIKE_ROOT + "/{votePaperId}"; + public static final String SWAGGER_UI_ROOT = "/swagger-ui"; public static final String SWAGGER_UI = "/swagger-ui.html"; public static final String SWAGGER_DOCS = "/docs/com.tune_fun-open-api-3.0.1.json"; diff --git a/src/main/java/com/tune_fun/v1/common/constant/Constants.java b/src/main/java/com/tune_fun/v1/common/constant/Constants.java index 32cfa396..b1e9ef33 100644 --- a/src/main/java/com/tune_fun/v1/common/constant/Constants.java +++ b/src/main/java/com/tune_fun/v1/common/constant/Constants.java @@ -30,6 +30,11 @@ public final class Constants { LocalDate.of(1970, 1, 1), LocalTime.of(0, 0, 1) ); + public static final class CacheNames { + public static final String VOTE_PAPER = "votePaper"; + public static final String VOTE_CHOICE = "voteChoice"; + } + public static final class NicknameFragment { public static final String[] PREFIX_NAMES = { diff --git a/src/main/java/com/tune_fun/v1/common/filter/MDCLoggingFilter.java b/src/main/java/com/tune_fun/v1/common/filter/MDCLoggingFilter.java index 4dcf1164..496f7a3d 100644 --- a/src/main/java/com/tune_fun/v1/common/filter/MDCLoggingFilter.java +++ b/src/main/java/com/tune_fun/v1/common/filter/MDCLoggingFilter.java @@ -16,7 +16,7 @@ */ @Component @Order(HIGHEST_PRECEDENCE) -class MDCLoggingFilter implements Filter { +public class MDCLoggingFilter implements Filter { @Override public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException { diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java b/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java new file mode 100644 index 00000000..d973debe --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java @@ -0,0 +1,33 @@ +package com.tune_fun.v1.interaction.adapter.input.rest; + +import com.tune_fun.v1.account.domain.value.CurrentUser; +import com.tune_fun.v1.common.config.Uris; +import com.tune_fun.v1.common.hexagon.WebAdapter; +import com.tune_fun.v1.interaction.application.port.input.usecase.LikeVotePaperUseCase; +import com.tune_fun.v1.interaction.application.port.input.usecase.UnlikeVotePaperUseCase; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.User; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@WebAdapter +@RequiredArgsConstructor +public class LikeController { + + private final LikeVotePaperUseCase likeVotePaperUseCase; + private final UnlikeVotePaperUseCase unlikeVotePaperUseCase; + + @PostMapping(value = Uris.LIKE_VOTE_PAPER) + public void likeVotePaper(@PathVariable(name = "votePaperId") String votePaperId, @CurrentUser final User user) { + + } + + @DeleteMapping(value = Uris.LIKE_VOTE_PAPER) + public void unlikeVotePaper(@PathVariable(name = "votePaperId") String votePaperId, @CurrentUser final User user) { + + } + +} diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/LikeVotePaperUseCase.java b/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/LikeVotePaperUseCase.java new file mode 100644 index 00000000..2ecea4ad --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/LikeVotePaperUseCase.java @@ -0,0 +1,10 @@ +package com.tune_fun.v1.interaction.application.port.input.usecase; + +import org.springframework.security.core.userdetails.User; + +@FunctionalInterface +public interface LikeVotePaperUseCase { + + void likeVotePaper(final Long votePaperId, final User user); + +} diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java b/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java new file mode 100644 index 00000000..6ff34238 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java @@ -0,0 +1,10 @@ +package com.tune_fun.v1.interaction.application.port.input.usecase; + +import org.springframework.security.core.userdetails.User; + +@FunctionalInterface +public interface UnlikeVotePaperUseCase { + + void unlikeVotePaper(final Long votePaperId, final User user); + +} diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java b/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java new file mode 100644 index 00000000..134e847a --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java @@ -0,0 +1,4 @@ +package com.tune_fun.v1.interaction.application.port.output; + +public interface DeleteLikePort { +} diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveLikePort.java b/src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveLikePort.java new file mode 100644 index 00000000..2f8c79af --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveLikePort.java @@ -0,0 +1,4 @@ +package com.tune_fun.v1.interaction.application.port.output; + +public interface SaveLikePort { +} diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java new file mode 100644 index 00000000..82b9985f --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java @@ -0,0 +1,23 @@ +package com.tune_fun.v1.interaction.application.service; + +import com.tune_fun.v1.common.hexagon.UseCase; +import com.tune_fun.v1.interaction.application.port.input.usecase.LikeVotePaperUseCase; +import com.tune_fun.v1.interaction.application.port.output.SaveLikePort; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.User; +import org.springframework.stereotype.Service; + +@Service +@UseCase +@RequiredArgsConstructor +public class LikeVotePaperService implements LikeVotePaperUseCase { + + private final SaveLikePort saveLikePort; + + + @Override + public void likeVotePaper(Long votePaperId, User user) { + + } + +} diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java new file mode 100644 index 00000000..47f1c681 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java @@ -0,0 +1,24 @@ +package com.tune_fun.v1.interaction.application.service; + +import com.tune_fun.v1.common.hexagon.UseCase; +import com.tune_fun.v1.interaction.application.port.input.usecase.UnlikeVotePaperUseCase; +import com.tune_fun.v1.interaction.application.port.output.DeleteLikePort; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.User; +import org.springframework.stereotype.Service; + +@Service +@UseCase +@RequiredArgsConstructor +public class UnlikeVotePaperService implements UnlikeVotePaperUseCase { + + private final DeleteLikePort deleteLikePort; + + + @Override + public void unlikeVotePaper(Long votePaperId, User user) { + + } + + +} diff --git a/src/main/java/com/tune_fun/v1/vote/application/service/GetVotePaperService.java b/src/main/java/com/tune_fun/v1/vote/application/service/GetVotePaperService.java index a3162139..0b5eaf2a 100644 --- a/src/main/java/com/tune_fun/v1/vote/application/service/GetVotePaperService.java +++ b/src/main/java/com/tune_fun/v1/vote/application/service/GetVotePaperService.java @@ -25,7 +25,6 @@ public class GetVotePaperService implements GetVotePaperUseCase { private final VoteValueMapper voteValueMapper; - @Override public FullVotePaper getVotePaper(final Long votePaperId) { RegisteredVotePaper registeredVotePaper = loadVotePaperPort.loadRegisteredVotePaper(votePaperId) diff --git a/src/test/java/com/tune_fun/v1/vote/VoteBoundedContextDependencyRuleTest.java b/src/test/java/com/tune_fun/v1/vote/VoteBoundedContextDependencyRuleTest.java index 2669a1cf..e82f0b5a 100644 --- a/src/test/java/com/tune_fun/v1/vote/VoteBoundedContextDependencyRuleTest.java +++ b/src/test/java/com/tune_fun/v1/vote/VoteBoundedContextDependencyRuleTest.java @@ -1,6 +1,7 @@ package com.tune_fun.v1.vote; import com.tune_fun.v1.base.architecture.BoundedContextDependencyRuleTest; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -16,6 +17,9 @@ public String getBoundedContextPackage() { return BOUNDED_CONTEXT_PACKAGE; } + // TODO : VotePaperControllerIT.registerVotePaperSuccess 에서 ScheduleVotePaperDeadlineService SpyBean 주입으로 인해 실패. + // 별도의 Service 로직 테스트로 분리 필요 + @Disabled @Execution(CONCURRENT) @Test @DisplayName("Vote Bounded Context satisfied Hexagonal Architecture.") From 0714da5f6c9c6052c5cf70eeed60fd2f5f802a0d Mon Sep 17 00:00:00 2001 From: habin Date: Sat, 11 May 2024 12:33:56 +0900 Subject: [PATCH 02/16] feat(interaction) like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit chore: VotePaperLikeJpaEntity 영속성 모델 추가 --- .../adapter/input/rest/LikeController.java | 15 ++++++-- .../persistence/VotePaperLikeJpaEntity.java | 38 +++++++++++++++++++ .../service/LikeVotePaperService.java | 4 +- .../persistence/VotePersistenceAdapter.java | 5 ++- 4 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeJpaEntity.java diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java b/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java index d973debe..8f52aa6f 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java @@ -3,9 +3,12 @@ import com.tune_fun.v1.account.domain.value.CurrentUser; import com.tune_fun.v1.common.config.Uris; import com.tune_fun.v1.common.hexagon.WebAdapter; +import com.tune_fun.v1.common.response.Response; +import com.tune_fun.v1.common.response.ResponseMapper; import com.tune_fun.v1.interaction.application.port.input.usecase.LikeVotePaperUseCase; import com.tune_fun.v1.interaction.application.port.input.usecase.UnlikeVotePaperUseCase; import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; import org.springframework.security.core.userdetails.User; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -20,14 +23,18 @@ public class LikeController { private final LikeVotePaperUseCase likeVotePaperUseCase; private final UnlikeVotePaperUseCase unlikeVotePaperUseCase; - @PostMapping(value = Uris.LIKE_VOTE_PAPER) - public void likeVotePaper(@PathVariable(name = "votePaperId") String votePaperId, @CurrentUser final User user) { + private final ResponseMapper responseMapper; + @PostMapping(value = Uris.LIKE_VOTE_PAPER) + public ResponseEntity> likeVotePaper(@PathVariable(name = "votePaperId") Long votePaperId, @CurrentUser final User user) { + likeVotePaperUseCase.likeVotePaper(votePaperId, user); + return responseMapper.ok(); } @DeleteMapping(value = Uris.LIKE_VOTE_PAPER) - public void unlikeVotePaper(@PathVariable(name = "votePaperId") String votePaperId, @CurrentUser final User user) { - + public ResponseEntity> unlikeVotePaper(@PathVariable(name = "votePaperId") Long votePaperId, @CurrentUser final User user) { + unlikeVotePaperUseCase.unlikeVotePaper(votePaperId, user); + return responseMapper.ok(); } } diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeJpaEntity.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeJpaEntity.java new file mode 100644 index 00000000..80487106 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeJpaEntity.java @@ -0,0 +1,38 @@ +package com.tune_fun.v1.interaction.adapter.output.persistence; + +import com.tune_fun.v1.account.adapter.output.persistence.AccountJpaEntity; +import com.tune_fun.v1.common.entity.BaseEntity; +import com.tune_fun.v1.vote.adapter.output.persistence.VotePaperJpaEntity; +import io.hypersistence.utils.hibernate.id.Tsid; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.hibernate.annotations.Comment; + +@SuperBuilder(toBuilder = true) +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Entity +@Table(name = "vote_paper_like") +public class VotePaperLikeJpaEntity extends BaseEntity { + + @Id + @Tsid + @Column(name = "id", nullable = false, updatable = false) + @Comment("TSID") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @JoinColumn(name = "vote_paper_id", nullable = false, updatable = false, referencedColumnName = "id") + @Comment("투표 게시물 ID") + private VotePaperJpaEntity votePaper; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "voter_id", nullable = false, updatable = false, referencedColumnName = "id") + @Comment("투표자 ID") + private AccountJpaEntity voter; + +} diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java index 82b9985f..7519df64 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java @@ -16,8 +16,8 @@ public class LikeVotePaperService implements LikeVotePaperUseCase { @Override - public void likeVotePaper(Long votePaperId, User user) { - + public void likeVotePaper(final Long votePaperId, final User user) { + saveLikePort.saveLike(votePaperId, user); } } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java index b3c9f26c..ebb5d175 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java @@ -5,6 +5,8 @@ import com.tune_fun.v1.common.constant.Constants; import com.tune_fun.v1.common.hexagon.PersistenceAdapter; import com.tune_fun.v1.common.util.StringUtil; +import com.tune_fun.v1.interaction.application.port.output.DeleteLikePort; +import com.tune_fun.v1.interaction.application.port.output.SaveLikePort; import com.tune_fun.v1.vote.application.port.output.*; import com.tune_fun.v1.vote.domain.behavior.SaveVoteChoice; import com.tune_fun.v1.vote.domain.behavior.SaveVotePaper; @@ -38,7 +40,8 @@ public class VotePersistenceAdapter implements LoadVotePort, SaveVotePort, LoadVotePaperPort, SaveVotePaperPort, DeleteVotePaperPort, UpdateDeliveryAtPort, UpdateVideoUrlPort, - LoadVoteChoicePort, SaveVoteChoicePort { + LoadVoteChoicePort, SaveVoteChoicePort, + SaveLikePort, DeleteLikePort { private final AccountPersistenceAdapter accountPersistenceAdapter; From ff866ddd17204abd2e79872ef81845465237c812 Mon Sep 17 00:00:00 2001 From: habin Date: Sat, 11 May 2024 17:14:41 +0900 Subject: [PATCH 03/16] feat(interaction) like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: Vote Paper Like API 구현 --- .../adapter/input/rest/LikeController.java | 6 ++--- .../persistence/VotePaperLikeJpaEntity.java | 6 ++--- .../persistence/VotePaperLikeRepository.java | 6 +++++ .../input/usecase/UnlikeVotePaperUseCase.java | 4 +--- .../port/output/DeleteLikePort.java | 1 + .../application/port/output/SaveLikePort.java | 1 + .../service/LikeVotePaperService.java | 4 +++- .../service/UnlikeVotePaperService.java | 8 +++---- .../persistence/VotePersistenceAdapter.java | 24 +++++++++++++++++++ 9 files changed, 46 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeRepository.java diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java b/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java index 8f52aa6f..c5438373 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java @@ -31,9 +31,9 @@ public ResponseEntity> likeVotePaper(@PathVariable(name = "votePaper return responseMapper.ok(); } - @DeleteMapping(value = Uris.LIKE_VOTE_PAPER) - public ResponseEntity> unlikeVotePaper(@PathVariable(name = "votePaperId") Long votePaperId, @CurrentUser final User user) { - unlikeVotePaperUseCase.unlikeVotePaper(votePaperId, user); + @DeleteMapping(value = Uris.LIKE_ROOT + "/{likeId}") + public ResponseEntity> unlikeVotePaper(@PathVariable(name = "likeId") Long likeId, @CurrentUser final User user) { + unlikeVotePaperUseCase.unlikeVotePaper(likeId); return responseMapper.ok(); } diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeJpaEntity.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeJpaEntity.java index 80487106..768e8347 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeJpaEntity.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeJpaEntity.java @@ -31,8 +31,8 @@ public class VotePaperLikeJpaEntity extends BaseEntity { private VotePaperJpaEntity votePaper; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "voter_id", nullable = false, updatable = false, referencedColumnName = "id") - @Comment("투표자 ID") - private AccountJpaEntity voter; + @JoinColumn(name = "liker_id", nullable = false, updatable = false, referencedColumnName = "id") + @Comment("좋아요 한 사용자 ID") + private AccountJpaEntity liker; } diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeRepository.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeRepository.java new file mode 100644 index 00000000..a99b2544 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeRepository.java @@ -0,0 +1,6 @@ +package com.tune_fun.v1.interaction.adapter.output.persistence; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface VotePaperLikeRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java b/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java index 6ff34238..df975159 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java @@ -1,10 +1,8 @@ package com.tune_fun.v1.interaction.application.port.input.usecase; -import org.springframework.security.core.userdetails.User; - @FunctionalInterface public interface UnlikeVotePaperUseCase { - void unlikeVotePaper(final Long votePaperId, final User user); + void unlikeVotePaper(final Long likeId); } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java b/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java index 134e847a..3e2761de 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java @@ -1,4 +1,5 @@ package com.tune_fun.v1.interaction.application.port.output; public interface DeleteLikePort { + void deleteLike(final Long likeId); } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveLikePort.java b/src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveLikePort.java index 2f8c79af..ddf49950 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveLikePort.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveLikePort.java @@ -1,4 +1,5 @@ package com.tune_fun.v1.interaction.application.port.output; public interface SaveLikePort { + void saveLike(final Long votePaperId, final String username); } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java index 7519df64..61556ca4 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java @@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @UseCase @@ -15,9 +16,10 @@ public class LikeVotePaperService implements LikeVotePaperUseCase { private final SaveLikePort saveLikePort; + @Transactional @Override public void likeVotePaper(final Long votePaperId, final User user) { - saveLikePort.saveLike(votePaperId, user); + saveLikePort.saveLike(votePaperId, user.getUsername()); } } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java index 47f1c681..4a431627 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java @@ -4,8 +4,8 @@ import com.tune_fun.v1.interaction.application.port.input.usecase.UnlikeVotePaperUseCase; import com.tune_fun.v1.interaction.application.port.output.DeleteLikePort; import lombok.RequiredArgsConstructor; -import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @UseCase @@ -14,10 +14,10 @@ public class UnlikeVotePaperService implements UnlikeVotePaperUseCase { private final DeleteLikePort deleteLikePort; - + @Transactional @Override - public void unlikeVotePaper(Long votePaperId, User user) { - + public void unlikeVotePaper(final Long likeId) { + deleteLikePort.deleteLike(likeId); } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java index ebb5d175..006a3f02 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java @@ -5,6 +5,8 @@ import com.tune_fun.v1.common.constant.Constants; import com.tune_fun.v1.common.hexagon.PersistenceAdapter; import com.tune_fun.v1.common.util.StringUtil; +import com.tune_fun.v1.interaction.adapter.output.persistence.VotePaperLikeJpaEntity; +import com.tune_fun.v1.interaction.adapter.output.persistence.VotePaperLikeRepository; import com.tune_fun.v1.interaction.application.port.output.DeleteLikePort; import com.tune_fun.v1.interaction.application.port.output.SaveLikePort; import com.tune_fun.v1.vote.application.port.output.*; @@ -48,6 +50,7 @@ public class VotePersistenceAdapter implements private final VoteRepository voteRepository; private final VotePaperRepository votePaperRepository; private final VoteChoiceRepository voteChoiceRepository; + private final VotePaperLikeRepository votePaperLikeRepository; private final VotePaperMapper votePaperMapper; private final VoteChoiceMapper voteChoiceMapper; @@ -175,6 +178,27 @@ public void saveVoteChoice(final Long votePaperId, final Set beh voteChoiceRepository.saveAll(updatedVoteChoices); } + @Override + public void saveLike(final Long votePaperId, final String username) { + AccountJpaEntity account = accountPersistenceAdapter.loadAccountByUsername(username) + .orElseThrow(() -> new IllegalArgumentException("Account not found")); + + VotePaperJpaEntity votePaper = votePaperRepository.findById(votePaperId) + .orElseThrow(() -> new IllegalArgumentException("VotePaper not found")); + + VotePaperLikeJpaEntity votePaperLike = VotePaperLikeJpaEntity.builder() + .votePaper(votePaper) + .liker(account) + .build(); + + votePaperLikeRepository.save(votePaperLike); + } + + @Override + public void deleteLike(final Long likeId) { + votePaperLikeRepository.deleteById(likeId); + } + public Optional findOneAvailable(final Long votePaperId, final String username) { return votePaperRepository.findOneAvailable(votePaperId, username); } From bb7b65e84eba934ca4686e01adfdd6b117ec353c Mon Sep 17 00:00:00 2001 From: habin Date: Thu, 16 May 2024 17:30:05 +0900 Subject: [PATCH 04/16] feat(interaction) like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit chore: Like Counting POC 로직 추가 --- .../v1/common/util/count/AtomicCounter.java | 23 +++++++++++++++++++ .../v1/common/util/count/Counter.java | 9 ++++++++ .../port/output/DeleteLikePort.java | 2 +- .../application/port/output/SaveLikePort.java | 2 +- .../service/LikeVotePaperService.java | 2 +- .../service/UnlikeVotePaperService.java | 2 +- .../persistence/VoteCountRedisEntity.java | 4 ++++ .../persistence/VoteCustomRepository.java | 5 +++- .../persistence/VoteCustomRepositoryImpl.java | 14 +++++++++++ .../persistence/VotePaperJpaEntity.java | 9 ++++++++ .../persistence/VotePersistenceAdapter.java | 4 ++-- .../persistence/VoteStatisticsJpaEntity.java | 4 ++++ 12 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/tune_fun/v1/common/util/count/AtomicCounter.java create mode 100644 src/main/java/com/tune_fun/v1/common/util/count/Counter.java create mode 100644 src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteCountRedisEntity.java create mode 100644 src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteStatisticsJpaEntity.java diff --git a/src/main/java/com/tune_fun/v1/common/util/count/AtomicCounter.java b/src/main/java/com/tune_fun/v1/common/util/count/AtomicCounter.java new file mode 100644 index 00000000..f0c75379 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/common/util/count/AtomicCounter.java @@ -0,0 +1,23 @@ +package com.tune_fun.v1.common.util.count; + +import java.util.concurrent.atomic.LongAdder; + +public final class AtomicCounter implements Counter { + + private final LongAdder concreteCounter = new LongAdder(); + + @Override + public void increment() { + concreteCounter.increment(); + } + + @Override + public void decrement() { + concreteCounter.decrement(); + } + + @Override + public long get() { + return concreteCounter.sum(); + } +} diff --git a/src/main/java/com/tune_fun/v1/common/util/count/Counter.java b/src/main/java/com/tune_fun/v1/common/util/count/Counter.java new file mode 100644 index 00000000..3c32e24c --- /dev/null +++ b/src/main/java/com/tune_fun/v1/common/util/count/Counter.java @@ -0,0 +1,9 @@ +package com.tune_fun.v1.common.util.count; + +public sealed interface Counter permits AtomicCounter { + void increment(); + + void decrement(); + + long get(); +} diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java b/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java index 3e2761de..9fc99396 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java @@ -1,5 +1,5 @@ package com.tune_fun.v1.interaction.application.port.output; public interface DeleteLikePort { - void deleteLike(final Long likeId); + void deleteVotePaperLike(final Long likeId); } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveLikePort.java b/src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveLikePort.java index ddf49950..efbd04cb 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveLikePort.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveLikePort.java @@ -1,5 +1,5 @@ package com.tune_fun.v1.interaction.application.port.output; public interface SaveLikePort { - void saveLike(final Long votePaperId, final String username); + void saveVotePaperLike(final Long votePaperId, final String username); } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java index 61556ca4..f7ee5e2a 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java @@ -19,7 +19,7 @@ public class LikeVotePaperService implements LikeVotePaperUseCase { @Transactional @Override public void likeVotePaper(final Long votePaperId, final User user) { - saveLikePort.saveLike(votePaperId, user.getUsername()); + saveLikePort.saveVotePaperLike(votePaperId, user.getUsername()); } } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java index 4a431627..3e221e4f 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java @@ -17,7 +17,7 @@ public class UnlikeVotePaperService implements UnlikeVotePaperUseCase { @Transactional @Override public void unlikeVotePaper(final Long likeId) { - deleteLikePort.deleteLike(likeId); + deleteLikePort.deleteVotePaperLike(likeId); } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteCountRedisEntity.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteCountRedisEntity.java new file mode 100644 index 00000000..12927ef1 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteCountRedisEntity.java @@ -0,0 +1,4 @@ +package com.tune_fun.v1.vote.adapter.output.persistence; + +public class VoteCountRedisEntity { +} diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteCustomRepository.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteCustomRepository.java index 7ecfefff..2c82f96e 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteCustomRepository.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteCustomRepository.java @@ -3,6 +3,7 @@ import com.tune_fun.v1.vote.domain.value.RegisteredVote; import java.util.List; +import java.util.Map; import java.util.Optional; public interface VoteCustomRepository { @@ -11,4 +12,6 @@ public interface VoteCustomRepository { Optional findByVoterUsernameAndVotePaperId(final String voter, final Long votePaperId); -} + Map countVotesByVotePaperIds(final List votePaperIds); + +} \ No newline at end of file diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteCustomRepositoryImpl.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteCustomRepositoryImpl.java index b3e9de34..6022325a 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteCustomRepositoryImpl.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteCustomRepositoryImpl.java @@ -1,13 +1,16 @@ package com.tune_fun.v1.vote.adapter.output.persistence; +import com.querydsl.core.ResultTransformer; import com.querydsl.jpa.impl.JPAQueryFactory; import com.tune_fun.v1.account.adapter.output.persistence.QAccountJpaEntity; import com.tune_fun.v1.vote.domain.value.RegisteredVote; import lombok.RequiredArgsConstructor; import java.util.List; +import java.util.Map; import java.util.Optional; +import static com.querydsl.core.group.GroupBy.groupBy; import static com.querydsl.core.types.Projections.fields; @RequiredArgsConstructor @@ -58,4 +61,15 @@ public Optional findByVoterUsernameAndVotePaperId(String voter, return Optional.ofNullable(registeredVote); } + + @Override + public Map countVotesByVotePaperIds(List votePaperIds) { + ResultTransformer> transformer = groupBy(VOTE_PAPER.id).as(VOTE.id.count()); + + return queryFactory.from(VOTE) + .join(VOTE.voteChoice, VOTE_CHOICE) + .join(VOTE_CHOICE.votePaper, VOTE_PAPER) + .where(VOTE_PAPER.id.in(votePaperIds)) + .transform(transformer); + } } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperJpaEntity.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperJpaEntity.java index 1f38050b..89d0ce8a 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperJpaEntity.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperJpaEntity.java @@ -2,6 +2,7 @@ import com.tune_fun.v1.account.adapter.output.persistence.AccountJpaEntity; import com.tune_fun.v1.common.entity.BaseEntity; +import com.tune_fun.v1.interaction.adapter.output.persistence.VotePaperLikeJpaEntity; import com.tune_fun.v1.vote.domain.value.VotePaperOption; import jakarta.persistence.*; import jakarta.validation.constraints.NotNull; @@ -45,6 +46,10 @@ public class VotePaperJpaEntity extends BaseEntity { @Comment("내용") private String content; + @Column(name = "page_link") + @Comment("View 페이지 다이나믹 링크") + private String pageLink; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "author_id", nullable = false, updatable = false, referencedColumnName = "id") @Comment("작성자") @@ -83,6 +88,10 @@ public class VotePaperJpaEntity extends BaseEntity { @OneToMany(mappedBy = "votePaper", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List choices; + @Singular + @OneToMany(mappedBy = "votePaper", fetch = FetchType.LAZY, cascade = CascadeType.ALL) + private List likes; + public void disable() { this.enabled = false; } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java index 006a3f02..73d09104 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java @@ -179,7 +179,7 @@ public void saveVoteChoice(final Long votePaperId, final Set beh } @Override - public void saveLike(final Long votePaperId, final String username) { + public void saveVotePaperLike(final Long votePaperId, final String username) { AccountJpaEntity account = accountPersistenceAdapter.loadAccountByUsername(username) .orElseThrow(() -> new IllegalArgumentException("Account not found")); @@ -195,7 +195,7 @@ public void saveLike(final Long votePaperId, final String username) { } @Override - public void deleteLike(final Long likeId) { + public void deleteVotePaperLike(final Long likeId) { votePaperLikeRepository.deleteById(likeId); } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteStatisticsJpaEntity.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteStatisticsJpaEntity.java new file mode 100644 index 00000000..6d393722 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteStatisticsJpaEntity.java @@ -0,0 +1,4 @@ +package com.tune_fun.v1.vote.adapter.output.persistence; + +public class VoteStatisticsJpaEntity { +} From 38fbb9e00e658501751b983c863dfcecf2c87708 Mon Sep 17 00:00:00 2001 From: habin Date: Thu, 16 May 2024 23:50:01 +0900 Subject: [PATCH 05/16] feat(interaction) like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: LikeCount Redis 영속성 로직 구현 --- build.gradle | 8 +- .../v1/common/config/RedisConfig.java | 11 +- .../v1/common/util/count/AtomicCounter.java | 11 +- .../adapter/input/rest/LikeController.java | 9 +- .../LikeCountAggregationScheduler.java | 19 + .../LikeCountPersistenceAdapter.java | 32 + .../input/usecase/UnlikeVotePaperUseCase.java | 2 +- .../output/SaveVotePaperLikeCountPort.java | 9 + .../service/LikeVotePaperService.java | 3 + .../service/UnlikeVotePaperService.java | 5 +- .../persistence/VoteStatisticsJpaEntity.java | 41 +- .../VoteBoundedContextDependencyRuleTest.java | 3 - .../input/rest/VotePaperControllerIT.java | 8 +- .../VotePersistenceAdapterTest.java | 976 ++++++++++++++---- 14 files changed, 923 insertions(+), 214 deletions(-) create mode 100644 src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java create mode 100644 src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java create mode 100644 src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveVotePaperLikeCountPort.java diff --git a/build.gradle b/build.gradle index c4a0ebf2..d9b84903 100644 --- a/build.gradle +++ b/build.gradle @@ -58,7 +58,7 @@ ext { set('awspringVersion', "3.1.1") set('awssdkVersion', "2.25.45") set('jwtVersion', '0.12.5') - set('queryDslVersion', "6.2.1") + set('queryDslVersion', "6.3") set('mapstructVersion', "1.5.5.Final") } @@ -82,7 +82,7 @@ dependencies { implementation "io.github.openfeign.querydsl:querydsl-collections:${queryDslVersion}" implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.1' implementation 'org.flywaydb:flyway-core' - implementation 'org.flywaydb:flyway-database-postgresql:10.12.0' + implementation 'org.flywaydb:flyway-database-postgresql:10.13.0' implementation 'org.postgresql:postgresql' // development @@ -108,7 +108,7 @@ dependencies { implementation 'software.amazon.cryptography:aws-cryptographic-material-providers:1.3.0' implementation 'org.springframework.boot:spring-boot-starter-batch' implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:4.1.1' - implementation 'com.slack.api:slack-app-backend:1.39.0' + implementation 'com.slack.api:slack-app-backend:1.39.2' implementation 'io.netty:netty-resolver-dns-native-macos:4.1.108.Final:osx-aarch_64' // Message Broker @@ -130,7 +130,7 @@ dependencies { implementation "org.mapstruct:mapstruct:${mapstructVersion}" implementation "org.mapstruct:mapstruct-processor:${mapstructVersion}" compileOnly 'org.projectlombok:lombok' - implementation 'com.google.guava:guava:33.1.0-jre' + implementation 'com.google.guava:guava:33.2.0-jre' implementation 'org.apache.commons:commons-lang3:3.14.0' implementation 'org.apache.commons:commons-rng-simple:1.5' implementation 'commons-io:commons-io:2.16.1' diff --git a/src/main/java/com/tune_fun/v1/common/config/RedisConfig.java b/src/main/java/com/tune_fun/v1/common/config/RedisConfig.java index 964e77a1..8d35f701 100644 --- a/src/main/java/com/tune_fun/v1/common/config/RedisConfig.java +++ b/src/main/java/com/tune_fun/v1/common/config/RedisConfig.java @@ -4,6 +4,7 @@ import com.tune_fun.v1.account.adapter.output.persistence.jwt.AccessTokenRedisEntity; import com.tune_fun.v1.account.adapter.output.persistence.jwt.RefreshTokenRedisEntity; import com.tune_fun.v1.common.constant.Constants; +import com.tune_fun.v1.common.util.count.AtomicCounter; import com.tune_fun.v1.otp.adapter.output.persistence.OtpRedisEntity; import io.lettuce.core.RedisClient; import io.lettuce.core.RedisURI; @@ -86,7 +87,7 @@ public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) } @Bean - public RedisTemplate redisTemplateForAccessToken() throws JsonProcessingException { + public RedisTemplate redisTemplateForAccessToken() { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory()); redisTemplate.setKeySerializer(new StringRedisSerializer()); @@ -95,7 +96,7 @@ public RedisTemplate redisTemplateForAccessToken } @Bean - public RedisTemplate redisTemplateForRefreshToken() throws JsonProcessingException { + public RedisTemplate redisTemplateForRefreshToken() { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory()); redisTemplate.setKeySerializer(new StringRedisSerializer()); @@ -104,7 +105,7 @@ public RedisTemplate redisTemplateForRefreshTok } @Bean - public RedisTemplate redisTemplateForOtp() throws JsonProcessingException { + public RedisTemplate redisTemplateForOtp() { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory()); redisTemplate.setKeySerializer(new StringRedisSerializer()); @@ -113,14 +114,14 @@ public RedisTemplate redisTemplateForOtp() throws JsonPr } @Bean - public StringRedisTemplate stringRedisTemplate() throws JsonProcessingException { + public StringRedisTemplate stringRedisTemplate() { StringRedisTemplate redisTemplate = new StringRedisTemplate(); redisTemplate.setConnectionFactory(redisConnectionFactory()); return redisTemplate; } @Bean - public RedisTemplate redisTemplateForObject() throws JsonProcessingException { + public RedisTemplate redisTemplateForObject() { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory()); redisTemplate.setKeySerializer(new StringRedisSerializer()); diff --git a/src/main/java/com/tune_fun/v1/common/util/count/AtomicCounter.java b/src/main/java/com/tune_fun/v1/common/util/count/AtomicCounter.java index f0c75379..463ebf75 100644 --- a/src/main/java/com/tune_fun/v1/common/util/count/AtomicCounter.java +++ b/src/main/java/com/tune_fun/v1/common/util/count/AtomicCounter.java @@ -1,11 +1,20 @@ package com.tune_fun.v1.common.util.count; +import java.io.Serial; +import java.io.Serializable; import java.util.concurrent.atomic.LongAdder; -public final class AtomicCounter implements Counter { +public final class AtomicCounter implements Counter, Serializable { + + @Serial + private static final long serialVersionUID = 119874651351L; private final LongAdder concreteCounter = new LongAdder(); + public void increment(long i) { + concreteCounter.add(i); + } + @Override public void increment() { concreteCounter.increment(); diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java b/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java index c5438373..d59caed1 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java @@ -31,9 +31,12 @@ public ResponseEntity> likeVotePaper(@PathVariable(name = "votePaper return responseMapper.ok(); } - @DeleteMapping(value = Uris.LIKE_ROOT + "/{likeId}") - public ResponseEntity> unlikeVotePaper(@PathVariable(name = "likeId") Long likeId, @CurrentUser final User user) { - unlikeVotePaperUseCase.unlikeVotePaper(likeId); + @DeleteMapping(value = Uris.LIKE_ROOT + "/{votePaperId}/{likeId}") + public ResponseEntity> unlikeVotePaper( + @PathVariable(name = "votePaperId") Long votePaperId, + @PathVariable(name = "likeId") Long likeId, + @CurrentUser final User user) { + unlikeVotePaperUseCase.unlikeVotePaper(votePaperId, likeId); return responseMapper.ok(); } diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java b/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java new file mode 100644 index 00000000..6124fadc --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java @@ -0,0 +1,19 @@ +package com.tune_fun.v1.interaction.adapter.input.scheduler; + +import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class LikeCountAggregationScheduler { + + private final UpdateVotePaperStatisticsUseCase updateVotePaperStatisticsPort; + + + @Scheduled(fixedDelay = 1000L * 5L) + public void aggregateLikeCount() { + + } + +} diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java new file mode 100644 index 00000000..cf788c98 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java @@ -0,0 +1,32 @@ +package com.tune_fun.v1.interaction.adapter.output.persistence; + +import com.tune_fun.v1.interaction.application.port.output.SaveVotePaperLikeCountPort; +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class LikeCountPersistenceAdapter implements SaveVotePaperLikeCountPort { + + private static final String VOTE_PAPER_LIKE_COUNT_KEY = "vote_paper_like_count"; + + private static final String LIKE_COUNT_HASH_KEY = "like_count"; + + private final RedisTemplate redisTemplate; + + @Override + public void incrementVotePaperLikeCount(final Long votePaperId) { + redisTemplate.opsForHash().increment(key(votePaperId), LIKE_COUNT_HASH_KEY, 1); + } + + @Override + public void decrementVotePaperLikeCount(final Long votePaperId) { + redisTemplate.opsForHash().increment(key(votePaperId), LIKE_COUNT_HASH_KEY, -1); + } + + private static String key(final Long votePaperId) { + return VOTE_PAPER_LIKE_COUNT_KEY + "::" + votePaperId; + } + +} diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java b/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java index df975159..146676de 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java @@ -3,6 +3,6 @@ @FunctionalInterface public interface UnlikeVotePaperUseCase { - void unlikeVotePaper(final Long likeId); + void unlikeVotePaper(final Long votePaperId, final Long likeId); } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveVotePaperLikeCountPort.java b/src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveVotePaperLikeCountPort.java new file mode 100644 index 00000000..a2684034 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/output/SaveVotePaperLikeCountPort.java @@ -0,0 +1,9 @@ +package com.tune_fun.v1.interaction.application.port.output; + +public interface SaveVotePaperLikeCountPort { + + void incrementVotePaperLikeCount(final Long votePaperId); + + void decrementVotePaperLikeCount(final Long votePaperId); + +} diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java index f7ee5e2a..0b03ebeb 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java @@ -3,6 +3,7 @@ import com.tune_fun.v1.common.hexagon.UseCase; import com.tune_fun.v1.interaction.application.port.input.usecase.LikeVotePaperUseCase; import com.tune_fun.v1.interaction.application.port.output.SaveLikePort; +import com.tune_fun.v1.interaction.application.port.output.SaveVotePaperLikeCountPort; import lombok.RequiredArgsConstructor; import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Service; @@ -14,12 +15,14 @@ public class LikeVotePaperService implements LikeVotePaperUseCase { private final SaveLikePort saveLikePort; + private final SaveVotePaperLikeCountPort saveVotePaperLikeCountPort; @Transactional @Override public void likeVotePaper(final Long votePaperId, final User user) { saveLikePort.saveVotePaperLike(votePaperId, user.getUsername()); + saveVotePaperLikeCountPort.incrementVotePaperLikeCount(votePaperId); } } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java index 3e221e4f..f33769d2 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java @@ -3,6 +3,7 @@ import com.tune_fun.v1.common.hexagon.UseCase; import com.tune_fun.v1.interaction.application.port.input.usecase.UnlikeVotePaperUseCase; import com.tune_fun.v1.interaction.application.port.output.DeleteLikePort; +import com.tune_fun.v1.interaction.application.port.output.SaveVotePaperLikeCountPort; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -13,11 +14,13 @@ public class UnlikeVotePaperService implements UnlikeVotePaperUseCase { private final DeleteLikePort deleteLikePort; + private final SaveVotePaperLikeCountPort saveVotePaperLikeCountPort; @Transactional @Override - public void unlikeVotePaper(final Long likeId) { + public void unlikeVotePaper(final Long votePaperId, final Long likeId) { deleteLikePort.deleteVotePaperLike(likeId); + saveVotePaperLikeCountPort.decrementVotePaperLikeCount(votePaperId); } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteStatisticsJpaEntity.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteStatisticsJpaEntity.java index 6d393722..2dd36255 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteStatisticsJpaEntity.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteStatisticsJpaEntity.java @@ -1,4 +1,43 @@ package com.tune_fun.v1.vote.adapter.output.persistence; -public class VoteStatisticsJpaEntity { +import com.tune_fun.v1.common.entity.BaseEntity; +import io.hypersistence.utils.hibernate.id.Tsid; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.hibernate.annotations.Comment; + +@SuperBuilder(toBuilder = true) +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Entity +@Table(name = "vote_statistics") +public class VoteStatisticsJpaEntity extends BaseEntity { + + @Id + @Tsid + @Column(name = "id", nullable = false, updatable = false) + @Comment("TSID") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @JoinColumn(name = "vote_paper_id", nullable = false, updatable = false, referencedColumnName = "id") + @Comment("투표 게시물 ID") + private VotePaperJpaEntity votePaper; + + @Builder.Default + @Column(name = "like_count", nullable = false) + @Comment("좋아요 수") + private Long likeCount = 0L; + + @Builder.Default + @Column(name = "vote_count", nullable = false) + @Comment("투표 수") + private Long voteCount = 0L; + + } diff --git a/src/test/java/com/tune_fun/v1/vote/VoteBoundedContextDependencyRuleTest.java b/src/test/java/com/tune_fun/v1/vote/VoteBoundedContextDependencyRuleTest.java index e82f0b5a..b33df2cf 100644 --- a/src/test/java/com/tune_fun/v1/vote/VoteBoundedContextDependencyRuleTest.java +++ b/src/test/java/com/tune_fun/v1/vote/VoteBoundedContextDependencyRuleTest.java @@ -17,9 +17,6 @@ public String getBoundedContextPackage() { return BOUNDED_CONTEXT_PACKAGE; } - // TODO : VotePaperControllerIT.registerVotePaperSuccess 에서 ScheduleVotePaperDeadlineService SpyBean 주입으로 인해 실패. - // 별도의 Service 로직 테스트로 분리 필요 - @Disabled @Execution(CONCURRENT) @Test @DisplayName("Vote Bounded Context satisfied Hexagonal Architecture.") diff --git a/src/test/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperControllerIT.java b/src/test/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperControllerIT.java index 37f1d3ab..5e9cdf46 100644 --- a/src/test/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperControllerIT.java +++ b/src/test/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperControllerIT.java @@ -196,7 +196,7 @@ void getVotePaperSuccess() throws Exception { fieldWithPath("data.author_username").description("투표 게시물 작성자 아이디").attributes(constraint("NOT NULL")), fieldWithPath("data.title").description("투표 게시물 제목").attributes(constraint("NOT NULL")), fieldWithPath("data.content").description("투표 게시물 내용").attributes(constraint("NOT NULL")), - fieldWithPath("data.option").description("투표 종류").attributes(constraint("NOT NULL")), + fieldWithPath("data.option").description("투표 종류").attributes(constraint("NOT NULL, allow-add-choices || deny-add-choices")), fieldWithPath("data.video_url").description("투표 게시물 영상 URL").attributes(constraint("NULL or NOT NULL")), fieldWithPath("data.vote_start_at").description("투표 시작 시간").attributes(constraint("NOT NULL")), fieldWithPath("data.vote_end_at").description("투표 종료 시간").attributes(constraint("NOT NULL")), @@ -278,9 +278,9 @@ void registerVotePaperSuccess() throws Exception { FieldDescriptor[] requestDescriptors = { fieldWithPath("title").description("투표 게시물 제목").attributes(constraint("NOT BLANK")), fieldWithPath("content").description("투표 게시물 내용").attributes(constraint("NOT BLANK")), - fieldWithPath("option").description("투표 종류").attributes(constraint("NOT BLANK")), - fieldWithPath("vote_start_at").description("투표 시작 시간").attributes(constraint("NOT NULL & FUTURE & BEFORE(endAt)")), - fieldWithPath("vote_end_at").description("투표 종료 시간").attributes(constraint("NOT NULL & FUTURE & AFTER(startAt)")), + fieldWithPath("option").description("투표 종류").attributes(constraint("NOT BLANK, allow-add-choices || deny-add-choices")), + fieldWithPath("vote_start_at").description("투표 시작 시간").attributes(constraint("NOT NULL & FUTURE & BEFORE(vote_end_at)")), + fieldWithPath("vote_end_at").description("투표 종료 시간").attributes(constraint("NOT NULL & FUTURE & AFTER(vote_start_at)")), fieldWithPath("offers").description("투표 선택지 목록").attributes(constraint("NOT EMPTY")), fieldWithPath("offers[].id").description("아이디").attributes(constraint("NOT NULL")), fieldWithPath("offers[].music").description("노래명").attributes(constraint("NOT BLANK")), diff --git a/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java b/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java index 5cf6cb83..672fea60 100644 --- a/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java +++ b/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java @@ -5,6 +5,8 @@ import com.tune_fun.v1.account.adapter.output.persistence.AccountPersistenceAdapter; import com.tune_fun.v1.account.adapter.output.persistence.AccountRepository; import com.tune_fun.v1.account.adapter.output.persistence.oauth2.OAuth2AccountRepository; +import com.tune_fun.v1.interaction.adapter.output.persistence.VotePaperLikeJpaEntity; +import com.tune_fun.v1.interaction.adapter.output.persistence.VotePaperLikeRepository; import com.tune_fun.v1.vote.domain.behavior.SaveVoteChoice; import com.tune_fun.v1.vote.domain.behavior.SaveVotePaper; import com.tune_fun.v1.vote.domain.value.RegisteredVote; @@ -43,12 +45,13 @@ void testLoadVoterIdsByVotePaperUuid() { VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act List actualLoadVoterIdsByVotePaperUuidResult = (new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .loadVoterIdsByVotePaperUuid("01234567-89AB-CDEF-FEDC-BA9876543210"); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl())).loadVoterIdsByVotePaperUuid("01234567-89AB-CDEF-FEDC-BA9876543210"); // Assert verify(voteRepository).findVoterIdsByVotePaperUuid(eq("01234567-89AB-CDEF-FEDC-BA9876543210")); @@ -73,12 +76,13 @@ void testLoadVoterIdsByVotePaperUuid2() { VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())) + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) .loadVoterIdsByVotePaperUuid("01234567-89AB-CDEF-FEDC-BA9876543210")); verify(voteRepository).findVoterIdsByVotePaperUuid(eq("01234567-89AB-CDEF-FEDC-BA9876543210")); } @@ -109,12 +113,13 @@ void testLoadVoteByVoterAndVotePaperId() { VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act Optional actualLoadVoteByVoterAndVotePaperIdResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, - new VoteChoiceMapperImpl())).loadVoteByVoterAndVotePaperId("Voter", 1L); + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).loadVoteByVoterAndVotePaperId("Voter", 1L); // Assert verify(voteRepository).findByVoterUsernameAndVotePaperId(eq("Voter"), eq(1L)); @@ -138,13 +143,14 @@ void testLoadVoteByVoterAndVotePaperId2() { VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).loadVoteByVoterAndVotePaperId("Voter", - 1L)); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .loadVoteByVoterAndVotePaperId("Voter", 1L)); verify(voteRepository).findByVoterUsernameAndVotePaperId(eq("Voter"), eq(1L)); } @@ -168,11 +174,12 @@ void testSaveVote() { Optional ofResult2 = Optional.of(new VoteChoiceJpaEntity()); when(voteChoiceRepository.findById(Mockito.any())).thenReturn(ofResult2); VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, - votePaperMapper, new VoteChoiceMapperImpl())).saveVote(1L, "janedoe"); + votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).saveVote(1L, "janedoe"); // Assert verify(accountRepository).findActive(eq("janedoe"), isNull(), isNull()); @@ -200,12 +207,14 @@ void testSaveVote2() { Optional ofResult2 = Optional.of(new VoteChoiceJpaEntity()); when(voteChoiceRepository.findById(Mockito.any())).thenReturn(ofResult2); VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).saveVote(1L, "janedoe")); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).saveVote(1L, + "janedoe")); verify(accountRepository).findActive(eq("janedoe"), isNull(), isNull()); verify(voteChoiceRepository).findById(eq(1L)); verify(voteRepository).save(isA(VoteJpaEntity.class)); @@ -230,12 +239,14 @@ void testSaveVote3() { when(voteChoiceRepository.findById(Mockito.any())).thenReturn(ofResult); VoteRepository voteRepository = mock(VoteRepository.class); VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).saveVote(1L, "janedoe")); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).saveVote(1L, + "janedoe")); verify(accountRepository).findActive(eq("janedoe"), isNull(), isNull()); verify(voteChoiceRepository).findById(eq(1L)); } @@ -256,12 +267,14 @@ void testSaveVote4() { VoteRepository voteRepository = mock(VoteRepository.class); VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).saveVote(1L, "janedoe")); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).saveVote(1L, + "janedoe")); verify(voteChoiceRepository).findById(eq(1L)); } @@ -282,12 +295,42 @@ void testScrollVotePaper() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + + // Act and Assert + assertThrows(IllegalArgumentException.class, + () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .scrollVotePaper(1, "Sort Type")); + verify(votePaperRepository).findFirst10ByEnabledTrue(isA(KeysetScrollPosition.class), isA(Sort.class)); + } + + /** + * Method under test: + * {@link VotePersistenceAdapter#scrollVotePaper(Integer, String)} + */ + @Test + void testScrollVotePaper2() { + // Arrange + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + when(votePaperRepository.findFirst10ByEnabledTrue(Mockito.any(), Mockito.any())) + .thenThrow(new IllegalArgumentException("id")); + AccountRepository accountRepository = mock(AccountRepository.class); + OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); + AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, + oauth2AccountRepository, new AccountMapperImpl()); + + VoteRepository voteRepository = mock(VoteRepository.class); + VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).scrollVotePaper(1, "Sort Type")); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .scrollVotePaper(0, "Sort Type")); verify(votePaperRepository).findFirst10ByEnabledTrue(isA(KeysetScrollPosition.class), isA(Sort.class)); } @@ -309,22 +352,25 @@ void testLoadRegisteredVotePaper() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act Optional actualLoadRegisteredVotePaperResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, - new VoteChoiceMapperImpl())).loadRegisteredVotePaper(1L); + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVotePaper(1L); // Assert verify(votePaperRepository).findByVoteEndAtAfterAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); RegisteredVotePaper getResult = actualLoadRegisteredVotePaperResult.get(); + assertNull(getResult.option()); assertNull(getResult.id()); assertNull(getResult.author()); + assertNull(getResult.authorUsername()); assertNull(getResult.content()); - assertNull(getResult.option()); assertNull(getResult.title()); assertNull(getResult.uuid()); + assertNull(getResult.videoUrl()); assertNull(getResult.createdAt()); assertNull(getResult.deliveryAt()); assertNull(getResult.updatedAt()); @@ -343,10 +389,12 @@ void testLoadRegisteredVotePaper2() { AccountJpaEntity author = new AccountJpaEntity(); LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); LocalDateTime voteEndAt = LocalDate.of(1970, 1, 1).atStartOfDay(); + LocalDateTime deliveryAt = LocalDate.of(1970, 1, 1).atStartOfDay(); + ArrayList choices = new ArrayList<>(); Optional ofResult = Optional .of(new VotePaperJpaEntity(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", "Dr", "Not all who wander are lost", - author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, voteEndAt, LocalDate.of(1970, 1, 1).atStartOfDay(), true, - "https://example.org/example", new ArrayList<>())); + "Page Link", author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, voteEndAt, deliveryAt, true, + "https://example.org/example", choices, new ArrayList<>())); when(votePaperRepository.findByVoteEndAtAfterAndIdAndEnabledTrue(Mockito.any(), Mockito.any())) .thenReturn(ofResult); AccountRepository accountRepository = mock(AccountRepository.class); @@ -356,12 +404,13 @@ void testLoadRegisteredVotePaper2() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act Optional actualLoadRegisteredVotePaperResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, - new VoteChoiceMapperImpl())).loadRegisteredVotePaper(1L); + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVotePaper(1L); // Assert verify(votePaperRepository).findByVoteEndAtAfterAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); @@ -388,12 +437,13 @@ void testLoadRegisteredVotePaper3() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act Optional actualLoadRegisteredVotePaperResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, - new VoteChoiceMapperImpl())).loadRegisteredVotePaper(1L); + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVotePaper(1L); // Assert verify(votePaperRepository).findByVoteEndAtAfterAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); @@ -418,12 +468,14 @@ void testLoadRegisteredVotePaper4() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVotePaper(1L)); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .loadRegisteredVotePaper(1L)); verify(votePaperRepository).findByVoteEndAtAfterAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); } @@ -436,8 +488,8 @@ void testLoadRegisteredVotePaper5() { // Arrange VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional ofResult = Optional.of(new VotePaperJpaEntity()); - when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), Mockito.any())) - .thenReturn(ofResult); + when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), + Mockito.any())).thenReturn(ofResult); AccountRepository accountRepository = mock(AccountRepository.class); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, @@ -445,22 +497,26 @@ void testLoadRegisteredVotePaper5() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act Optional actualLoadRegisteredVotePaperResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, - new VoteChoiceMapperImpl())).loadRegisteredVotePaper("janedoe"); + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVotePaper("janedoe"); // Assert - verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), eq("janedoe")); + verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), + eq("janedoe")); RegisteredVotePaper getResult = actualLoadRegisteredVotePaperResult.get(); + assertNull(getResult.option()); assertNull(getResult.id()); assertNull(getResult.author()); + assertNull(getResult.authorUsername()); assertNull(getResult.content()); - assertNull(getResult.option()); assertNull(getResult.title()); assertNull(getResult.uuid()); + assertNull(getResult.videoUrl()); assertNull(getResult.createdAt()); assertNull(getResult.deliveryAt()); assertNull(getResult.updatedAt()); @@ -479,12 +535,14 @@ void testLoadRegisteredVotePaper6() { AccountJpaEntity author = new AccountJpaEntity(); LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); LocalDateTime voteEndAt = LocalDate.of(1970, 1, 1).atStartOfDay(); + LocalDateTime deliveryAt = LocalDate.of(1970, 1, 1).atStartOfDay(); + ArrayList choices = new ArrayList<>(); Optional ofResult = Optional .of(new VotePaperJpaEntity(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", "Dr", "Not all who wander are lost", - author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, voteEndAt, LocalDate.of(1970, 1, 1).atStartOfDay(), true, - "https://example.org/example", new ArrayList<>())); - when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), Mockito.any())) - .thenReturn(ofResult); + "Page Link", author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, voteEndAt, deliveryAt, true, + "https://example.org/example", choices, new ArrayList<>())); + when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), + Mockito.any())).thenReturn(ofResult); AccountRepository accountRepository = mock(AccountRepository.class); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, @@ -492,15 +550,17 @@ void testLoadRegisteredVotePaper6() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act Optional actualLoadRegisteredVotePaperResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, - new VoteChoiceMapperImpl())).loadRegisteredVotePaper("janedoe"); + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVotePaper("janedoe"); // Assert - verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), eq("janedoe")); + verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), + eq("janedoe")); RegisteredVotePaper getResult = actualLoadRegisteredVotePaperResult.get(); LocalTime expectedToLocalTimeResult = getResult.voteStartAt().toLocalTime(); assertSame(expectedToLocalTimeResult, getResult.voteEndAt().toLocalTime()); @@ -515,8 +575,8 @@ void testLoadRegisteredVotePaper7() { // Arrange VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional emptyResult = Optional.empty(); - when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), Mockito.any())) - .thenReturn(emptyResult); + when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), + Mockito.any())).thenReturn(emptyResult); AccountRepository accountRepository = mock(AccountRepository.class); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, @@ -524,15 +584,17 @@ void testLoadRegisteredVotePaper7() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act Optional actualLoadRegisteredVotePaperResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, - new VoteChoiceMapperImpl())).loadRegisteredVotePaper("janedoe"); + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVotePaper("janedoe"); // Assert - verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), eq("janedoe")); + verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), + eq("janedoe")); assertFalse(actualLoadRegisteredVotePaperResult.isPresent()); assertSame(emptyResult, actualLoadRegisteredVotePaperResult); } @@ -545,8 +607,8 @@ void testLoadRegisteredVotePaper7() { void testLoadRegisteredVotePaper8() { // Arrange VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), Mockito.any())) - .thenThrow(new IllegalArgumentException("foo")); + when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), + Mockito.any())).thenThrow(new IllegalArgumentException("foo")); AccountRepository accountRepository = mock(AccountRepository.class); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, @@ -554,13 +616,16 @@ void testLoadRegisteredVotePaper8() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVotePaper("janedoe")); - verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), eq("janedoe")); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .loadRegisteredVotePaper("janedoe")); + verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), + eq("janedoe")); } /** @@ -571,25 +636,45 @@ void testLoadRegisteredVotePaper8() { void testSaveVotePaper() { // Arrange AccountRepository accountRepository = mock(AccountRepository.class); - Optional emptyResult = Optional.empty(); + Optional ofResult = Optional.of(new AccountJpaEntity()); when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(emptyResult); + .thenReturn(ofResult); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, oauth2AccountRepository, new AccountMapperImpl()); - VoteRepository voteRepository = mock(VoteRepository.class); VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + when(votePaperRepository.save(Mockito.any())).thenReturn(new VotePaperJpaEntity()); + VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - // Act and Assert - assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.saveVotePaper(new SaveVotePaper("Dr", - "Not all who wander are lost", "JaneDoe", VotePaperOption.DENY_ADD_CHOICES, voteStartAt, LocalDate.of(1970, 1, 1).atStartOfDay()))); + // Act + RegisteredVotePaper actualSaveVotePaperResult = votePersistenceAdapter + .saveVotePaper(new SaveVotePaper("Dr", "Not all who wander are lost", "JaneDoe", + VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, LocalDate.of(1970, 1, 1).atStartOfDay())); + + // Assert verify(accountRepository).findActive(eq("JaneDoe"), isNull(), isNull()); + verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); + assertNull(actualSaveVotePaperResult.option()); + assertNull(actualSaveVotePaperResult.id()); + assertNull(actualSaveVotePaperResult.author()); + assertNull(actualSaveVotePaperResult.authorUsername()); + assertNull(actualSaveVotePaperResult.content()); + assertNull(actualSaveVotePaperResult.title()); + assertNull(actualSaveVotePaperResult.uuid()); + assertNull(actualSaveVotePaperResult.videoUrl()); + assertNull(actualSaveVotePaperResult.createdAt()); + assertNull(actualSaveVotePaperResult.deliveryAt()); + assertNull(actualSaveVotePaperResult.updatedAt()); + assertNull(actualSaveVotePaperResult.voteEndAt()); + assertNull(actualSaveVotePaperResult.voteStartAt()); } /** @@ -608,33 +693,22 @@ void testSaveVotePaper2() { oauth2AccountRepository, new AccountMapperImpl()); VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.save(Mockito.any())).thenReturn(new VotePaperJpaEntity()); + when(votePaperRepository.save(Mockito.any())).thenThrow(new IllegalArgumentException("foo")); VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - // Act - RegisteredVotePaper actualSaveVotePaperResult = votePersistenceAdapter - .saveVotePaper(new SaveVotePaper("Dr", "Not all who wander are lost", "JaneDoe", VotePaperOption.ALLOW_ADD_CHOICES, - voteStartAt, LocalDate.of(1970, 1, 1).atStartOfDay())); - - // Assert + // Act and Assert + assertThrows(IllegalArgumentException.class, + () -> votePersistenceAdapter.saveVotePaper(new SaveVotePaper("Dr", "Not all who wander are lost", "JaneDoe", + VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, LocalDate.of(1970, 1, 1).atStartOfDay()))); verify(accountRepository).findActive(eq("JaneDoe"), isNull(), isNull()); verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); - assertNull(actualSaveVotePaperResult.id()); - assertNull(actualSaveVotePaperResult.author()); - assertNull(actualSaveVotePaperResult.content()); - assertNull(actualSaveVotePaperResult.option()); - assertNull(actualSaveVotePaperResult.title()); - assertNull(actualSaveVotePaperResult.uuid()); - assertNull(actualSaveVotePaperResult.createdAt()); - assertNull(actualSaveVotePaperResult.deliveryAt()); - assertNull(actualSaveVotePaperResult.updatedAt()); - assertNull(actualSaveVotePaperResult.voteEndAt()); - assertNull(actualSaveVotePaperResult.voteStartAt()); } /** @@ -643,6 +717,38 @@ void testSaveVotePaper2() { */ @Test void testSaveVotePaper3() { + // Arrange + AccountRepository accountRepository = mock(AccountRepository.class); + Optional emptyResult = Optional.empty(); + when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) + .thenReturn(emptyResult); + OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); + AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, + oauth2AccountRepository, new AccountMapperImpl()); + + VoteRepository voteRepository = mock(VoteRepository.class); + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); + LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); + + // Act and Assert + assertThrows(IllegalArgumentException.class, + () -> votePersistenceAdapter.saveVotePaper(new SaveVotePaper("Dr", "Not all who wander are lost", "JaneDoe", + VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, LocalDate.of(1970, 1, 1).atStartOfDay()))); + verify(accountRepository).findActive(eq("JaneDoe"), isNull(), isNull()); + } + + /** + * Method under test: + * {@link VotePersistenceAdapter#saveVotePaper(SaveVotePaper)} + */ + @Test + void testSaveVotePaper4() { // Arrange AccountRepository accountRepository = mock(AccountRepository.class); Optional ofResult = Optional.of(new AccountJpaEntity()); @@ -656,15 +762,17 @@ void testSaveVotePaper3() { when(votePaperRepository.save(Mockito.any())).thenReturn(null); VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); // Act RegisteredVotePaper actualSaveVotePaperResult = votePersistenceAdapter - .saveVotePaper(new SaveVotePaper("Dr", "Not all who wander are lost", "JaneDoe", VotePaperOption.ALLOW_ADD_CHOICES, - voteStartAt, LocalDate.of(1970, 1, 1).atStartOfDay())); + .saveVotePaper(new SaveVotePaper("Dr", "Not all who wander are lost", "JaneDoe", + VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, LocalDate.of(1970, 1, 1).atStartOfDay())); // Assert verify(accountRepository).findActive(eq("JaneDoe"), isNull(), isNull()); @@ -677,7 +785,7 @@ void testSaveVotePaper3() { * {@link VotePersistenceAdapter#saveVotePaper(SaveVotePaper)} */ @Test - void testSaveVotePaper4() { + void testSaveVotePaper5() { // Arrange AccountRepository accountRepository = mock(AccountRepository.class); Optional ofResult = Optional.of(new AccountJpaEntity()); @@ -691,21 +799,25 @@ void testSaveVotePaper4() { AccountJpaEntity author = new AccountJpaEntity(); LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); LocalDateTime voteEndAt = LocalDate.of(1970, 1, 1).atStartOfDay(); + LocalDateTime deliveryAt = LocalDate.of(1970, 1, 1).atStartOfDay(); + ArrayList choices = new ArrayList<>(); when(votePaperRepository.save(Mockito.any())) .thenReturn(new VotePaperJpaEntity(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", "Dr", - "Not all who wander are lost", author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, voteEndAt, - LocalDate.of(1970, 1, 1).atStartOfDay(), true, "https://example.org/example", new ArrayList<>())); + "Not all who wander are lost", "Page Link", author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, + voteEndAt, deliveryAt, true, "https://example.org/example", choices, new ArrayList<>())); VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); LocalDateTime voteStartAt2 = LocalDate.of(1970, 1, 1).atStartOfDay(); // Act RegisteredVotePaper actualSaveVotePaperResult = votePersistenceAdapter - .saveVotePaper(new SaveVotePaper("Dr", "Not all who wander are lost", "JaneDoe", VotePaperOption.ALLOW_ADD_CHOICES, - voteStartAt2, LocalDate.of(1970, 1, 1).atStartOfDay())); + .saveVotePaper(new SaveVotePaper("Dr", "Not all who wander are lost", "JaneDoe", + VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt2, LocalDate.of(1970, 1, 1).atStartOfDay())); // Assert verify(accountRepository).findActive(eq("JaneDoe"), isNull(), isNull()); @@ -715,38 +827,90 @@ void testSaveVotePaper4() { } /** - * Method under test: - * {@link VotePersistenceAdapter#saveVotePaper(SaveVotePaper)} + * Method under test: {@link VotePersistenceAdapter#disableVotePaper(Long)} */ @Test - void testSaveVotePaper5() { + void testDisableVotePaper() { // Arrange + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + when(votePaperRepository.save(Mockito.any())).thenReturn(new VotePaperJpaEntity()); + Optional ofResult = Optional.of(new VotePaperJpaEntity()); + when(votePaperRepository.findById(Mockito.any())).thenReturn(ofResult); AccountRepository accountRepository = mock(AccountRepository.class); - Optional ofResult = Optional.of(new AccountJpaEntity()); - when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(ofResult); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, oauth2AccountRepository, new AccountMapperImpl()); + VoteRepository voteRepository = mock(VoteRepository.class); + VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + + // Act + (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, + votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).disableVotePaper(1L); + + // Assert + verify(votePaperRepository).findById(eq(1L)); + verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); + } + + /** + * Method under test: {@link VotePersistenceAdapter#disableVotePaper(Long)} + */ + @Test + void testDisableVotePaper2() { + // Arrange VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.save(Mockito.any())) - .thenThrow(new IllegalArgumentException("allow-add-choices")); + when(votePaperRepository.save(Mockito.any())).thenThrow(new IllegalArgumentException("foo")); + Optional ofResult = Optional.of(new VotePaperJpaEntity()); + when(votePaperRepository.findById(Mockito.any())).thenReturn(ofResult); + AccountRepository accountRepository = mock(AccountRepository.class); + OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); + AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, + oauth2AccountRepository, new AccountMapperImpl()); + VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); - LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); // Act and Assert assertThrows(IllegalArgumentException.class, - () -> votePersistenceAdapter.saveVotePaper(new SaveVotePaper("Dr", "Not all who wander are lost", "JaneDoe", - VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, LocalDate.of(1970, 1, 1).atStartOfDay()))); - verify(accountRepository).findActive(eq("JaneDoe"), isNull(), isNull()); + () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .disableVotePaper(1L)); + verify(votePaperRepository).findById(eq(1L)); verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); } + /** + * Method under test: {@link VotePersistenceAdapter#disableVotePaper(Long)} + */ + @Test + void testDisableVotePaper3() { + // Arrange + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + Optional emptyResult = Optional.empty(); + when(votePaperRepository.findById(Mockito.any())).thenReturn(emptyResult); + AccountRepository accountRepository = mock(AccountRepository.class); + OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); + AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, + oauth2AccountRepository, new AccountMapperImpl()); + + VoteRepository voteRepository = mock(VoteRepository.class); + VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + + // Act + (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, + votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).disableVotePaper(1L); + + // Assert + verify(votePaperRepository).findById(eq(1L)); + } + /** * Method under test: * {@link VotePersistenceAdapter#updateDeliveryAt(Long, LocalDateTime)} @@ -765,9 +929,11 @@ void testUpdateDeliveryAt() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); // Act RegisteredVotePaper actualUpdateDeliveryAtResult = votePersistenceAdapter.updateDeliveryAt(1L, @@ -776,12 +942,14 @@ void testUpdateDeliveryAt() { // Assert verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); + assertNull(actualUpdateDeliveryAtResult.option()); assertNull(actualUpdateDeliveryAtResult.id()); assertNull(actualUpdateDeliveryAtResult.author()); + assertNull(actualUpdateDeliveryAtResult.authorUsername()); assertNull(actualUpdateDeliveryAtResult.content()); - assertNull(actualUpdateDeliveryAtResult.option()); assertNull(actualUpdateDeliveryAtResult.title()); assertNull(actualUpdateDeliveryAtResult.uuid()); + assertNull(actualUpdateDeliveryAtResult.videoUrl()); assertNull(actualUpdateDeliveryAtResult.createdAt()); assertNull(actualUpdateDeliveryAtResult.deliveryAt()); assertNull(actualUpdateDeliveryAtResult.updatedAt()); @@ -807,9 +975,11 @@ void testUpdateDeliveryAt2() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); // Act and Assert assertThrows(IllegalArgumentException.class, @@ -836,9 +1006,11 @@ void testUpdateDeliveryAt3() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); // Act RegisteredVotePaper actualUpdateDeliveryAtResult = votePersistenceAdapter.updateDeliveryAt(1L, @@ -861,10 +1033,12 @@ void testUpdateDeliveryAt4() { AccountJpaEntity author = new AccountJpaEntity(); LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); LocalDateTime voteEndAt = LocalDate.of(1970, 1, 1).atStartOfDay(); + LocalDateTime deliveryAt = LocalDate.of(1970, 1, 1).atStartOfDay(); + ArrayList choices = new ArrayList<>(); when(votePaperRepository.save(Mockito.any())) .thenReturn(new VotePaperJpaEntity(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", "Dr", - "Not all who wander are lost", author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, voteEndAt, - LocalDate.of(1970, 1, 1).atStartOfDay(), true, "https://example.org/example", new ArrayList<>())); + "Not all who wander are lost", "Page Link", author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, + voteEndAt, deliveryAt, true, "https://example.org/example", choices, new ArrayList<>())); Optional ofResult = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); AccountRepository accountRepository = mock(AccountRepository.class); @@ -874,9 +1048,11 @@ void testUpdateDeliveryAt4() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); // Act RegisteredVotePaper actualUpdateDeliveryAtResult = votePersistenceAdapter.updateDeliveryAt(1L, @@ -895,6 +1071,53 @@ void testUpdateDeliveryAt4() { */ @Test void testUpdateDeliveryAt5() { + // Arrange + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + when(votePaperRepository.save(Mockito.any())).thenReturn(new VotePaperJpaEntity()); + Optional ofResult = Optional + .of(new VotePaperJpaEntity(mock(VotePaperJpaEntity.VotePaperJpaEntityBuilder.class))); + when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); + AccountRepository accountRepository = mock(AccountRepository.class); + OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); + AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, + oauth2AccountRepository, new AccountMapperImpl()); + + VoteRepository voteRepository = mock(VoteRepository.class); + VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); + + // Act + RegisteredVotePaper actualUpdateDeliveryAtResult = votePersistenceAdapter.updateDeliveryAt(1L, + LocalDate.of(1970, 1, 1).atStartOfDay()); + + // Assert + verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); + verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); + assertNull(actualUpdateDeliveryAtResult.option()); + assertNull(actualUpdateDeliveryAtResult.id()); + assertNull(actualUpdateDeliveryAtResult.author()); + assertNull(actualUpdateDeliveryAtResult.authorUsername()); + assertNull(actualUpdateDeliveryAtResult.content()); + assertNull(actualUpdateDeliveryAtResult.title()); + assertNull(actualUpdateDeliveryAtResult.uuid()); + assertNull(actualUpdateDeliveryAtResult.videoUrl()); + assertNull(actualUpdateDeliveryAtResult.createdAt()); + assertNull(actualUpdateDeliveryAtResult.deliveryAt()); + assertNull(actualUpdateDeliveryAtResult.updatedAt()); + assertNull(actualUpdateDeliveryAtResult.voteEndAt()); + assertNull(actualUpdateDeliveryAtResult.voteStartAt()); + } + + /** + * Method under test: + * {@link VotePersistenceAdapter#updateDeliveryAt(Long, LocalDateTime)} + */ + @Test + void testUpdateDeliveryAt6() { // Arrange VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional emptyResult = Optional.empty(); @@ -906,9 +1129,11 @@ void testUpdateDeliveryAt5() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); // Act and Assert assertThrows(IllegalArgumentException.class, @@ -934,21 +1159,22 @@ void testUpdateVideoUrl() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act RegisteredVotePaper actualUpdateVideoUrlResult = (new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .updateVideoUrl(1L, "https://example.org/example"); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl())).updateVideoUrl(1L, "https://example.org/example"); // Assert verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); + assertNull(actualUpdateVideoUrlResult.option()); assertNull(actualUpdateVideoUrlResult.id()); assertNull(actualUpdateVideoUrlResult.author()); assertNull(actualUpdateVideoUrlResult.authorUsername()); assertNull(actualUpdateVideoUrlResult.content()); - assertNull(actualUpdateVideoUrlResult.option()); assertNull(actualUpdateVideoUrlResult.title()); assertNull(actualUpdateVideoUrlResult.uuid()); assertNull(actualUpdateVideoUrlResult.videoUrl()); @@ -977,13 +1203,14 @@ void testUpdateVideoUrl2() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).updateVideoUrl(1L, - "https://example.org/example")); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .updateVideoUrl(1L, "https://example.org/example")); verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); } @@ -1006,12 +1233,13 @@ void testUpdateVideoUrl3() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act RegisteredVotePaper actualUpdateVideoUrlResult = (new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .updateVideoUrl(1L, "https://example.org/example"); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl())).updateVideoUrl(1L, "https://example.org/example"); // Assert verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); @@ -1030,10 +1258,12 @@ void testUpdateVideoUrl4() { AccountJpaEntity author = new AccountJpaEntity(); LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); LocalDateTime voteEndAt = LocalDate.of(1970, 1, 1).atStartOfDay(); + LocalDateTime deliveryAt = LocalDate.of(1970, 1, 1).atStartOfDay(); + ArrayList choices = new ArrayList<>(); when(votePaperRepository.save(Mockito.any())) .thenReturn(new VotePaperJpaEntity(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", "Dr", - "Not all who wander are lost", author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, voteEndAt, - LocalDate.of(1970, 1, 1).atStartOfDay(), true, "https://example.org/example", new ArrayList<>())); + "Not all who wander are lost", "Page Link", author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, + voteEndAt, deliveryAt, true, "https://example.org/example", choices, new ArrayList<>())); Optional ofResult = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); AccountRepository accountRepository = mock(AccountRepository.class); @@ -1043,12 +1273,13 @@ void testUpdateVideoUrl4() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act RegisteredVotePaper actualUpdateVideoUrlResult = (new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .updateVideoUrl(1L, "https://example.org/example"); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl())).updateVideoUrl(1L, "https://example.org/example"); // Assert verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); @@ -1063,6 +1294,51 @@ voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new */ @Test void testUpdateVideoUrl5() { + // Arrange + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + when(votePaperRepository.save(Mockito.any())).thenReturn(new VotePaperJpaEntity()); + Optional ofResult = Optional + .of(new VotePaperJpaEntity(mock(VotePaperJpaEntity.VotePaperJpaEntityBuilder.class))); + when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); + AccountRepository accountRepository = mock(AccountRepository.class); + OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); + AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, + oauth2AccountRepository, new AccountMapperImpl()); + + VoteRepository voteRepository = mock(VoteRepository.class); + VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + + // Act + RegisteredVotePaper actualUpdateVideoUrlResult = (new VotePersistenceAdapter(accountPersistenceAdapter, + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl())).updateVideoUrl(1L, "https://example.org/example"); + + // Assert + verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); + verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); + assertNull(actualUpdateVideoUrlResult.option()); + assertNull(actualUpdateVideoUrlResult.id()); + assertNull(actualUpdateVideoUrlResult.author()); + assertNull(actualUpdateVideoUrlResult.authorUsername()); + assertNull(actualUpdateVideoUrlResult.content()); + assertNull(actualUpdateVideoUrlResult.title()); + assertNull(actualUpdateVideoUrlResult.uuid()); + assertNull(actualUpdateVideoUrlResult.videoUrl()); + assertNull(actualUpdateVideoUrlResult.createdAt()); + assertNull(actualUpdateVideoUrlResult.deliveryAt()); + assertNull(actualUpdateVideoUrlResult.updatedAt()); + assertNull(actualUpdateVideoUrlResult.voteEndAt()); + assertNull(actualUpdateVideoUrlResult.voteStartAt()); + } + + /** + * Method under test: + * {@link VotePersistenceAdapter#updateVideoUrl(Long, String)} + */ + @Test + void testUpdateVideoUrl6() { // Arrange VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional emptyResult = Optional.empty(); @@ -1074,13 +1350,14 @@ void testUpdateVideoUrl5() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).updateVideoUrl(1L, - "https://example.org/example")); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .updateVideoUrl(1L, "https://example.org/example")); verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); } @@ -1100,12 +1377,13 @@ void testLoadRegisteredVoteChoice() { VoteRepository voteRepository = mock(VoteRepository.class); VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act List actualLoadRegisteredVoteChoiceResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, - new VoteChoiceMapperImpl())).loadRegisteredVoteChoice(1L); + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVoteChoice(1L); // Assert verify(voteChoiceRepository).findAllByVotePaperId(eq(1L)); @@ -1118,6 +1396,87 @@ void testLoadRegisteredVoteChoice() { */ @Test void testLoadRegisteredVoteChoice2() { + // Arrange + ArrayList voteChoiceJpaEntityList = new ArrayList<>(); + voteChoiceJpaEntityList.add(new VoteChoiceJpaEntity()); + VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + when(voteChoiceRepository.findAllByVotePaperId(Mockito.any())).thenReturn(voteChoiceJpaEntityList); + AccountRepository accountRepository = mock(AccountRepository.class); + OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); + AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, + oauth2AccountRepository, new AccountMapperImpl()); + + VoteRepository voteRepository = mock(VoteRepository.class); + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + + // Act + List actualLoadRegisteredVoteChoiceResult = (new VotePersistenceAdapter( + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVoteChoice(1L); + + // Assert + verify(voteChoiceRepository).findAllByVotePaperId(eq(1L)); + assertEquals(1, actualLoadRegisteredVoteChoiceResult.size()); + RegisteredVoteChoice getResult = actualLoadRegisteredVoteChoiceResult.get(0); + assertNull(getResult.id()); + assertNull(getResult.votePaperId()); + assertNull(getResult.artistName()); + assertNull(getResult.music()); + assertNull(getResult.offerId()); + } + + /** + * Method under test: + * {@link VotePersistenceAdapter#loadRegisteredVoteChoice(Long)} + */ + @Test + void testLoadRegisteredVoteChoice3() { + // Arrange + ArrayList voteChoiceJpaEntityList = new ArrayList<>(); + voteChoiceJpaEntityList.add(new VoteChoiceJpaEntity()); + voteChoiceJpaEntityList.add(new VoteChoiceJpaEntity()); + VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + when(voteChoiceRepository.findAllByVotePaperId(Mockito.any())).thenReturn(voteChoiceJpaEntityList); + AccountRepository accountRepository = mock(AccountRepository.class); + OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); + AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, + oauth2AccountRepository, new AccountMapperImpl()); + + VoteRepository voteRepository = mock(VoteRepository.class); + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + + // Act + List actualLoadRegisteredVoteChoiceResult = (new VotePersistenceAdapter( + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVoteChoice(1L); + + // Assert + verify(voteChoiceRepository).findAllByVotePaperId(eq(1L)); + assertEquals(2, actualLoadRegisteredVoteChoiceResult.size()); + RegisteredVoteChoice getResult = actualLoadRegisteredVoteChoiceResult.get(0); + assertNull(getResult.id()); + RegisteredVoteChoice getResult2 = actualLoadRegisteredVoteChoiceResult.get(1); + assertNull(getResult2.id()); + assertNull(getResult.votePaperId()); + assertNull(getResult2.votePaperId()); + assertNull(getResult.artistName()); + assertNull(getResult2.artistName()); + assertNull(getResult.music()); + assertNull(getResult2.music()); + assertNull(getResult.offerId()); + assertNull(getResult2.offerId()); + } + + /** + * Method under test: + * {@link VotePersistenceAdapter#loadRegisteredVoteChoice(Long)} + */ + @Test + void testLoadRegisteredVoteChoice4() { // Arrange VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); when(voteChoiceRepository.findAllByVotePaperId(Mockito.any())).thenThrow(new IllegalArgumentException("foo")); @@ -1128,12 +1487,14 @@ void testLoadRegisteredVoteChoice2() { VoteRepository voteRepository = mock(VoteRepository.class); VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVoteChoice(1L)); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .loadRegisteredVoteChoice(1L)); verify(voteChoiceRepository).findAllByVotePaperId(eq(1L)); } @@ -1142,12 +1503,14 @@ void testLoadRegisteredVoteChoice2() { * {@link VotePersistenceAdapter#loadRegisteredVoteChoice(Long)} */ @Test - void testLoadRegisteredVoteChoice3() { + void testLoadRegisteredVoteChoice5() { // Arrange ArrayList voteChoiceJpaEntityList = new ArrayList<>(); VotePaperJpaEntity votePaper = new VotePaperJpaEntity(); - voteChoiceJpaEntityList.add(new VoteChoiceJpaEntity(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", votePaper, - new Offer(",", ",", ","), new ArrayList<>(), "jain doe")); + Offer offer = new Offer("42", "Music", "Artist Name"); + + voteChoiceJpaEntityList.add(new VoteChoiceJpaEntity(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", votePaper, offer, + new ArrayList<>(), "Jan 1, 2020 8:00am GMT+0100")); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); when(voteChoiceRepository.findAllByVotePaperId(Mockito.any())).thenReturn(voteChoiceJpaEntityList); AccountRepository accountRepository = mock(AccountRepository.class); @@ -1157,16 +1520,23 @@ void testLoadRegisteredVoteChoice3() { VoteRepository voteRepository = mock(VoteRepository.class); VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act List actualLoadRegisteredVoteChoiceResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, - new VoteChoiceMapperImpl())).loadRegisteredVoteChoice(1L); + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVoteChoice(1L); // Assert verify(voteChoiceRepository).findAllByVotePaperId(eq(1L)); assertEquals(1, actualLoadRegisteredVoteChoiceResult.size()); + RegisteredVoteChoice getResult = actualLoadRegisteredVoteChoiceResult.get(0); + assertEquals("42", getResult.offerId()); + assertEquals("Artist Name", getResult.artistName()); + assertEquals("Music", getResult.music()); + assertNull(getResult.votePaperId()); + assertEquals(1L, getResult.id().longValue()); } /** @@ -1175,14 +1545,50 @@ void testLoadRegisteredVoteChoice3() { */ @Test void testLoadVoteChoiceByUsername() { + // Arrange + VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + Optional ofResult = Optional.of(new VoteChoiceJpaEntity()); + when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) + .thenReturn(ofResult); + AccountRepository accountRepository = mock(AccountRepository.class); + OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); + AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, + oauth2AccountRepository, new AccountMapperImpl()); + + VoteRepository voteRepository = mock(VoteRepository.class); + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + + // Act + Optional actualLoadVoteChoiceByUsernameResult = (new VotePersistenceAdapter( + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).loadVoteChoiceByUsername(1L, "janedoe"); + + // Assert + verify(voteChoiceRepository).findByVotePaperIdAndCreatedBy(eq(1L), eq("janedoe")); + RegisteredVoteChoice getResult = actualLoadVoteChoiceByUsernameResult.get(); + assertNull(getResult.id()); + assertNull(getResult.votePaperId()); + assertNull(getResult.artistName()); + assertNull(getResult.music()); + assertNull(getResult.offerId()); + } + + /** + * Method under test: + * {@link VotePersistenceAdapter#loadVoteChoiceByUsername(Long, String)} + */ + @Test + void testLoadVoteChoiceByUsername2() { // Arrange VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); VotePaperJpaEntity votePaper = new VotePaperJpaEntity(); - Offer offer = new Offer(",", ",", ","); + Offer offer = new Offer("42", "Music", "Artist Name"); Optional ofResult = Optional.of(new VoteChoiceJpaEntity(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", votePaper, offer, new ArrayList<>(), "Jan 1, 2020 8:00am GMT+0100")); - when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) + when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) .thenReturn(ofResult); AccountRepository accountRepository = mock(AccountRepository.class); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); @@ -1191,18 +1597,20 @@ void testLoadVoteChoiceByUsername() { VoteRepository voteRepository = mock(VoteRepository.class); VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act Optional actualLoadVoteChoiceByUsernameResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, - new VoteChoiceMapperImpl())).loadVoteChoiceByUsername(1L, "janedoe"); + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).loadVoteChoiceByUsername(1L, "janedoe"); // Assert verify(voteChoiceRepository).findByVotePaperIdAndCreatedBy(eq(1L), eq("janedoe")); RegisteredVoteChoice getResult = actualLoadVoteChoiceByUsernameResult.get(); - assertEquals(",", getResult.artistName()); - assertEquals(",", getResult.music()); + assertEquals("42", getResult.offerId()); + assertEquals("Artist Name", getResult.artistName()); + assertEquals("Music", getResult.music()); assertNull(getResult.votePaperId()); assertEquals(1L, getResult.id().longValue()); } @@ -1212,11 +1620,11 @@ void testLoadVoteChoiceByUsername() { * {@link VotePersistenceAdapter#loadVoteChoiceByUsername(Long, String)} */ @Test - void testLoadVoteChoiceByUsername2() { + void testLoadVoteChoiceByUsername3() { // Arrange VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); Optional emptyResult = Optional.empty(); - when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) + when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) .thenReturn(emptyResult); AccountRepository accountRepository = mock(AccountRepository.class); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); @@ -1225,12 +1633,13 @@ void testLoadVoteChoiceByUsername2() { VoteRepository voteRepository = mock(VoteRepository.class); VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act Optional actualLoadVoteChoiceByUsernameResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, - new VoteChoiceMapperImpl())).loadVoteChoiceByUsername(1L, "janedoe"); + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).loadVoteChoiceByUsername(1L, "janedoe"); // Assert verify(voteChoiceRepository).findByVotePaperIdAndCreatedBy(eq(1L), eq("janedoe")); @@ -1243,10 +1652,10 @@ void testLoadVoteChoiceByUsername2() { * {@link VotePersistenceAdapter#loadVoteChoiceByUsername(Long, String)} */ @Test - void testLoadVoteChoiceByUsername3() { + void testLoadVoteChoiceByUsername4() { // Arrange VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) + when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) .thenThrow(new IllegalArgumentException("foo")); AccountRepository accountRepository = mock(AccountRepository.class); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); @@ -1255,13 +1664,14 @@ void testLoadVoteChoiceByUsername3() { VoteRepository voteRepository = mock(VoteRepository.class); VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).loadVoteChoiceByUsername(1L, - "janedoe")); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .loadVoteChoiceByUsername(1L, "janedoe")); verify(voteChoiceRepository).findByVotePaperIdAndCreatedBy(eq(1L), eq("janedoe")); } @@ -1282,9 +1692,11 @@ void testSaveVoteChoice() { oauth2AccountRepository, new AccountMapperImpl()); VoteRepository voteRepository = mock(VoteRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); // Act votePersistenceAdapter.saveVoteChoice(1L, new HashSet<>()); @@ -1312,9 +1724,11 @@ void testSaveVoteChoice2() { oauth2AccountRepository, new AccountMapperImpl()); VoteRepository voteRepository = mock(VoteRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); // Act and Assert assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.saveVoteChoice(1L, new HashSet<>())); @@ -1338,9 +1752,11 @@ void testSaveVoteChoice3() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); // Act and Assert assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.saveVoteChoice(1L, new HashSet<>())); @@ -1364,12 +1780,14 @@ void testSaveVoteChoice4() { oauth2AccountRepository, new AccountMapperImpl()); VoteRepository voteRepository = mock(VoteRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl()); HashSet behavior = new HashSet<>(); - behavior.add(new SaveVoteChoice("Id", "Music", "Offer Artist Name")); + behavior.add(new SaveVoteChoice("42", "Music", "Artist Name")); // Act votePersistenceAdapter.saveVoteChoice(1L, behavior); @@ -1380,86 +1798,185 @@ void testSaveVoteChoice4() { } /** - * Method under test: {@link VotePersistenceAdapter#saveVoteChoice(Long, Set)} + * Method under test: + * {@link VotePersistenceAdapter#saveVotePaperLike(Long, String)} */ @Test - void testSaveVoteChoice5() { + void testSaveVotePaperLike() { // Arrange + AccountRepository accountRepository = mock(AccountRepository.class); + Optional ofResult = Optional.of(new AccountJpaEntity()); + when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) + .thenReturn(ofResult); + OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); + AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, + oauth2AccountRepository, new AccountMapperImpl()); + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - Optional ofResult = Optional.of(new VotePaperJpaEntity()); - when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); + Optional ofResult2 = Optional.of(new VotePaperJpaEntity()); + when(votePaperRepository.findById(Mockito.any())).thenReturn(ofResult2); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + when(votePaperLikeRepository.save(Mockito.any())).thenReturn(new VotePaperLikeJpaEntity()); + VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - when(voteChoiceRepository.saveAll(Mockito.any())).thenReturn(new ArrayList<>()); + VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + + // Act + (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, + votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).saveVotePaperLike(1L, "janedoe"); + + // Assert + verify(accountRepository).findActive(eq("janedoe"), isNull(), isNull()); + verify(votePaperRepository).findById(eq(1L)); + verify(votePaperLikeRepository).save(isA(VotePaperLikeJpaEntity.class)); + } + + /** + * Method under test: + * {@link VotePersistenceAdapter#saveVotePaperLike(Long, String)} + */ + @Test + void testSaveVotePaperLike2() { + // Arrange AccountRepository accountRepository = mock(AccountRepository.class); + Optional ofResult = Optional.of(new AccountJpaEntity()); + when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) + .thenReturn(ofResult); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, oauth2AccountRepository, new AccountMapperImpl()); + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + Optional ofResult2 = Optional.of(new VotePaperJpaEntity()); + when(votePaperRepository.findById(Mockito.any())).thenReturn(ofResult2); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + when(votePaperLikeRepository.save(Mockito.any())) + .thenThrow(new IllegalArgumentException("foo")); VoteRepository voteRepository = mock(VoteRepository.class); + VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl()); - HashSet behavior = new HashSet<>(); - behavior.add(new SaveVoteChoice(",", ",",",")); - behavior.add(new SaveVoteChoice("Id", "Music", "Offer Artist Name")); + // Act and Assert + assertThrows(IllegalArgumentException.class, + () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .saveVotePaperLike(1L, "janedoe")); + verify(accountRepository).findActive(eq("janedoe"), isNull(), isNull()); + verify(votePaperRepository).findById(eq(1L)); + verify(votePaperLikeRepository).save(isA(VotePaperLikeJpaEntity.class)); + } - // Act - votePersistenceAdapter.saveVoteChoice(1L, behavior); + /** + * Method under test: + * {@link VotePersistenceAdapter#saveVotePaperLike(Long, String)} + */ + @Test + void testSaveVotePaperLike3() { + // Arrange + AccountRepository accountRepository = mock(AccountRepository.class); + Optional emptyResult = Optional.empty(); + when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) + .thenReturn(emptyResult); + OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); + AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, + oauth2AccountRepository, new AccountMapperImpl()); - // Assert - verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); - verify(voteChoiceRepository).saveAll(isA(Iterable.class)); + VoteRepository voteRepository = mock(VoteRepository.class); + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + + // Act and Assert + assertThrows(IllegalArgumentException.class, + () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .saveVotePaperLike(1L, "janedoe")); + verify(accountRepository).findActive(eq("janedoe"), isNull(), isNull()); } /** - * Method under test: {@link VotePersistenceAdapter#disableVotePaper(Long)} + * Method under test: + * {@link VotePersistenceAdapter#saveVotePaperLike(Long, String)} */ @Test - void testDisableVotePaper() { + void testSaveVotePaperLike4() { // Arrange + AccountRepository accountRepository = mock(AccountRepository.class); + Optional ofResult = Optional.of(new AccountJpaEntity()); + when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) + .thenReturn(ofResult); + OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); + AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, + oauth2AccountRepository, new AccountMapperImpl()); + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - Optional ofResult = Optional.of(new VotePaperJpaEntity()); - when(votePaperRepository.findById(Mockito.any())).thenReturn(ofResult); + Optional emptyResult = Optional.empty(); + when(votePaperRepository.findById(Mockito.any())).thenReturn(emptyResult); + VoteRepository voteRepository = mock(VoteRepository.class); + VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + + // Act and Assert + assertThrows(IllegalArgumentException.class, + () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .saveVotePaperLike(1L, "janedoe")); + verify(accountRepository).findActive(eq("janedoe"), isNull(), isNull()); + verify(votePaperRepository).findById(eq(1L)); + } + + /** + * Method under test: {@link VotePersistenceAdapter#deleteVotePaperLike(Long)} + */ + @Test + void testDeleteVotePaperLike() { + // Arrange + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + doNothing().when(votePaperLikeRepository).deleteById(Mockito.any()); AccountRepository accountRepository = mock(AccountRepository.class); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, oauth2AccountRepository, new AccountMapperImpl()); VoteRepository voteRepository = mock(VoteRepository.class); + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, - votePaperMapper, new VoteChoiceMapperImpl())).disableVotePaper(1L); + votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).deleteVotePaperLike(1L); // Assert - verify(votePaperRepository).findById(eq(1L)); + verify(votePaperLikeRepository).deleteById(eq(1L)); } /** - * Method under test: {@link VotePersistenceAdapter#disableVotePaper(Long)} + * Method under test: {@link VotePersistenceAdapter#deleteVotePaperLike(Long)} */ @Test - void testDisableVotePaper2() { + void testDeleteVotePaperLike2() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - doThrow(new IllegalArgumentException("foo")).when(votePaperRepository).findById(Mockito.any()); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + doThrow(new IllegalArgumentException("foo")).when(votePaperLikeRepository).deleteById(Mockito.any()); AccountRepository accountRepository = mock(AccountRepository.class); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, oauth2AccountRepository, new AccountMapperImpl()); VoteRepository voteRepository = mock(VoteRepository.class); + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).disableVotePaper(1L)); - verify(votePaperRepository).findById(eq(1L)); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .deleteVotePaperLike(1L)); + verify(votePaperLikeRepository).deleteById(eq(1L)); } /** @@ -1479,12 +1996,13 @@ void testFindOneAvailable() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act Optional actualFindOneAvailableResult = (new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .findOneAvailable(1L, "janedoe"); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl())).findOneAvailable(1L, "janedoe"); // Assert verify(votePaperRepository).findOneAvailable(eq(1L), eq("janedoe")); @@ -1508,12 +2026,14 @@ void testFindOneAvailable2() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).findOneAvailable(1L, "janedoe")); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .findOneAvailable(1L, "janedoe")); verify(votePaperRepository).findOneAvailable(eq(1L), eq("janedoe")); } @@ -1526,7 +2046,8 @@ void testFindCompleteVotePaperById() { // Arrange VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional ofResult = Optional.of(new VotePaperJpaEntity()); - when(votePaperRepository.findByVoteEndAtBeforeAndIdAndEnabledTrue(Mockito.any(), Mockito.any())) + when( + votePaperRepository.findByVoteEndAtBeforeAndIdAndEnabledTrue(Mockito.any(), Mockito.any())) .thenReturn(ofResult); AccountRepository accountRepository = mock(AccountRepository.class); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); @@ -1535,12 +2056,13 @@ void testFindCompleteVotePaperById() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act Optional actualFindCompleteVotePaperByIdResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, - new VoteChoiceMapperImpl())).findCompleteVotePaperById(1L); + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).findCompleteVotePaperById(1L); // Assert verify(votePaperRepository).findByVoteEndAtBeforeAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); @@ -1555,7 +2077,8 @@ void testFindCompleteVotePaperById() { void testFindCompleteVotePaperById2() { // Arrange VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.findByVoteEndAtBeforeAndIdAndEnabledTrue(Mockito.any(), Mockito.any())) + when( + votePaperRepository.findByVoteEndAtBeforeAndIdAndEnabledTrue(Mockito.any(), Mockito.any())) .thenThrow(new IllegalArgumentException("foo")); AccountRepository accountRepository = mock(AccountRepository.class); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); @@ -1564,12 +2087,14 @@ void testFindCompleteVotePaperById2() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).findCompleteVotePaperById(1L)); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .findCompleteVotePaperById(1L)); verify(votePaperRepository).findByVoteEndAtBeforeAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); } @@ -1582,8 +2107,8 @@ void testFindProgressingVotePaperByAuthor() { // Arrange VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional ofResult = Optional.of(new VotePaperJpaEntity()); - when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), Mockito.any())) - .thenReturn(ofResult); + when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), + Mockito.any())).thenReturn(ofResult); AccountRepository accountRepository = mock(AccountRepository.class); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, @@ -1591,15 +2116,17 @@ void testFindProgressingVotePaperByAuthor() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act Optional actualFindProgressingVotePaperByAuthorResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, - new VoteChoiceMapperImpl())).findProgressingVotePaperByAuthor("janedoe"); + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).findProgressingVotePaperByAuthor("janedoe"); // Assert - verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), eq("janedoe")); + verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), + eq("janedoe")); assertSame(ofResult, actualFindProgressingVotePaperByAuthorResult); } @@ -1611,8 +2138,8 @@ void testFindProgressingVotePaperByAuthor() { void testFindProgressingVotePaperByAuthor2() { // Arrange VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), Mockito.any())) - .thenThrow(new IllegalArgumentException("foo")); + when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), + Mockito.any())).thenThrow(new IllegalArgumentException("foo")); AccountRepository accountRepository = mock(AccountRepository.class); OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, @@ -1620,14 +2147,16 @@ void testFindProgressingVotePaperByAuthor2() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())) + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) .findProgressingVotePaperByAuthor("janedoe")); - verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), eq("janedoe")); + verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), + eq("janedoe")); } /** @@ -1648,12 +2177,13 @@ void testFindProgressingVotePaperById() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act Optional actualFindProgressingVotePaperByIdResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, - new VoteChoiceMapperImpl())).findProgressingVotePaperById(1L); + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).findProgressingVotePaperById(1L); // Assert verify(votePaperRepository).findByVoteEndAtAfterAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); @@ -1677,12 +2207,14 @@ void testFindProgressingVotePaperById2() { VoteRepository voteRepository = mock(VoteRepository.class); VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).findProgressingVotePaperById(1L)); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .findProgressingVotePaperById(1L)); verify(votePaperRepository).findByVoteEndAtAfterAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); } @@ -1702,12 +2234,13 @@ void testFindAllByVotePaperId() { VoteRepository voteRepository = mock(VoteRepository.class); VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act List actualFindAllByVotePaperIdResult = (new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .findAllByVotePaperId(1L); + voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, + new VoteChoiceMapperImpl())).findAllByVotePaperId(1L); // Assert verify(voteChoiceRepository).findAllByVotePaperId(eq(1L)); @@ -1730,12 +2263,73 @@ void testFindAllByVotePaperId2() { VoteRepository voteRepository = mock(VoteRepository.class); VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperMapper, new VoteChoiceMapperImpl())).findAllByVotePaperId(1L)); + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .findAllByVotePaperId(1L)); verify(voteChoiceRepository).findAllByVotePaperId(eq(1L)); } + + /** + * Method under test: + * {@link VotePersistenceAdapter#findByVotePaperIdAndUsername(Long, String)} + */ + @Test + void testFindByVotePaperIdAndUsername() { + // Arrange + VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + Optional ofResult = Optional.of(new VoteChoiceJpaEntity()); + when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) + .thenReturn(ofResult); + AccountRepository accountRepository = mock(AccountRepository.class); + OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); + AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, + oauth2AccountRepository, new AccountMapperImpl()); + + VoteRepository voteRepository = mock(VoteRepository.class); + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + + // Act + Optional actualFindByVotePaperIdAndUsernameResult = (new VotePersistenceAdapter( + accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, + votePaperMapper, new VoteChoiceMapperImpl())).findByVotePaperIdAndUsername(1L, "janedoe"); + + // Assert + verify(voteChoiceRepository).findByVotePaperIdAndCreatedBy(eq(1L), eq("janedoe")); + assertSame(ofResult, actualFindByVotePaperIdAndUsernameResult); + } + + /** + * Method under test: + * {@link VotePersistenceAdapter#findByVotePaperIdAndUsername(Long, String)} + */ + @Test + void testFindByVotePaperIdAndUsername2() { + // Arrange + VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) + .thenThrow(new IllegalArgumentException("foo")); + AccountRepository accountRepository = mock(AccountRepository.class); + OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); + AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, + oauth2AccountRepository, new AccountMapperImpl()); + + VoteRepository voteRepository = mock(VoteRepository.class); + VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); + VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + + // Act and Assert + assertThrows(IllegalArgumentException.class, + () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, + voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) + .findByVotePaperIdAndUsername(1L, "janedoe")); + verify(voteChoiceRepository).findByVotePaperIdAndCreatedBy(eq(1L), eq("janedoe")); + } } From af14594032583a91ed99c970d482a5bf9f2209ad Mon Sep 17 00:00:00 2001 From: habin Date: Wed, 22 May 2024 22:48:09 +0900 Subject: [PATCH 06/16] feat(interaction) like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: UpdateVotePaperStatisticsService 구현 --- .../LikeCountAggregationScheduler.java | 5 ++-- .../LikeCountPersistenceAdapter.java | 16 +++++++++- .../UpdateVotePaperStatisticsUseCase.java | 8 +++++ .../output/LoadVotePaperLikeCountPort.java | 9 ++++++ .../UpdateVotePaperStatisticsService.java | 30 +++++++++++++++++++ 5 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UpdateVotePaperStatisticsUseCase.java create mode 100644 src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadVotePaperLikeCountPort.java create mode 100644 src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java b/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java index 6124fadc..d82ec088 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java @@ -1,5 +1,6 @@ package com.tune_fun.v1.interaction.adapter.input.scheduler; +import com.tune_fun.v1.interaction.application.port.input.usecase.UpdateVotePaperStatisticsUseCase; import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -8,12 +9,12 @@ @RequiredArgsConstructor public class LikeCountAggregationScheduler { - private final UpdateVotePaperStatisticsUseCase updateVotePaperStatisticsPort; + private final UpdateVotePaperStatisticsUseCase updateVotePaperStatisticsUseCase; @Scheduled(fixedDelay = 1000L * 5L) public void aggregateLikeCount() { - + updateVotePaperStatisticsUseCase.updateVotePaperStatistics(); } } diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java index cf788c98..905e26a3 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java @@ -1,13 +1,18 @@ package com.tune_fun.v1.interaction.adapter.output.persistence; +import com.tune_fun.v1.interaction.application.port.output.LoadVotePaperLikeCountPort; import com.tune_fun.v1.interaction.application.port.output.SaveVotePaperLikeCountPort; import lombok.RequiredArgsConstructor; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; +import java.util.Set; + +import static java.util.stream.Collectors.toSet; + @Component @RequiredArgsConstructor -public class LikeCountPersistenceAdapter implements SaveVotePaperLikeCountPort { +public class LikeCountPersistenceAdapter implements SaveVotePaperLikeCountPort, LoadVotePaperLikeCountPort { private static final String VOTE_PAPER_LIKE_COUNT_KEY = "vote_paper_like_count"; @@ -15,6 +20,15 @@ public class LikeCountPersistenceAdapter implements SaveVotePaperLikeCountPort { private final RedisTemplate redisTemplate; + @Override + public Set getVotePaperIds() { + Set keys = redisTemplate.keys(VOTE_PAPER_LIKE_COUNT_KEY + "*"); + + if (keys == null) return Set.of(); + + return keys.stream().map(key -> Long.valueOf(key.split("::")[1])).collect(toSet()); + } + @Override public void incrementVotePaperLikeCount(final Long votePaperId) { redisTemplate.opsForHash().increment(key(votePaperId), LIKE_COUNT_HASH_KEY, 1); diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UpdateVotePaperStatisticsUseCase.java b/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UpdateVotePaperStatisticsUseCase.java new file mode 100644 index 00000000..35dba71b --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UpdateVotePaperStatisticsUseCase.java @@ -0,0 +1,8 @@ +package com.tune_fun.v1.interaction.application.port.input.usecase; + +@FunctionalInterface +public interface UpdateVotePaperStatisticsUseCase { + + void updateVotePaperStatistics(); + +} diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadVotePaperLikeCountPort.java b/src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadVotePaperLikeCountPort.java new file mode 100644 index 00000000..81aa0711 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadVotePaperLikeCountPort.java @@ -0,0 +1,9 @@ +package com.tune_fun.v1.interaction.application.port.output; + +import java.util.Set; + +public interface LoadVotePaperLikeCountPort { + + Set getVotePaperIds(); + +} diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java new file mode 100644 index 00000000..bf2d0fda --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java @@ -0,0 +1,30 @@ +package com.tune_fun.v1.interaction.application.service; + +import com.tune_fun.v1.common.hexagon.UseCase; +import com.tune_fun.v1.interaction.application.port.input.usecase.UpdateVotePaperStatisticsUseCase; +import com.tune_fun.v1.interaction.application.port.output.LoadVotePaperLikeCountPort; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Set; + +@Service +@UseCase +@RequiredArgsConstructor +public class UpdateVotePaperStatisticsService implements UpdateVotePaperStatisticsUseCase { + + private final LoadVotePaperLikeCountPort loadVotePaperLikeCountPort; + private final UpdateVotePaperStatPort updateVotePaperStatPort; + + + @Override + public void updateVotePaperStatistics() { + Set keys = loadVotePaperLikeCountPort.getVotePaperIds(); + + keys.forEach(key -> { + Long likeCount = loadVotePaperLikeCountPort.getVotePaperLikeCount(key); + updateVotePaperStatPort.updateVotePaperStat(votePaperId, likeCount); + }); + + } +} From 8d590934fc189b547c8a5445f2a5e1cf451ca9d0 Mon Sep 17 00:00:00 2001 From: habin Date: Thu, 23 May 2024 15:02:18 +0900 Subject: [PATCH 07/16] feat(interaction) like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: VotePaperLikeCountKey 조회 로직 추가 feat: VotePaperStatistics LikeCount Update 로직 추가 feat: VotePaperStatistics LikeCount 조회 로직 추가 --- .../LikeCountAggregationScheduler.java | 1 - .../LikeCountPersistenceAdapter.java | 25 +- .../output/LoadVotePaperLikeCountPort.java | 7 +- .../UpdateVotePaperStatisticsService.java | 9 +- .../output/persistence/VotePaperMapper.java | 10 +- .../VotePaperStatisticsCustomRepository.java | 10 + ...tePaperStatisticsCustomRepositoryImpl.java | 37 + ...java => VotePaperStatisticsJpaEntity.java} | 17 +- .../VotePaperStatisticsRepository.java | 6 + .../persistence/VotePersistenceAdapter.java | 22 +- .../output/SaveVotePaperStatisticsPort.java | 9 + .../service/RegisterVotePaperService.java | 10 +- .../VotePersistenceAdapterTest.java | 1831 +++-------------- 13 files changed, 406 insertions(+), 1588 deletions(-) create mode 100644 src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsCustomRepository.java create mode 100644 src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsCustomRepositoryImpl.java rename src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/{VoteStatisticsJpaEntity.java => VotePaperStatisticsJpaEntity.java} (65%) create mode 100644 src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsRepository.java create mode 100644 src/main/java/com/tune_fun/v1/vote/application/port/output/SaveVotePaperStatisticsPort.java diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java b/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java index d82ec088..b57f7b2e 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java @@ -11,7 +11,6 @@ public class LikeCountAggregationScheduler { private final UpdateVotePaperStatisticsUseCase updateVotePaperStatisticsUseCase; - @Scheduled(fixedDelay = 1000L * 5L) public void aggregateLikeCount() { updateVotePaperStatisticsUseCase.updateVotePaperStatistics(); diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java index 905e26a3..bc639f6c 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java @@ -8,8 +8,6 @@ import java.util.Set; -import static java.util.stream.Collectors.toSet; - @Component @RequiredArgsConstructor public class LikeCountPersistenceAdapter implements SaveVotePaperLikeCountPort, LoadVotePaperLikeCountPort { @@ -21,26 +19,33 @@ public class LikeCountPersistenceAdapter implements SaveVotePaperLikeCountPort, private final RedisTemplate redisTemplate; @Override - public Set getVotePaperIds() { - Set keys = redisTemplate.keys(VOTE_PAPER_LIKE_COUNT_KEY + "*"); - - if (keys == null) return Set.of(); + public Set getVotePaperLikeCountKeys() { + return redisTemplate.keys(VOTE_PAPER_LIKE_COUNT_KEY + "*"); + } - return keys.stream().map(key -> Long.valueOf(key.split("::")[1])).collect(toSet()); + @Override + public Long getVotePaperLikeCount(String key) { + return (Long) redisTemplate.opsForHash().get(key, LIKE_COUNT_HASH_KEY); } @Override public void incrementVotePaperLikeCount(final Long votePaperId) { - redisTemplate.opsForHash().increment(key(votePaperId), LIKE_COUNT_HASH_KEY, 1); + redisTemplate.opsForHash().increment(getKey(votePaperId), LIKE_COUNT_HASH_KEY, 1); } @Override public void decrementVotePaperLikeCount(final Long votePaperId) { - redisTemplate.opsForHash().increment(key(votePaperId), LIKE_COUNT_HASH_KEY, -1); + redisTemplate.opsForHash().increment(getKey(votePaperId), LIKE_COUNT_HASH_KEY, -1); } - private static String key(final Long votePaperId) { + @Override + public String getKey(final Long votePaperId) { return VOTE_PAPER_LIKE_COUNT_KEY + "::" + votePaperId; } + @Override + public Long getVotePaperId(final String key) { + return Long.parseLong(key.split("::")[1]); + } + } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadVotePaperLikeCountPort.java b/src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadVotePaperLikeCountPort.java index 81aa0711..1a03fd7b 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadVotePaperLikeCountPort.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadVotePaperLikeCountPort.java @@ -4,6 +4,11 @@ public interface LoadVotePaperLikeCountPort { - Set getVotePaperIds(); + Set getVotePaperLikeCountKeys(); + Long getVotePaperLikeCount(final String key); + + String getKey(Long votePaperId); + + Long getVotePaperId(String key); } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java index bf2d0fda..171d0322 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java @@ -3,6 +3,7 @@ import com.tune_fun.v1.common.hexagon.UseCase; import com.tune_fun.v1.interaction.application.port.input.usecase.UpdateVotePaperStatisticsUseCase; import com.tune_fun.v1.interaction.application.port.output.LoadVotePaperLikeCountPort; +import com.tune_fun.v1.vote.application.port.output.SaveVotePaperStatisticsPort; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -14,17 +15,17 @@ public class UpdateVotePaperStatisticsService implements UpdateVotePaperStatisticsUseCase { private final LoadVotePaperLikeCountPort loadVotePaperLikeCountPort; - private final UpdateVotePaperStatPort updateVotePaperStatPort; + private final SaveVotePaperStatisticsPort saveVotePaperStatPort; @Override public void updateVotePaperStatistics() { - Set keys = loadVotePaperLikeCountPort.getVotePaperIds(); + Set keys = loadVotePaperLikeCountPort.getVotePaperLikeCountKeys(); keys.forEach(key -> { Long likeCount = loadVotePaperLikeCountPort.getVotePaperLikeCount(key); - updateVotePaperStatPort.updateVotePaperStat(votePaperId, likeCount); + Long votePaperId = loadVotePaperLikeCountPort.getVotePaperId(key); + saveVotePaperStatPort.updateLikeCount(votePaperId, likeCount); }); - } } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperMapper.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperMapper.java index 5c54e548..4cf8aa5f 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperMapper.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperMapper.java @@ -24,12 +24,12 @@ public abstract class VotePaperMapper { @Mapping(target = "authorUsername", source = "author.username") public abstract RegisteredVotePaper registeredVotePaper(final VotePaperJpaEntity votePaperJpaEntity); - @Mapping(target = "authorUsername", source = "author.username") - @Mapping(target = "authorNickname", source = "author.nickname") - @Mapping(target = "remainDays", source = ".", qualifiedByName = "remainDays") + @Mapping(target = "authorUsername", source = "votePaperJpaEntity.author.username") + @Mapping(target = "authorNickname", source = "votePaperJpaEntity.author.nickname") + @Mapping(target = "remainDays", source = "votePaperJpaEntity", qualifiedByName = "remainDays") @Mapping(target = "totalVoteCount", constant = "0") - @Mapping(target = "totalLikeCount", constant = "0") - public abstract ScrollableVotePaper scrollableVotePaper(final VotePaperJpaEntity votePaperJpaEntity); + @Mapping(target = "totalLikeCount", source = "likeCount") + public abstract ScrollableVotePaper scrollableVotePaper(final VotePaperJpaEntity votePaperJpaEntity, final Long likeCount); @Named("remainDays") public Long remainDays(final VotePaperJpaEntity votePaperJpaEntity) { diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsCustomRepository.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsCustomRepository.java new file mode 100644 index 00000000..11fdea82 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsCustomRepository.java @@ -0,0 +1,10 @@ +package com.tune_fun.v1.vote.adapter.output.persistence; + +import java.util.Map; +import java.util.Set; + +public interface VotePaperStatisticsCustomRepository { + void updateLikeCount(final Long votePaperId, final Long likeCount); + + Map findLikeCountMap(final Set votePaperIds); +} diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsCustomRepositoryImpl.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsCustomRepositoryImpl.java new file mode 100644 index 00000000..c0593924 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsCustomRepositoryImpl.java @@ -0,0 +1,37 @@ +package com.tune_fun.v1.vote.adapter.output.persistence; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; +import lombok.RequiredArgsConstructor; + +import java.util.Map; +import java.util.Set; + +import static com.querydsl.core.group.GroupBy.groupBy; + +@RequiredArgsConstructor +public class VotePaperStatisticsCustomRepositoryImpl implements VotePaperStatisticsCustomRepository { + + private final JPAQueryFactory queryFactory; + private final EntityManager entityManager; + + public static final QVotePaperStatisticsJpaEntity VOTE_PAPER_STATISTICS = QVotePaperStatisticsJpaEntity.votePaperStatisticsJpaEntity; + + @Override + public void updateLikeCount(Long votePaperId, Long likeCount) { + queryFactory.update(VOTE_PAPER_STATISTICS) + .set(VOTE_PAPER_STATISTICS.likeCount, likeCount) + .where(VOTE_PAPER_STATISTICS.votePaperId.eq(votePaperId)) + .execute(); + + entityManager.clear(); + entityManager.flush(); + } + + @Override + public Map findLikeCountMap(Set votePaperIds) { + return queryFactory.from(VOTE_PAPER_STATISTICS) + .where(VOTE_PAPER_STATISTICS.votePaperId.in(votePaperIds)) + .transform(groupBy(VOTE_PAPER_STATISTICS.votePaperId).as(VOTE_PAPER_STATISTICS.likeCount)); + } +} diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteStatisticsJpaEntity.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsJpaEntity.java similarity index 65% rename from src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteStatisticsJpaEntity.java rename to src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsJpaEntity.java index 2dd36255..5c6ef8ea 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteStatisticsJpaEntity.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsJpaEntity.java @@ -2,7 +2,10 @@ import com.tune_fun.v1.common.entity.BaseEntity; import io.hypersistence.utils.hibernate.id.Tsid; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -15,8 +18,8 @@ @AllArgsConstructor @Getter @Entity -@Table(name = "vote_statistics") -public class VoteStatisticsJpaEntity extends BaseEntity { +@Table(name = "vote_paper_statistics") +public class VotePaperStatisticsJpaEntity extends BaseEntity { @Id @Tsid @@ -24,10 +27,9 @@ public class VoteStatisticsJpaEntity extends BaseEntity { @Comment("TSID") private Long id; - @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @JoinColumn(name = "vote_paper_id", nullable = false, updatable = false, referencedColumnName = "id") + @Column(name = "vote_paper_id", nullable = false, updatable = false) @Comment("투표 게시물 ID") - private VotePaperJpaEntity votePaper; + private Long votePaperId; @Builder.Default @Column(name = "like_count", nullable = false) @@ -39,5 +41,8 @@ public class VoteStatisticsJpaEntity extends BaseEntity { @Comment("투표 수") private Long voteCount = 0L; + public VotePaperStatisticsJpaEntity(final Long votePaperId) { + this.votePaperId = votePaperId; + } } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsRepository.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsRepository.java new file mode 100644 index 00000000..ebf6f28e --- /dev/null +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsRepository.java @@ -0,0 +1,6 @@ +package com.tune_fun.v1.vote.adapter.output.persistence; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface VotePaperStatisticsRepository extends JpaRepository, VotePaperStatisticsCustomRepository { +} \ No newline at end of file diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java index 73d09104..252ed29b 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java @@ -43,7 +43,8 @@ public class VotePersistenceAdapter implements LoadVotePaperPort, SaveVotePaperPort, DeleteVotePaperPort, UpdateDeliveryAtPort, UpdateVideoUrlPort, LoadVoteChoicePort, SaveVoteChoicePort, - SaveLikePort, DeleteLikePort { + SaveLikePort, DeleteLikePort, + SaveVotePaperStatisticsPort { private final AccountPersistenceAdapter accountPersistenceAdapter; @@ -51,6 +52,7 @@ public class VotePersistenceAdapter implements private final VotePaperRepository votePaperRepository; private final VoteChoiceRepository voteChoiceRepository; private final VotePaperLikeRepository votePaperLikeRepository; + private final VotePaperStatisticsRepository votePaperStatisticsRepository; private final VotePaperMapper votePaperMapper; private final VoteChoiceMapper voteChoiceMapper; @@ -101,7 +103,12 @@ public Window scrollVotePaper(final Integer lastId, final S position = forward(Map.of("id", lastId, "voteEndAt", Constants.LOCAL_DATE_TIME_MIN)); Sort sort = by(desc("id"), desc("voteEndAt")); - return votePaperRepository.findFirst10ByEnabledTrue(position, sort).map(votePaperMapper::scrollableVotePaper); + Window scroll = votePaperRepository.findFirst10ByEnabledTrue(position, sort); + + Set votePaperIds = scroll.stream().map(VotePaperJpaEntity::getId).collect(toSet()); + Map likeCountMap = votePaperStatisticsRepository.findLikeCountMap(votePaperIds); + + return scroll.map(votePaperJpaEntity -> votePaperMapper.scrollableVotePaper(votePaperJpaEntity, likeCountMap.get(votePaperJpaEntity.getId()))); } @Override @@ -199,6 +206,17 @@ public void deleteVotePaperLike(final Long likeId) { votePaperLikeRepository.deleteById(likeId); } + @Override + public void initializeStatistics(final Long votePaperId) { + VotePaperStatisticsJpaEntity stat = new VotePaperStatisticsJpaEntity(votePaperId); + votePaperStatisticsRepository.save(stat); + } + + @Override + public void updateLikeCount(final Long votePaperId, final Long likeCount) { + votePaperStatisticsRepository.updateLikeCount(votePaperId, likeCount); + } + public Optional findOneAvailable(final Long votePaperId, final String username) { return votePaperRepository.findOneAvailable(votePaperId, username); } diff --git a/src/main/java/com/tune_fun/v1/vote/application/port/output/SaveVotePaperStatisticsPort.java b/src/main/java/com/tune_fun/v1/vote/application/port/output/SaveVotePaperStatisticsPort.java new file mode 100644 index 00000000..aedd6077 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/vote/application/port/output/SaveVotePaperStatisticsPort.java @@ -0,0 +1,9 @@ +package com.tune_fun.v1.vote.application.port.output; + +public interface SaveVotePaperStatisticsPort { + + void initializeStatistics(final Long votePaperId); + + void updateLikeCount(final Long votePaperId, final Long likeCount); + +} diff --git a/src/main/java/com/tune_fun/v1/vote/application/service/RegisterVotePaperService.java b/src/main/java/com/tune_fun/v1/vote/application/service/RegisterVotePaperService.java index 6676d8d7..75fc0a71 100644 --- a/src/main/java/com/tune_fun/v1/vote/application/service/RegisterVotePaperService.java +++ b/src/main/java/com/tune_fun/v1/vote/application/service/RegisterVotePaperService.java @@ -5,10 +5,7 @@ import com.tune_fun.v1.common.hexagon.UseCase; import com.tune_fun.v1.vote.application.port.input.command.VotePaperCommands; import com.tune_fun.v1.vote.application.port.input.usecase.RegisterVotePaperUseCase; -import com.tune_fun.v1.vote.application.port.output.LoadVotePaperPort; -import com.tune_fun.v1.vote.application.port.output.ProduceVotePaperRegisterEventPort; -import com.tune_fun.v1.vote.application.port.output.SaveVoteChoicePort; -import com.tune_fun.v1.vote.application.port.output.SaveVotePaperPort; +import com.tune_fun.v1.vote.application.port.output.*; import com.tune_fun.v1.vote.domain.behavior.SaveVoteChoice; import com.tune_fun.v1.vote.domain.behavior.SaveVotePaper; import com.tune_fun.v1.vote.domain.event.VotePaperDeadlineEvent; @@ -39,6 +36,8 @@ public class RegisterVotePaperService implements RegisterVotePaperUseCase { private final SaveVoteChoicePort saveVoteChoicePort; + private final SaveVotePaperStatisticsPort saveVotePaperStatisticsPort; + private final ProduceVotePaperRegisterEventPort produceVotePaperRegisterEventPort; private final ApplicationEventPublisher applicationEventPublisher; @@ -55,6 +54,9 @@ public void register(final VotePaperCommands.Register command, final User user) validateRegistrableVotePaperCount(user); RegisteredVotePaper registeredVotePaper = saveVotePaper(command, user); + + saveVotePaperStatisticsPort.initializeStatistics(registeredVotePaper.id()); + saveVoteChoiceByRegisteredVotePaper(command, registeredVotePaper); VotePaperRegisterEvent votePaperRegisterEventBehavior = getProduceVotePaperUploadEventBehavior(registeredVotePaper); diff --git a/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java b/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java index 672fea60..948be93a 100644 --- a/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java +++ b/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java @@ -1,33 +1,65 @@ package com.tune_fun.v1.vote.adapter.output.persistence; import com.tune_fun.v1.account.adapter.output.persistence.AccountJpaEntity; -import com.tune_fun.v1.account.adapter.output.persistence.AccountMapperImpl; import com.tune_fun.v1.account.adapter.output.persistence.AccountPersistenceAdapter; -import com.tune_fun.v1.account.adapter.output.persistence.AccountRepository; -import com.tune_fun.v1.account.adapter.output.persistence.oauth2.OAuth2AccountRepository; +import com.tune_fun.v1.common.constant.Constants; import com.tune_fun.v1.interaction.adapter.output.persistence.VotePaperLikeJpaEntity; import com.tune_fun.v1.interaction.adapter.output.persistence.VotePaperLikeRepository; -import com.tune_fun.v1.vote.domain.behavior.SaveVoteChoice; import com.tune_fun.v1.vote.domain.behavior.SaveVotePaper; import com.tune_fun.v1.vote.domain.value.RegisteredVote; import com.tune_fun.v1.vote.domain.value.RegisteredVoteChoice; import com.tune_fun.v1.vote.domain.value.RegisteredVotePaper; import com.tune_fun.v1.vote.domain.value.VotePaperOption; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.domain.KeysetScrollPosition; import org.springframework.data.domain.Sort; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.aot.DisabledInAotMode; +import org.springframework.test.context.junit.jupiter.SpringExtension; -import java.time.LocalDate; import java.time.LocalDateTime; -import java.time.LocalTime; import java.util.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +@ContextConfiguration(classes = {VotePersistenceAdapter.class}) +@ExtendWith(SpringExtension.class) +@DisabledInAotMode class VotePersistenceAdapterTest { + + @MockBean + private AccountPersistenceAdapter accountPersistenceAdapter; + + @MockBean + private VoteChoiceMapper voteChoiceMapper; + + @MockBean + private VoteChoiceRepository voteChoiceRepository; + + @MockBean + private VotePaperLikeRepository votePaperLikeRepository; + + @MockBean + private VotePaperMapper votePaperMapper; + + @MockBean + private VotePaperRepository votePaperRepository; + + @MockBean + private VotePaperStatisticsRepository votePaperStatisticsRepository; + + @Autowired + private VotePersistenceAdapter votePersistenceAdapter; + + @MockBean + private VoteRepository voteRepository; + /** * Method under test: * {@link VotePersistenceAdapter#loadVoterIdsByVotePaperUuid(String)} @@ -35,23 +67,12 @@ class VotePersistenceAdapterTest { @Test void testLoadVoterIdsByVotePaperUuid() { // Arrange - VoteRepository voteRepository = mock(VoteRepository.class); ArrayList resultLongList = new ArrayList<>(); when(voteRepository.findVoterIdsByVotePaperUuid(Mockito.any())).thenReturn(resultLongList); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act - List actualLoadVoterIdsByVotePaperUuidResult = (new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl())).loadVoterIdsByVotePaperUuid("01234567-89AB-CDEF-FEDC-BA9876543210"); + List actualLoadVoterIdsByVotePaperUuidResult = votePersistenceAdapter + .loadVoterIdsByVotePaperUuid("01234567-89AB-CDEF-FEDC-BA9876543210"); // Assert verify(voteRepository).findVoterIdsByVotePaperUuid(eq("01234567-89AB-CDEF-FEDC-BA9876543210")); @@ -66,24 +87,12 @@ void testLoadVoterIdsByVotePaperUuid() { @Test void testLoadVoterIdsByVotePaperUuid2() { // Arrange - VoteRepository voteRepository = mock(VoteRepository.class); when(voteRepository.findVoterIdsByVotePaperUuid(Mockito.any())) .thenThrow(new IllegalArgumentException("foo")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .loadVoterIdsByVotePaperUuid("01234567-89AB-CDEF-FEDC-BA9876543210")); + () -> votePersistenceAdapter.loadVoterIdsByVotePaperUuid("01234567-89AB-CDEF-FEDC-BA9876543210")); verify(voteRepository).findVoterIdsByVotePaperUuid(eq("01234567-89AB-CDEF-FEDC-BA9876543210")); } @@ -94,7 +103,6 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testLoadVoteByVoterAndVotePaperId() { // Arrange - VoteRepository voteRepository = mock(VoteRepository.class); RegisteredVote buildResult = RegisteredVote.builder() .artistName("Artist Name") .id(1L) @@ -106,20 +114,10 @@ void testLoadVoteByVoterAndVotePaperId() { Optional ofResult = Optional.of(buildResult); when(voteRepository.findByVoterUsernameAndVotePaperId(Mockito.any(), Mockito.any())) .thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act - Optional actualLoadVoteByVoterAndVotePaperIdResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).loadVoteByVoterAndVotePaperId("Voter", 1L); + Optional actualLoadVoteByVoterAndVotePaperIdResult = votePersistenceAdapter + .loadVoteByVoterAndVotePaperId("Voter", 1L); // Assert verify(voteRepository).findByVoterUsernameAndVotePaperId(eq("Voter"), eq(1L)); @@ -133,24 +131,12 @@ void testLoadVoteByVoterAndVotePaperId() { @Test void testLoadVoteByVoterAndVotePaperId2() { // Arrange - VoteRepository voteRepository = mock(VoteRepository.class); when(voteRepository.findByVoterUsernameAndVotePaperId(Mockito.any(), Mockito.any())) .thenThrow(new IllegalArgumentException("foo")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .loadVoteByVoterAndVotePaperId("Voter", 1L)); + () -> votePersistenceAdapter.loadVoteByVoterAndVotePaperId("Voter", 1L)); verify(voteRepository).findByVoterUsernameAndVotePaperId(eq("Voter"), eq(1L)); } @@ -160,29 +146,17 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testSaveVote() { // Arrange - AccountRepository accountRepository = mock(AccountRepository.class); Optional ofResult = Optional.of(new AccountJpaEntity()); - when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(ofResult); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); + when(accountPersistenceAdapter.loadAccountByUsername(Mockito.any())).thenReturn(ofResult); when(voteRepository.save(Mockito.any())).thenReturn(new VoteJpaEntity()); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); Optional ofResult2 = Optional.of(new VoteChoiceJpaEntity()); when(voteChoiceRepository.findById(Mockito.any())).thenReturn(ofResult2); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act - (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, - votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).saveVote(1L, "janedoe"); + votePersistenceAdapter.saveVote(1L, "janedoe"); // Assert - verify(accountRepository).findActive(eq("janedoe"), isNull(), isNull()); + verify(accountPersistenceAdapter).loadAccountByUsername(eq("janedoe")); verify(voteChoiceRepository).findById(eq(1L)); verify(voteRepository).save(isA(VoteJpaEntity.class)); } @@ -193,29 +167,15 @@ void testSaveVote() { @Test void testSaveVote2() { // Arrange - AccountRepository accountRepository = mock(AccountRepository.class); Optional ofResult = Optional.of(new AccountJpaEntity()); - when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(ofResult); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); + when(accountPersistenceAdapter.loadAccountByUsername(Mockito.any())).thenReturn(ofResult); when(voteRepository.save(Mockito.any())).thenThrow(new IllegalArgumentException("foo")); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); Optional ofResult2 = Optional.of(new VoteChoiceJpaEntity()); when(voteChoiceRepository.findById(Mockito.any())).thenReturn(ofResult2); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).saveVote(1L, - "janedoe")); - verify(accountRepository).findActive(eq("janedoe"), isNull(), isNull()); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.saveVote(1L, "janedoe")); + verify(accountPersistenceAdapter).loadAccountByUsername(eq("janedoe")); verify(voteChoiceRepository).findById(eq(1L)); verify(voteRepository).save(isA(VoteJpaEntity.class)); } @@ -226,28 +186,14 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testSaveVote3() { // Arrange - AccountRepository accountRepository = mock(AccountRepository.class); Optional emptyResult = Optional.empty(); - when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(emptyResult); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); + when(accountPersistenceAdapter.loadAccountByUsername(Mockito.any())).thenReturn(emptyResult); Optional ofResult = Optional.of(new VoteChoiceJpaEntity()); when(voteChoiceRepository.findById(Mockito.any())).thenReturn(ofResult); - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).saveVote(1L, - "janedoe")); - verify(accountRepository).findActive(eq("janedoe"), isNull(), isNull()); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.saveVote(1L, "janedoe")); + verify(accountPersistenceAdapter).loadAccountByUsername(eq("janedoe")); verify(voteChoiceRepository).findById(eq(1L)); } @@ -257,24 +203,11 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testSaveVote4() { // Arrange - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); Optional emptyResult = Optional.empty(); when(voteChoiceRepository.findById(Mockito.any())).thenReturn(emptyResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).saveVote(1L, - "janedoe")); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.saveVote(1L, "janedoe")); verify(voteChoiceRepository).findById(eq(1L)); } @@ -285,24 +218,11 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testScrollVotePaper() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); when(votePaperRepository.findFirst10ByEnabledTrue(Mockito.any(), Mockito.any())) .thenThrow(new IllegalArgumentException("id")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .scrollVotePaper(1, "Sort Type")); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.scrollVotePaper(1, "Sort Type")); verify(votePaperRepository).findFirst10ByEnabledTrue(isA(KeysetScrollPosition.class), isA(Sort.class)); } @@ -313,24 +233,11 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testScrollVotePaper2() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); when(votePaperRepository.findFirst10ByEnabledTrue(Mockito.any(), Mockito.any())) .thenThrow(new IllegalArgumentException("id")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .scrollVotePaper(0, "Sort Type")); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.scrollVotePaper(0, "Sort Type")); verify(votePaperRepository).findFirst10ByEnabledTrue(isA(KeysetScrollPosition.class), isA(Sort.class)); } @@ -341,142 +248,25 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testLoadRegisteredVotePaper() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional ofResult = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findByVoteEndAtAfterAndIdAndEnabledTrue(Mockito.any(), Mockito.any())) .thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + when(votePaperMapper.registeredVotePaper(Mockito.any())) + .thenReturn(new RegisteredVotePaper(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", "JaneDoe", "janedoe", "Dr", + "Not all who wander are lost", VotePaperOption.ALLOW_ADD_CHOICES, "https://example.org/example", + Constants.LOCAL_DATE_TIME_MIN, Constants.LOCAL_DATE_TIME_MIN, Constants.LOCAL_DATE_TIME_MIN, + Constants.LOCAL_DATE_TIME_MIN, Constants.LOCAL_DATE_TIME_MIN)); // Act - Optional actualLoadRegisteredVotePaperResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVotePaper(1L); + Optional actualLoadRegisteredVotePaperResult = votePersistenceAdapter + .loadRegisteredVotePaper(1L); // Assert + verify(votePaperMapper).registeredVotePaper(isA(VotePaperJpaEntity.class)); verify(votePaperRepository).findByVoteEndAtAfterAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); RegisteredVotePaper getResult = actualLoadRegisteredVotePaperResult.get(); - assertNull(getResult.option()); - assertNull(getResult.id()); - assertNull(getResult.author()); - assertNull(getResult.authorUsername()); - assertNull(getResult.content()); - assertNull(getResult.title()); - assertNull(getResult.uuid()); - assertNull(getResult.videoUrl()); - assertNull(getResult.createdAt()); - assertNull(getResult.deliveryAt()); - assertNull(getResult.updatedAt()); - assertNull(getResult.voteEndAt()); - assertNull(getResult.voteStartAt()); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#loadRegisteredVotePaper(Long)} - */ - @Test - void testLoadRegisteredVotePaper2() { - // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - AccountJpaEntity author = new AccountJpaEntity(); - LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - LocalDateTime voteEndAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - LocalDateTime deliveryAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - ArrayList choices = new ArrayList<>(); - Optional ofResult = Optional - .of(new VotePaperJpaEntity(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", "Dr", "Not all who wander are lost", - "Page Link", author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, voteEndAt, deliveryAt, true, - "https://example.org/example", choices, new ArrayList<>())); - when(votePaperRepository.findByVoteEndAtAfterAndIdAndEnabledTrue(Mockito.any(), Mockito.any())) - .thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act - Optional actualLoadRegisteredVotePaperResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVotePaper(1L); - - // Assert - verify(votePaperRepository).findByVoteEndAtAfterAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); - RegisteredVotePaper getResult = actualLoadRegisteredVotePaperResult.get(); - LocalTime expectedToLocalTimeResult = getResult.voteStartAt().toLocalTime(); - assertSame(expectedToLocalTimeResult, getResult.voteEndAt().toLocalTime()); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#loadRegisteredVotePaper(Long)} - */ - @Test - void testLoadRegisteredVotePaper3() { - // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - Optional emptyResult = Optional.empty(); - when(votePaperRepository.findByVoteEndAtAfterAndIdAndEnabledTrue(Mockito.any(), Mockito.any())) - .thenReturn(emptyResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act - Optional actualLoadRegisteredVotePaperResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVotePaper(1L); - - // Assert - verify(votePaperRepository).findByVoteEndAtAfterAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); - assertFalse(actualLoadRegisteredVotePaperResult.isPresent()); - assertSame(emptyResult, actualLoadRegisteredVotePaperResult); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#loadRegisteredVotePaper(Long)} - */ - @Test - void testLoadRegisteredVotePaper4() { - // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.findByVoteEndAtAfterAndIdAndEnabledTrue(Mockito.any(), Mockito.any())) - .thenThrow(new IllegalArgumentException("foo")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .loadRegisteredVotePaper(1L)); - verify(votePaperRepository).findByVoteEndAtAfterAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); + LocalDateTime expectedVoteEndAtResult = getResult.voteStartAt(); + assertSame(expectedVoteEndAtResult, getResult.voteEndAt()); } /** @@ -484,148 +274,28 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa * {@link VotePersistenceAdapter#loadRegisteredVotePaper(String)} */ @Test - void testLoadRegisteredVotePaper5() { + void testLoadRegisteredVotePaper2() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional ofResult = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + when(votePaperMapper.registeredVotePaper(Mockito.any())) + .thenReturn(new RegisteredVotePaper(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", "JaneDoe", "janedoe", "Dr", + "Not all who wander are lost", VotePaperOption.ALLOW_ADD_CHOICES, "https://example.org/example", + Constants.LOCAL_DATE_TIME_MIN, Constants.LOCAL_DATE_TIME_MIN, Constants.LOCAL_DATE_TIME_MIN, + Constants.LOCAL_DATE_TIME_MIN, Constants.LOCAL_DATE_TIME_MIN)); // Act - Optional actualLoadRegisteredVotePaperResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVotePaper("janedoe"); + Optional actualLoadRegisteredVotePaperResult = votePersistenceAdapter + .loadRegisteredVotePaper("janedoe"); // Assert + verify(votePaperMapper).registeredVotePaper(isA(VotePaperJpaEntity.class)); verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), eq("janedoe")); RegisteredVotePaper getResult = actualLoadRegisteredVotePaperResult.get(); - assertNull(getResult.option()); - assertNull(getResult.id()); - assertNull(getResult.author()); - assertNull(getResult.authorUsername()); - assertNull(getResult.content()); - assertNull(getResult.title()); - assertNull(getResult.uuid()); - assertNull(getResult.videoUrl()); - assertNull(getResult.createdAt()); - assertNull(getResult.deliveryAt()); - assertNull(getResult.updatedAt()); - assertNull(getResult.voteEndAt()); - assertNull(getResult.voteStartAt()); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#loadRegisteredVotePaper(String)} - */ - @Test - void testLoadRegisteredVotePaper6() { - // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - AccountJpaEntity author = new AccountJpaEntity(); - LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - LocalDateTime voteEndAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - LocalDateTime deliveryAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - ArrayList choices = new ArrayList<>(); - Optional ofResult = Optional - .of(new VotePaperJpaEntity(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", "Dr", "Not all who wander are lost", - "Page Link", author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, voteEndAt, deliveryAt, true, - "https://example.org/example", choices, new ArrayList<>())); - when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), - Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act - Optional actualLoadRegisteredVotePaperResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVotePaper("janedoe"); - - // Assert - verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), - eq("janedoe")); - RegisteredVotePaper getResult = actualLoadRegisteredVotePaperResult.get(); - LocalTime expectedToLocalTimeResult = getResult.voteStartAt().toLocalTime(); - assertSame(expectedToLocalTimeResult, getResult.voteEndAt().toLocalTime()); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#loadRegisteredVotePaper(String)} - */ - @Test - void testLoadRegisteredVotePaper7() { - // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - Optional emptyResult = Optional.empty(); - when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), - Mockito.any())).thenReturn(emptyResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act - Optional actualLoadRegisteredVotePaperResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVotePaper("janedoe"); - - // Assert - verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), - eq("janedoe")); - assertFalse(actualLoadRegisteredVotePaperResult.isPresent()); - assertSame(emptyResult, actualLoadRegisteredVotePaperResult); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#loadRegisteredVotePaper(String)} - */ - @Test - void testLoadRegisteredVotePaper8() { - // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), - Mockito.any())).thenThrow(new IllegalArgumentException("foo")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .loadRegisteredVotePaper("janedoe")); - verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), - eq("janedoe")); + LocalDateTime expectedVoteEndAtResult = getResult.voteStartAt(); + assertSame(expectedVoteEndAtResult, getResult.voteEndAt()); } /** @@ -635,46 +305,29 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testSaveVotePaper() { // Arrange - AccountRepository accountRepository = mock(AccountRepository.class); Optional ofResult = Optional.of(new AccountJpaEntity()); - when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(ofResult); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + when(accountPersistenceAdapter.loadAccountByUsername(Mockito.any())).thenReturn(ofResult); when(votePaperRepository.save(Mockito.any())).thenReturn(new VotePaperJpaEntity()); - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); - LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); + when(votePaperMapper.fromSaveVotePaperBehavior(Mockito.any(), Mockito.any())) + .thenReturn(new VotePaperJpaEntity()); + when(votePaperMapper.registeredVotePaper(Mockito.any())) + .thenReturn(new RegisteredVotePaper(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", "JaneDoe", "janedoe", "Dr", + "Not all who wander are lost", VotePaperOption.ALLOW_ADD_CHOICES, "https://example.org/example", + Constants.LOCAL_DATE_TIME_MIN, Constants.LOCAL_DATE_TIME_MIN, Constants.LOCAL_DATE_TIME_MIN, + Constants.LOCAL_DATE_TIME_MIN, Constants.LOCAL_DATE_TIME_MIN)); // Act RegisteredVotePaper actualSaveVotePaperResult = votePersistenceAdapter .saveVotePaper(new SaveVotePaper("Dr", "Not all who wander are lost", "JaneDoe", - VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, LocalDate.of(1970, 1, 1).atStartOfDay())); + VotePaperOption.ALLOW_ADD_CHOICES, Constants.LOCAL_DATE_TIME_MIN, Constants.LOCAL_DATE_TIME_MIN)); // Assert - verify(accountRepository).findActive(eq("JaneDoe"), isNull(), isNull()); + verify(accountPersistenceAdapter).loadAccountByUsername(eq("JaneDoe")); + verify(votePaperMapper).fromSaveVotePaperBehavior(isA(SaveVotePaper.class), isA(AccountJpaEntity.class)); + verify(votePaperMapper).registeredVotePaper(isA(VotePaperJpaEntity.class)); verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); - assertNull(actualSaveVotePaperResult.option()); - assertNull(actualSaveVotePaperResult.id()); - assertNull(actualSaveVotePaperResult.author()); - assertNull(actualSaveVotePaperResult.authorUsername()); - assertNull(actualSaveVotePaperResult.content()); - assertNull(actualSaveVotePaperResult.title()); - assertNull(actualSaveVotePaperResult.uuid()); - assertNull(actualSaveVotePaperResult.videoUrl()); - assertNull(actualSaveVotePaperResult.createdAt()); - assertNull(actualSaveVotePaperResult.deliveryAt()); - assertNull(actualSaveVotePaperResult.updatedAt()); - assertNull(actualSaveVotePaperResult.voteEndAt()); - assertNull(actualSaveVotePaperResult.voteStartAt()); + LocalDateTime expectedVoteEndAtResult = actualSaveVotePaperResult.voteStartAt(); + assertSame(expectedVoteEndAtResult, actualSaveVotePaperResult.voteEndAt()); } /** @@ -684,31 +337,17 @@ void testSaveVotePaper() { @Test void testSaveVotePaper2() { // Arrange - AccountRepository accountRepository = mock(AccountRepository.class); Optional ofResult = Optional.of(new AccountJpaEntity()); - when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(ofResult); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.save(Mockito.any())).thenThrow(new IllegalArgumentException("foo")); - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); - LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); + when(accountPersistenceAdapter.loadAccountByUsername(Mockito.any())).thenReturn(ofResult); + when(votePaperMapper.fromSaveVotePaperBehavior(Mockito.any(), Mockito.any())) + .thenThrow(new IllegalArgumentException("foo")); // Act and Assert assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.saveVotePaper(new SaveVotePaper("Dr", "Not all who wander are lost", "JaneDoe", - VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, LocalDate.of(1970, 1, 1).atStartOfDay()))); - verify(accountRepository).findActive(eq("JaneDoe"), isNull(), isNull()); - verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); + VotePaperOption.ALLOW_ADD_CHOICES, Constants.LOCAL_DATE_TIME_MIN, Constants.LOCAL_DATE_TIME_MIN))); + verify(accountPersistenceAdapter).loadAccountByUsername(eq("JaneDoe")); + verify(votePaperMapper).fromSaveVotePaperBehavior(isA(SaveVotePaper.class), isA(AccountJpaEntity.class)); } /** @@ -718,112 +357,14 @@ void testSaveVotePaper2() { @Test void testSaveVotePaper3() { // Arrange - AccountRepository accountRepository = mock(AccountRepository.class); Optional emptyResult = Optional.empty(); - when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(emptyResult); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); - LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); + when(accountPersistenceAdapter.loadAccountByUsername(Mockito.any())).thenReturn(emptyResult); // Act and Assert assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.saveVotePaper(new SaveVotePaper("Dr", "Not all who wander are lost", "JaneDoe", - VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, LocalDate.of(1970, 1, 1).atStartOfDay()))); - verify(accountRepository).findActive(eq("JaneDoe"), isNull(), isNull()); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#saveVotePaper(SaveVotePaper)} - */ - @Test - void testSaveVotePaper4() { - // Arrange - AccountRepository accountRepository = mock(AccountRepository.class); - Optional ofResult = Optional.of(new AccountJpaEntity()); - when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(ofResult); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.save(Mockito.any())).thenReturn(null); - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); - LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - - // Act - RegisteredVotePaper actualSaveVotePaperResult = votePersistenceAdapter - .saveVotePaper(new SaveVotePaper("Dr", "Not all who wander are lost", "JaneDoe", - VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, LocalDate.of(1970, 1, 1).atStartOfDay())); - - // Assert - verify(accountRepository).findActive(eq("JaneDoe"), isNull(), isNull()); - verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); - assertNull(actualSaveVotePaperResult); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#saveVotePaper(SaveVotePaper)} - */ - @Test - void testSaveVotePaper5() { - // Arrange - AccountRepository accountRepository = mock(AccountRepository.class); - Optional ofResult = Optional.of(new AccountJpaEntity()); - when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(ofResult); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - AccountJpaEntity author = new AccountJpaEntity(); - LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - LocalDateTime voteEndAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - LocalDateTime deliveryAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - ArrayList choices = new ArrayList<>(); - when(votePaperRepository.save(Mockito.any())) - .thenReturn(new VotePaperJpaEntity(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", "Dr", - "Not all who wander are lost", "Page Link", author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, - voteEndAt, deliveryAt, true, "https://example.org/example", choices, new ArrayList<>())); - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); - LocalDateTime voteStartAt2 = LocalDate.of(1970, 1, 1).atStartOfDay(); - - // Act - RegisteredVotePaper actualSaveVotePaperResult = votePersistenceAdapter - .saveVotePaper(new SaveVotePaper("Dr", "Not all who wander are lost", "JaneDoe", - VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt2, LocalDate.of(1970, 1, 1).atStartOfDay())); - - // Assert - verify(accountRepository).findActive(eq("JaneDoe"), isNull(), isNull()); - verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); - LocalTime expectedToLocalTimeResult = actualSaveVotePaperResult.voteStartAt().toLocalTime(); - assertSame(expectedToLocalTimeResult, actualSaveVotePaperResult.voteEndAt().toLocalTime()); + VotePaperOption.ALLOW_ADD_CHOICES, Constants.LOCAL_DATE_TIME_MIN, Constants.LOCAL_DATE_TIME_MIN))); + verify(accountPersistenceAdapter).loadAccountByUsername(eq("JaneDoe")); } /** @@ -832,23 +373,12 @@ void testSaveVotePaper5() { @Test void testDisableVotePaper() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); when(votePaperRepository.save(Mockito.any())).thenReturn(new VotePaperJpaEntity()); Optional ofResult = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findById(Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act - (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, - votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).disableVotePaper(1L); + votePersistenceAdapter.disableVotePaper(1L); // Assert verify(votePaperRepository).findById(eq(1L)); @@ -861,25 +391,12 @@ void testDisableVotePaper() { @Test void testDisableVotePaper2() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); when(votePaperRepository.save(Mockito.any())).thenThrow(new IllegalArgumentException("foo")); Optional ofResult = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findById(Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .disableVotePaper(1L)); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.disableVotePaper(1L)); verify(votePaperRepository).findById(eq(1L)); verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); } @@ -890,102 +407,52 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testDisableVotePaper3() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - Optional emptyResult = Optional.empty(); - when(votePaperRepository.findById(Mockito.any())).thenReturn(emptyResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + VotePaperJpaEntity votePaperJpaEntity = mock(VotePaperJpaEntity.class); + doNothing().when(votePaperJpaEntity).disable(); + Optional ofResult = Optional.of(votePaperJpaEntity); + when(votePaperRepository.save(Mockito.any())).thenReturn(new VotePaperJpaEntity()); + when(votePaperRepository.findById(Mockito.any())).thenReturn(ofResult); // Act - (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, - votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).disableVotePaper(1L); + votePersistenceAdapter.disableVotePaper(1L); - // Assert + // Assert that nothing has changed + verify(votePaperJpaEntity).disable(); verify(votePaperRepository).findById(eq(1L)); + verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); } /** - * Method under test: - * {@link VotePersistenceAdapter#updateDeliveryAt(Long, LocalDateTime)} + * Method under test: {@link VotePersistenceAdapter#disableVotePaper(Long)} */ @Test - void testUpdateDeliveryAt() { + void testDisableVotePaper4() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.save(Mockito.any())).thenReturn(new VotePaperJpaEntity()); - Optional ofResult = Optional.of(new VotePaperJpaEntity()); - when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); + Optional emptyResult = Optional.empty(); + when(votePaperRepository.findById(Mockito.any())).thenReturn(emptyResult); // Act - RegisteredVotePaper actualUpdateDeliveryAtResult = votePersistenceAdapter.updateDeliveryAt(1L, - LocalDate.of(1970, 1, 1).atStartOfDay()); + votePersistenceAdapter.disableVotePaper(1L); - // Assert - verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); - verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); - assertNull(actualUpdateDeliveryAtResult.option()); - assertNull(actualUpdateDeliveryAtResult.id()); - assertNull(actualUpdateDeliveryAtResult.author()); - assertNull(actualUpdateDeliveryAtResult.authorUsername()); - assertNull(actualUpdateDeliveryAtResult.content()); - assertNull(actualUpdateDeliveryAtResult.title()); - assertNull(actualUpdateDeliveryAtResult.uuid()); - assertNull(actualUpdateDeliveryAtResult.videoUrl()); - assertNull(actualUpdateDeliveryAtResult.createdAt()); - assertNull(actualUpdateDeliveryAtResult.deliveryAt()); - assertNull(actualUpdateDeliveryAtResult.updatedAt()); - assertNull(actualUpdateDeliveryAtResult.voteEndAt()); - assertNull(actualUpdateDeliveryAtResult.voteStartAt()); + // Assert that nothing has changed + verify(votePaperRepository).findById(eq(1L)); } /** - * Method under test: - * {@link VotePersistenceAdapter#updateDeliveryAt(Long, LocalDateTime)} + * Method under test: {@link VotePersistenceAdapter#disableVotePaper(Long)} */ @Test - void testUpdateDeliveryAt2() { + void testDisableVotePaper5() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.save(Mockito.any())).thenThrow(new IllegalArgumentException("foo")); - Optional ofResult = Optional.of(new VotePaperJpaEntity()); - when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); + VotePaperJpaEntity votePaperJpaEntity = mock(VotePaperJpaEntity.class); + doThrow(new IllegalArgumentException("foo")).when(votePaperJpaEntity).disable(); + Optional ofResult = Optional.of(votePaperJpaEntity); + when(votePaperRepository.findById(Mockito.any())).thenReturn(ofResult); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> votePersistenceAdapter.updateDeliveryAt(1L, LocalDate.of(1970, 1, 1).atStartOfDay())); - verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); - verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.disableVotePaper(1L)); + verify(votePaperJpaEntity).disable(); + verify(votePaperRepository).findById(eq(1L)); } /** @@ -993,33 +460,20 @@ void testUpdateDeliveryAt2() { * {@link VotePersistenceAdapter#updateDeliveryAt(Long, LocalDateTime)} */ @Test - void testUpdateDeliveryAt3() { + void testUpdateDeliveryAt() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.save(Mockito.any())).thenReturn(null); Optional ofResult = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); - - // Act - RegisteredVotePaper actualUpdateDeliveryAtResult = votePersistenceAdapter.updateDeliveryAt(1L, - LocalDate.of(1970, 1, 1).atStartOfDay()); + Mockito.>when(votePaperMapper.updateDeliveryAt( + any(), any())) + .thenThrow(new IllegalArgumentException("foo")); - // Assert + // Act and Assert + assertThrows(IllegalArgumentException.class, + () -> votePersistenceAdapter.updateDeliveryAt(1L, Constants.LOCAL_DATE_TIME_MIN)); verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); - verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); - assertNull(actualUpdateDeliveryAtResult); + verify(votePaperMapper).updateDeliveryAt(isA(LocalDateTime.class), + isA(VotePaperJpaEntity.VotePaperJpaEntityBuilder.class)); } /** @@ -1027,42 +481,15 @@ void testUpdateDeliveryAt3() { * {@link VotePersistenceAdapter#updateDeliveryAt(Long, LocalDateTime)} */ @Test - void testUpdateDeliveryAt4() { + void testUpdateDeliveryAt2() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - AccountJpaEntity author = new AccountJpaEntity(); - LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - LocalDateTime voteEndAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - LocalDateTime deliveryAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - ArrayList choices = new ArrayList<>(); - when(votePaperRepository.save(Mockito.any())) - .thenReturn(new VotePaperJpaEntity(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", "Dr", - "Not all who wander are lost", "Page Link", author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, - voteEndAt, deliveryAt, true, "https://example.org/example", choices, new ArrayList<>())); - Optional ofResult = Optional.of(new VotePaperJpaEntity()); - when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); - - // Act - RegisteredVotePaper actualUpdateDeliveryAtResult = votePersistenceAdapter.updateDeliveryAt(1L, - LocalDate.of(1970, 1, 1).atStartOfDay()); + Optional emptyResult = Optional.empty(); + when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(emptyResult); - // Assert + // Act and Assert + assertThrows(IllegalArgumentException.class, + () -> votePersistenceAdapter.updateDeliveryAt(1L, Constants.LOCAL_DATE_TIME_MIN)); verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); - verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); - LocalTime expectedToLocalTimeResult = actualUpdateDeliveryAtResult.voteStartAt().toLocalTime(); - assertSame(expectedToLocalTimeResult, actualUpdateDeliveryAtResult.voteEndAt().toLocalTime()); } /** @@ -1070,75 +497,19 @@ void testUpdateDeliveryAt4() { * {@link VotePersistenceAdapter#updateDeliveryAt(Long, LocalDateTime)} */ @Test - void testUpdateDeliveryAt5() { + void testUpdateDeliveryAt3() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.save(Mockito.any())).thenReturn(new VotePaperJpaEntity()); - Optional ofResult = Optional - .of(new VotePaperJpaEntity(mock(VotePaperJpaEntity.VotePaperJpaEntityBuilder.class))); + VotePaperJpaEntity votePaperJpaEntity = mock(VotePaperJpaEntity.class); + Mockito.>when(votePaperJpaEntity.toBuilder()) + .thenThrow(new IllegalArgumentException("foo")); + Optional ofResult = Optional.of(votePaperJpaEntity); when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); - - // Act - RegisteredVotePaper actualUpdateDeliveryAtResult = votePersistenceAdapter.updateDeliveryAt(1L, - LocalDate.of(1970, 1, 1).atStartOfDay()); - - // Assert - verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); - verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); - assertNull(actualUpdateDeliveryAtResult.option()); - assertNull(actualUpdateDeliveryAtResult.id()); - assertNull(actualUpdateDeliveryAtResult.author()); - assertNull(actualUpdateDeliveryAtResult.authorUsername()); - assertNull(actualUpdateDeliveryAtResult.content()); - assertNull(actualUpdateDeliveryAtResult.title()); - assertNull(actualUpdateDeliveryAtResult.uuid()); - assertNull(actualUpdateDeliveryAtResult.videoUrl()); - assertNull(actualUpdateDeliveryAtResult.createdAt()); - assertNull(actualUpdateDeliveryAtResult.deliveryAt()); - assertNull(actualUpdateDeliveryAtResult.updatedAt()); - assertNull(actualUpdateDeliveryAtResult.voteEndAt()); - assertNull(actualUpdateDeliveryAtResult.voteStartAt()); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#updateDeliveryAt(Long, LocalDateTime)} - */ - @Test - void testUpdateDeliveryAt6() { - // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - Optional emptyResult = Optional.empty(); - when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(emptyResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); // Act and Assert assertThrows(IllegalArgumentException.class, - () -> votePersistenceAdapter.updateDeliveryAt(1L, LocalDate.of(1970, 1, 1).atStartOfDay())); + () -> votePersistenceAdapter.updateDeliveryAt(1L, Constants.LOCAL_DATE_TIME_MIN)); verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); + verify(votePaperJpaEntity).toBuilder(); } /** @@ -1148,41 +519,18 @@ void testUpdateDeliveryAt6() { @Test void testUpdateVideoUrl() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.save(Mockito.any())).thenReturn(new VotePaperJpaEntity()); Optional ofResult = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act - RegisteredVotePaper actualUpdateVideoUrlResult = (new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl())).updateVideoUrl(1L, "https://example.org/example"); + Mockito.>when(votePaperMapper.updateVideoUrl( + any(), any())) + .thenThrow(new IllegalArgumentException("foo")); - // Assert + // Act and Assert + assertThrows(IllegalArgumentException.class, + () -> votePersistenceAdapter.updateVideoUrl(1L, "https://example.org/example")); verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); - verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); - assertNull(actualUpdateVideoUrlResult.option()); - assertNull(actualUpdateVideoUrlResult.id()); - assertNull(actualUpdateVideoUrlResult.author()); - assertNull(actualUpdateVideoUrlResult.authorUsername()); - assertNull(actualUpdateVideoUrlResult.content()); - assertNull(actualUpdateVideoUrlResult.title()); - assertNull(actualUpdateVideoUrlResult.uuid()); - assertNull(actualUpdateVideoUrlResult.videoUrl()); - assertNull(actualUpdateVideoUrlResult.createdAt()); - assertNull(actualUpdateVideoUrlResult.deliveryAt()); - assertNull(actualUpdateVideoUrlResult.updatedAt()); - assertNull(actualUpdateVideoUrlResult.voteEndAt()); - assertNull(actualUpdateVideoUrlResult.voteStartAt()); + verify(votePaperMapper).updateVideoUrl(eq("https://example.org/example"), + isA(VotePaperJpaEntity.VotePaperJpaEntityBuilder.class)); } /** @@ -1192,27 +540,13 @@ void testUpdateVideoUrl() { @Test void testUpdateVideoUrl2() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.save(Mockito.any())).thenThrow(new IllegalArgumentException("foo")); - Optional ofResult = Optional.of(new VotePaperJpaEntity()); - when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + Optional emptyResult = Optional.empty(); + when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(emptyResult); // Act and Assert assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .updateVideoUrl(1L, "https://example.org/example")); + () -> votePersistenceAdapter.updateVideoUrl(1L, "https://example.org/example")); verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); - verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); } /** @@ -1222,143 +556,17 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testUpdateVideoUrl3() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.save(Mockito.any())).thenReturn(null); - Optional ofResult = Optional.of(new VotePaperJpaEntity()); - when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act - RegisteredVotePaper actualUpdateVideoUrlResult = (new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl())).updateVideoUrl(1L, "https://example.org/example"); - - // Assert - verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); - verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); - assertNull(actualUpdateVideoUrlResult); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#updateVideoUrl(Long, String)} - */ - @Test - void testUpdateVideoUrl4() { - // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - AccountJpaEntity author = new AccountJpaEntity(); - LocalDateTime voteStartAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - LocalDateTime voteEndAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - LocalDateTime deliveryAt = LocalDate.of(1970, 1, 1).atStartOfDay(); - ArrayList choices = new ArrayList<>(); - when(votePaperRepository.save(Mockito.any())) - .thenReturn(new VotePaperJpaEntity(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", "Dr", - "Not all who wander are lost", "Page Link", author, VotePaperOption.ALLOW_ADD_CHOICES, voteStartAt, - voteEndAt, deliveryAt, true, "https://example.org/example", choices, new ArrayList<>())); - Optional ofResult = Optional.of(new VotePaperJpaEntity()); - when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act - RegisteredVotePaper actualUpdateVideoUrlResult = (new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl())).updateVideoUrl(1L, "https://example.org/example"); - - // Assert - verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); - verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); - LocalTime expectedToLocalTimeResult = actualUpdateVideoUrlResult.voteStartAt().toLocalTime(); - assertSame(expectedToLocalTimeResult, actualUpdateVideoUrlResult.voteEndAt().toLocalTime()); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#updateVideoUrl(Long, String)} - */ - @Test - void testUpdateVideoUrl5() { - // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - when(votePaperRepository.save(Mockito.any())).thenReturn(new VotePaperJpaEntity()); - Optional ofResult = Optional - .of(new VotePaperJpaEntity(mock(VotePaperJpaEntity.VotePaperJpaEntityBuilder.class))); + VotePaperJpaEntity votePaperJpaEntity = mock(VotePaperJpaEntity.class); + Mockito.>when(votePaperJpaEntity.toBuilder()) + .thenThrow(new IllegalArgumentException("foo")); + Optional ofResult = Optional.of(votePaperJpaEntity); when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act - RegisteredVotePaper actualUpdateVideoUrlResult = (new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl())).updateVideoUrl(1L, "https://example.org/example"); - - // Assert - verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); - verify(votePaperRepository).save(isA(VotePaperJpaEntity.class)); - assertNull(actualUpdateVideoUrlResult.option()); - assertNull(actualUpdateVideoUrlResult.id()); - assertNull(actualUpdateVideoUrlResult.author()); - assertNull(actualUpdateVideoUrlResult.authorUsername()); - assertNull(actualUpdateVideoUrlResult.content()); - assertNull(actualUpdateVideoUrlResult.title()); - assertNull(actualUpdateVideoUrlResult.uuid()); - assertNull(actualUpdateVideoUrlResult.videoUrl()); - assertNull(actualUpdateVideoUrlResult.createdAt()); - assertNull(actualUpdateVideoUrlResult.deliveryAt()); - assertNull(actualUpdateVideoUrlResult.updatedAt()); - assertNull(actualUpdateVideoUrlResult.voteEndAt()); - assertNull(actualUpdateVideoUrlResult.voteStartAt()); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#updateVideoUrl(Long, String)} - */ - @Test - void testUpdateVideoUrl6() { - // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - Optional emptyResult = Optional.empty(); - when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(emptyResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .updateVideoUrl(1L, "https://example.org/example")); + () -> votePersistenceAdapter.updateVideoUrl(1L, "https://example.org/example")); verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); + verify(votePaperJpaEntity).toBuilder(); } /** @@ -1368,26 +576,20 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testLoadRegisteredVoteChoice() { // Arrange - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); when(voteChoiceRepository.findAllByVotePaperId(Mockito.any())).thenReturn(new ArrayList<>()); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + ArrayList registeredVoteChoiceList = new ArrayList<>(); + when(voteChoiceMapper.registeredVoteChoices(Mockito.any())) + .thenReturn(registeredVoteChoiceList); // Act - List actualLoadRegisteredVoteChoiceResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVoteChoice(1L); + List actualLoadRegisteredVoteChoiceResult = votePersistenceAdapter + .loadRegisteredVoteChoice(1L); // Assert + verify(voteChoiceMapper).registeredVoteChoices(isA(List.class)); verify(voteChoiceRepository).findAllByVotePaperId(eq(1L)); assertTrue(actualLoadRegisteredVoteChoiceResult.isEmpty()); + assertSame(registeredVoteChoiceList, actualLoadRegisteredVoteChoiceResult); } /** @@ -1397,148 +599,16 @@ void testLoadRegisteredVoteChoice() { @Test void testLoadRegisteredVoteChoice2() { // Arrange - ArrayList voteChoiceJpaEntityList = new ArrayList<>(); - voteChoiceJpaEntityList.add(new VoteChoiceJpaEntity()); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - when(voteChoiceRepository.findAllByVotePaperId(Mockito.any())).thenReturn(voteChoiceJpaEntityList); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act - List actualLoadRegisteredVoteChoiceResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVoteChoice(1L); - - // Assert - verify(voteChoiceRepository).findAllByVotePaperId(eq(1L)); - assertEquals(1, actualLoadRegisteredVoteChoiceResult.size()); - RegisteredVoteChoice getResult = actualLoadRegisteredVoteChoiceResult.get(0); - assertNull(getResult.id()); - assertNull(getResult.votePaperId()); - assertNull(getResult.artistName()); - assertNull(getResult.music()); - assertNull(getResult.offerId()); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#loadRegisteredVoteChoice(Long)} - */ - @Test - void testLoadRegisteredVoteChoice3() { - // Arrange - ArrayList voteChoiceJpaEntityList = new ArrayList<>(); - voteChoiceJpaEntityList.add(new VoteChoiceJpaEntity()); - voteChoiceJpaEntityList.add(new VoteChoiceJpaEntity()); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - when(voteChoiceRepository.findAllByVotePaperId(Mockito.any())).thenReturn(voteChoiceJpaEntityList); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act - List actualLoadRegisteredVoteChoiceResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVoteChoice(1L); - - // Assert - verify(voteChoiceRepository).findAllByVotePaperId(eq(1L)); - assertEquals(2, actualLoadRegisteredVoteChoiceResult.size()); - RegisteredVoteChoice getResult = actualLoadRegisteredVoteChoiceResult.get(0); - assertNull(getResult.id()); - RegisteredVoteChoice getResult2 = actualLoadRegisteredVoteChoiceResult.get(1); - assertNull(getResult2.id()); - assertNull(getResult.votePaperId()); - assertNull(getResult2.votePaperId()); - assertNull(getResult.artistName()); - assertNull(getResult2.artistName()); - assertNull(getResult.music()); - assertNull(getResult2.music()); - assertNull(getResult.offerId()); - assertNull(getResult2.offerId()); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#loadRegisteredVoteChoice(Long)} - */ - @Test - void testLoadRegisteredVoteChoice4() { - // Arrange - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - when(voteChoiceRepository.findAllByVotePaperId(Mockito.any())).thenThrow(new IllegalArgumentException("foo")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + when(voteChoiceRepository.findAllByVotePaperId(Mockito.any())).thenReturn(new ArrayList<>()); + when(voteChoiceMapper.registeredVoteChoices(Mockito.any())) + .thenThrow(new IllegalArgumentException("foo")); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .loadRegisteredVoteChoice(1L)); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.loadRegisteredVoteChoice(1L)); + verify(voteChoiceMapper).registeredVoteChoices(isA(List.class)); verify(voteChoiceRepository).findAllByVotePaperId(eq(1L)); } - /** - * Method under test: - * {@link VotePersistenceAdapter#loadRegisteredVoteChoice(Long)} - */ - @Test - void testLoadRegisteredVoteChoice5() { - // Arrange - ArrayList voteChoiceJpaEntityList = new ArrayList<>(); - VotePaperJpaEntity votePaper = new VotePaperJpaEntity(); - Offer offer = new Offer("42", "Music", "Artist Name"); - - voteChoiceJpaEntityList.add(new VoteChoiceJpaEntity(1L, "01234567-89AB-CDEF-FEDC-BA9876543210", votePaper, offer, - new ArrayList<>(), "Jan 1, 2020 8:00am GMT+0100")); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - when(voteChoiceRepository.findAllByVotePaperId(Mockito.any())).thenReturn(voteChoiceJpaEntityList); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act - List actualLoadRegisteredVoteChoiceResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).loadRegisteredVoteChoice(1L); - - // Assert - verify(voteChoiceRepository).findAllByVotePaperId(eq(1L)); - assertEquals(1, actualLoadRegisteredVoteChoiceResult.size()); - RegisteredVoteChoice getResult = actualLoadRegisteredVoteChoiceResult.get(0); - assertEquals("42", getResult.offerId()); - assertEquals("Artist Name", getResult.artistName()); - assertEquals("Music", getResult.music()); - assertNull(getResult.votePaperId()); - assertEquals(1L, getResult.id().longValue()); - } - /** * Method under test: * {@link VotePersistenceAdapter#loadVoteChoiceByUsername(Long, String)} @@ -1546,132 +616,17 @@ void testLoadRegisteredVoteChoice5() { @Test void testLoadVoteChoiceByUsername() { // Arrange - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); Optional ofResult = Optional.of(new VoteChoiceJpaEntity()); when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) .thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + when(voteChoiceMapper.registeredVoteChoice(Mockito.any())) + .thenReturn(new RegisteredVoteChoice(1L, 1L, "42", "Music", "Artist Name")); // Act - Optional actualLoadVoteChoiceByUsernameResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).loadVoteChoiceByUsername(1L, "janedoe"); + votePersistenceAdapter.loadVoteChoiceByUsername(1L, "janedoe"); // Assert - verify(voteChoiceRepository).findByVotePaperIdAndCreatedBy(eq(1L), eq("janedoe")); - RegisteredVoteChoice getResult = actualLoadVoteChoiceByUsernameResult.get(); - assertNull(getResult.id()); - assertNull(getResult.votePaperId()); - assertNull(getResult.artistName()); - assertNull(getResult.music()); - assertNull(getResult.offerId()); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#loadVoteChoiceByUsername(Long, String)} - */ - @Test - void testLoadVoteChoiceByUsername2() { - // Arrange - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperJpaEntity votePaper = new VotePaperJpaEntity(); - Offer offer = new Offer("42", "Music", "Artist Name"); - - Optional ofResult = Optional.of(new VoteChoiceJpaEntity(1L, - "01234567-89AB-CDEF-FEDC-BA9876543210", votePaper, offer, new ArrayList<>(), "Jan 1, 2020 8:00am GMT+0100")); - when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) - .thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act - Optional actualLoadVoteChoiceByUsernameResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).loadVoteChoiceByUsername(1L, "janedoe"); - - // Assert - verify(voteChoiceRepository).findByVotePaperIdAndCreatedBy(eq(1L), eq("janedoe")); - RegisteredVoteChoice getResult = actualLoadVoteChoiceByUsernameResult.get(); - assertEquals("42", getResult.offerId()); - assertEquals("Artist Name", getResult.artistName()); - assertEquals("Music", getResult.music()); - assertNull(getResult.votePaperId()); - assertEquals(1L, getResult.id().longValue()); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#loadVoteChoiceByUsername(Long, String)} - */ - @Test - void testLoadVoteChoiceByUsername3() { - // Arrange - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - Optional emptyResult = Optional.empty(); - when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) - .thenReturn(emptyResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act - Optional actualLoadVoteChoiceByUsernameResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).loadVoteChoiceByUsername(1L, "janedoe"); - - // Assert - verify(voteChoiceRepository).findByVotePaperIdAndCreatedBy(eq(1L), eq("janedoe")); - assertFalse(actualLoadVoteChoiceByUsernameResult.isPresent()); - assertSame(emptyResult, actualLoadVoteChoiceByUsernameResult); - } - - /** - * Method under test: - * {@link VotePersistenceAdapter#loadVoteChoiceByUsername(Long, String)} - */ - @Test - void testLoadVoteChoiceByUsername4() { - // Arrange - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) - .thenThrow(new IllegalArgumentException("foo")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - - // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .loadVoteChoiceByUsername(1L, "janedoe")); + verify(voteChoiceMapper).registeredVoteChoice(isA(VoteChoiceJpaEntity.class)); verify(voteChoiceRepository).findByVotePaperIdAndCreatedBy(eq(1L), eq("janedoe")); } @@ -1681,27 +636,16 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testSaveVoteChoice() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional ofResult = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); when(voteChoiceRepository.saveAll(Mockito.any())).thenReturn(new ArrayList<>()); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); + when(voteChoiceMapper.fromSaveVoteChoiceBehaviors(Mockito.any())).thenReturn(new HashSet<>()); // Act votePersistenceAdapter.saveVoteChoice(1L, new HashSet<>()); // Assert + verify(voteChoiceMapper).fromSaveVoteChoiceBehaviors(isA(Set.class)); verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); verify(voteChoiceRepository).saveAll(isA(Iterable.class)); } @@ -1712,28 +656,15 @@ void testSaveVoteChoice() { @Test void testSaveVoteChoice2() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional ofResult = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - when(voteChoiceRepository.saveAll(Mockito.any())) + when(voteChoiceMapper.fromSaveVoteChoiceBehaviors(Mockito.any())) .thenThrow(new IllegalArgumentException("foo")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); // Act and Assert assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.saveVoteChoice(1L, new HashSet<>())); + verify(voteChoiceMapper).fromSaveVoteChoiceBehaviors(isA(Set.class)); verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); - verify(voteChoiceRepository).saveAll(isA(Iterable.class)); } /** @@ -1742,61 +673,14 @@ void testSaveVoteChoice2() { @Test void testSaveVoteChoice3() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional emptyResult = Optional.empty(); when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(emptyResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); // Act and Assert assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.saveVoteChoice(1L, new HashSet<>())); verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); } - /** - * Method under test: {@link VotePersistenceAdapter#saveVoteChoice(Long, Set)} - */ - @Test - void testSaveVoteChoice4() { - // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - Optional ofResult = Optional.of(new VotePaperJpaEntity()); - when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - when(voteChoiceRepository.saveAll(Mockito.any())).thenReturn(new ArrayList<>()); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); - VotePersistenceAdapter votePersistenceAdapter = new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl()); - - HashSet behavior = new HashSet<>(); - behavior.add(new SaveVoteChoice("42", "Music", "Artist Name")); - - // Act - votePersistenceAdapter.saveVoteChoice(1L, behavior); - - // Assert - verify(votePaperRepository).findOneAvailable(eq(1L), isNull()); - verify(voteChoiceRepository).saveAll(isA(Iterable.class)); - } - /** * Method under test: * {@link VotePersistenceAdapter#saveVotePaperLike(Long, String)} @@ -1804,29 +688,17 @@ void testSaveVoteChoice4() { @Test void testSaveVotePaperLike() { // Arrange - AccountRepository accountRepository = mock(AccountRepository.class); Optional ofResult = Optional.of(new AccountJpaEntity()); - when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(ofResult); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + when(accountPersistenceAdapter.loadAccountByUsername(Mockito.any())).thenReturn(ofResult); Optional ofResult2 = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findById(Mockito.any())).thenReturn(ofResult2); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); when(votePaperLikeRepository.save(Mockito.any())).thenReturn(new VotePaperLikeJpaEntity()); - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act - (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, - votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).saveVotePaperLike(1L, "janedoe"); + votePersistenceAdapter.saveVotePaperLike(1L, "janedoe"); // Assert - verify(accountRepository).findActive(eq("janedoe"), isNull(), isNull()); + verify(accountPersistenceAdapter).loadAccountByUsername(eq("janedoe")); verify(votePaperRepository).findById(eq(1L)); verify(votePaperLikeRepository).save(isA(VotePaperLikeJpaEntity.class)); } @@ -1838,30 +710,16 @@ void testSaveVotePaperLike() { @Test void testSaveVotePaperLike2() { // Arrange - AccountRepository accountRepository = mock(AccountRepository.class); Optional ofResult = Optional.of(new AccountJpaEntity()); - when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(ofResult); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + when(accountPersistenceAdapter.loadAccountByUsername(Mockito.any())).thenReturn(ofResult); Optional ofResult2 = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findById(Mockito.any())).thenReturn(ofResult2); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); when(votePaperLikeRepository.save(Mockito.any())) .thenThrow(new IllegalArgumentException("foo")); - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .saveVotePaperLike(1L, "janedoe")); - verify(accountRepository).findActive(eq("janedoe"), isNull(), isNull()); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.saveVotePaperLike(1L, "janedoe")); + verify(accountPersistenceAdapter).loadAccountByUsername(eq("janedoe")); verify(votePaperRepository).findById(eq(1L)); verify(votePaperLikeRepository).save(isA(VotePaperLikeJpaEntity.class)); } @@ -1873,26 +731,12 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testSaveVotePaperLike3() { // Arrange - AccountRepository accountRepository = mock(AccountRepository.class); Optional emptyResult = Optional.empty(); - when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(emptyResult); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); + when(accountPersistenceAdapter.loadAccountByUsername(Mockito.any())).thenReturn(emptyResult); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .saveVotePaperLike(1L, "janedoe")); - verify(accountRepository).findActive(eq("janedoe"), isNull(), isNull()); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.saveVotePaperLike(1L, "janedoe")); + verify(accountPersistenceAdapter).loadAccountByUsername(eq("janedoe")); } /** @@ -1902,28 +746,14 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testSaveVotePaperLike4() { // Arrange - AccountRepository accountRepository = mock(AccountRepository.class); Optional ofResult = Optional.of(new AccountJpaEntity()); - when(accountRepository.findActive(Mockito.any(), Mockito.any(), Mockito.any())) - .thenReturn(ofResult); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); + when(accountPersistenceAdapter.loadAccountByUsername(Mockito.any())).thenReturn(ofResult); Optional emptyResult = Optional.empty(); when(votePaperRepository.findById(Mockito.any())).thenReturn(emptyResult); - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .saveVotePaperLike(1L, "janedoe")); - verify(accountRepository).findActive(eq("janedoe"), isNull(), isNull()); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.saveVotePaperLike(1L, "janedoe")); + verify(accountPersistenceAdapter).loadAccountByUsername(eq("janedoe")); verify(votePaperRepository).findById(eq(1L)); } @@ -1933,23 +763,12 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testDeleteVotePaperLike() { // Arrange - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); doNothing().when(votePaperLikeRepository).deleteById(Mockito.any()); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act - (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, - votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())).deleteVotePaperLike(1L); + votePersistenceAdapter.deleteVotePaperLike(1L); - // Assert + // Assert that nothing has changed verify(votePaperLikeRepository).deleteById(eq(1L)); } @@ -1959,26 +778,72 @@ void testDeleteVotePaperLike() { @Test void testDeleteVotePaperLike2() { // Arrange - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); doThrow(new IllegalArgumentException("foo")).when(votePaperLikeRepository).deleteById(Mockito.any()); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .deleteVotePaperLike(1L)); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.deleteVotePaperLike(1L)); verify(votePaperLikeRepository).deleteById(eq(1L)); } + /** + * Method under test: {@link VotePersistenceAdapter#initializeStatistics(Long)} + */ + @Test + void testInitializeStatistics() { + // Arrange + when(votePaperStatisticsRepository.save(Mockito.any())) + .thenReturn(new VotePaperStatisticsJpaEntity()); + + // Act + votePersistenceAdapter.initializeStatistics(1L); + + // Assert + verify(votePaperStatisticsRepository).save(isA(VotePaperStatisticsJpaEntity.class)); + } + + /** + * Method under test: {@link VotePersistenceAdapter#initializeStatistics(Long)} + */ + @Test + void testInitializeStatistics2() { + // Arrange + when(votePaperStatisticsRepository.save(Mockito.any())) + .thenThrow(new IllegalArgumentException("foo")); + + // Act and Assert + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.initializeStatistics(1L)); + verify(votePaperStatisticsRepository).save(isA(VotePaperStatisticsJpaEntity.class)); + } + + /** + * Method under test: {@link VotePersistenceAdapter#updateLikeCount(Long, Long)} + */ + @Test + void testUpdateLikeCount() { + // Arrange + doNothing().when(votePaperStatisticsRepository).updateLikeCount(Mockito.any(), Mockito.any()); + + // Act + votePersistenceAdapter.updateLikeCount(1L, 3L); + + // Assert that nothing has changed + verify(votePaperStatisticsRepository).updateLikeCount(eq(1L), eq(3L)); + } + + /** + * Method under test: {@link VotePersistenceAdapter#updateLikeCount(Long, Long)} + */ + @Test + void testUpdateLikeCount2() { + // Arrange + doThrow(new IllegalArgumentException("foo")).when(votePaperStatisticsRepository) + .updateLikeCount(Mockito.any(), Mockito.any()); + + // Act and Assert + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.updateLikeCount(1L, 3L)); + verify(votePaperStatisticsRepository).updateLikeCount(eq(1L), eq(3L)); + } + /** * Method under test: * {@link VotePersistenceAdapter#findOneAvailable(Long, String)} @@ -1986,23 +851,11 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testFindOneAvailable() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional ofResult = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act - Optional actualFindOneAvailableResult = (new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl())).findOneAvailable(1L, "janedoe"); + Optional actualFindOneAvailableResult = votePersistenceAdapter.findOneAvailable(1L, "janedoe"); // Assert verify(votePaperRepository).findOneAvailable(eq(1L), eq("janedoe")); @@ -2016,24 +869,11 @@ void testFindOneAvailable() { @Test void testFindOneAvailable2() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); when(votePaperRepository.findOneAvailable(Mockito.any(), Mockito.any())) .thenThrow(new IllegalArgumentException("foo")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .findOneAvailable(1L, "janedoe")); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.findOneAvailable(1L, "janedoe")); verify(votePaperRepository).findOneAvailable(eq(1L), eq("janedoe")); } @@ -2044,25 +884,14 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testFindCompleteVotePaperById() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional ofResult = Optional.of(new VotePaperJpaEntity()); when( votePaperRepository.findByVoteEndAtBeforeAndIdAndEnabledTrue(Mockito.any(), Mockito.any())) .thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act - Optional actualFindCompleteVotePaperByIdResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).findCompleteVotePaperById(1L); + Optional actualFindCompleteVotePaperByIdResult = votePersistenceAdapter + .findCompleteVotePaperById(1L); // Assert verify(votePaperRepository).findByVoteEndAtBeforeAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); @@ -2076,25 +905,12 @@ void testFindCompleteVotePaperById() { @Test void testFindCompleteVotePaperById2() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); when( votePaperRepository.findByVoteEndAtBeforeAndIdAndEnabledTrue(Mockito.any(), Mockito.any())) .thenThrow(new IllegalArgumentException("foo")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .findCompleteVotePaperById(1L)); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.findCompleteVotePaperById(1L)); verify(votePaperRepository).findByVoteEndAtBeforeAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); } @@ -2105,24 +921,13 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testFindProgressingVotePaperByAuthor() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional ofResult = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), Mockito.any())).thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act - Optional actualFindProgressingVotePaperByAuthorResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).findProgressingVotePaperByAuthor("janedoe"); + Optional actualFindProgressingVotePaperByAuthorResult = votePersistenceAdapter + .findProgressingVotePaperByAuthor("janedoe"); // Assert verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), @@ -2137,24 +942,12 @@ void testFindProgressingVotePaperByAuthor() { @Test void testFindProgressingVotePaperByAuthor2() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); when(votePaperRepository.findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(Mockito.any(), Mockito.any())).thenThrow(new IllegalArgumentException("foo")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .findProgressingVotePaperByAuthor("janedoe")); + () -> votePersistenceAdapter.findProgressingVotePaperByAuthor("janedoe")); verify(votePaperRepository).findByVoteEndAtAfterAndAuthorUsernameAndEnabledTrue(isA(LocalDateTime.class), eq("janedoe")); } @@ -2166,24 +959,13 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testFindProgressingVotePaperById() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); Optional ofResult = Optional.of(new VotePaperJpaEntity()); when(votePaperRepository.findByVoteEndAtAfterAndIdAndEnabledTrue(Mockito.any(), Mockito.any())) .thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act - Optional actualFindProgressingVotePaperByIdResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).findProgressingVotePaperById(1L); + Optional actualFindProgressingVotePaperByIdResult = votePersistenceAdapter + .findProgressingVotePaperById(1L); // Assert verify(votePaperRepository).findByVoteEndAtAfterAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); @@ -2197,24 +979,11 @@ void testFindProgressingVotePaperById() { @Test void testFindProgressingVotePaperById2() { // Arrange - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); when(votePaperRepository.findByVoteEndAtAfterAndIdAndEnabledTrue(Mockito.any(), Mockito.any())) .thenThrow(new IllegalArgumentException("foo")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .findProgressingVotePaperById(1L)); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.findProgressingVotePaperById(1L)); verify(votePaperRepository).findByVoteEndAtAfterAndIdAndEnabledTrue(isA(LocalDateTime.class), eq(1L)); } @@ -2224,23 +993,11 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testFindAllByVotePaperId() { // Arrange - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); ArrayList voteChoiceJpaEntityList = new ArrayList<>(); when(voteChoiceRepository.findAllByVotePaperId(Mockito.any())).thenReturn(voteChoiceJpaEntityList); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act - List actualFindAllByVotePaperIdResult = (new VotePersistenceAdapter(accountPersistenceAdapter, - voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, votePaperMapper, - new VoteChoiceMapperImpl())).findAllByVotePaperId(1L); + List actualFindAllByVotePaperIdResult = votePersistenceAdapter.findAllByVotePaperId(1L); // Assert verify(voteChoiceRepository).findAllByVotePaperId(eq(1L)); @@ -2254,23 +1011,10 @@ void testFindAllByVotePaperId() { @Test void testFindAllByVotePaperId2() { // Arrange - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); when(voteChoiceRepository.findAllByVotePaperId(Mockito.any())).thenThrow(new IllegalArgumentException("foo")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert - assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .findAllByVotePaperId(1L)); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.findAllByVotePaperId(1L)); verify(voteChoiceRepository).findAllByVotePaperId(eq(1L)); } @@ -2281,24 +1025,13 @@ voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMa @Test void testFindByVotePaperIdAndUsername() { // Arrange - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); Optional ofResult = Optional.of(new VoteChoiceJpaEntity()); when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) .thenReturn(ofResult); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act - Optional actualFindByVotePaperIdAndUsernameResult = (new VotePersistenceAdapter( - accountPersistenceAdapter, voteRepository, votePaperRepository, voteChoiceRepository, votePaperLikeRepository, - votePaperMapper, new VoteChoiceMapperImpl())).findByVotePaperIdAndUsername(1L, "janedoe"); + Optional actualFindByVotePaperIdAndUsernameResult = votePersistenceAdapter + .findByVotePaperIdAndUsername(1L, "janedoe"); // Assert verify(voteChoiceRepository).findByVotePaperIdAndCreatedBy(eq(1L), eq("janedoe")); @@ -2312,24 +1045,12 @@ void testFindByVotePaperIdAndUsername() { @Test void testFindByVotePaperIdAndUsername2() { // Arrange - VoteChoiceRepository voteChoiceRepository = mock(VoteChoiceRepository.class); when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) .thenThrow(new IllegalArgumentException("foo")); - AccountRepository accountRepository = mock(AccountRepository.class); - OAuth2AccountRepository oauth2AccountRepository = mock(OAuth2AccountRepository.class); - AccountPersistenceAdapter accountPersistenceAdapter = new AccountPersistenceAdapter(accountRepository, - oauth2AccountRepository, new AccountMapperImpl()); - - VoteRepository voteRepository = mock(VoteRepository.class); - VotePaperRepository votePaperRepository = mock(VotePaperRepository.class); - VotePaperLikeRepository votePaperLikeRepository = mock(VotePaperLikeRepository.class); - VotePaperMapperImpl votePaperMapper = new VotePaperMapperImpl(); // Act and Assert assertThrows(IllegalArgumentException.class, - () -> (new VotePersistenceAdapter(accountPersistenceAdapter, voteRepository, votePaperRepository, - voteChoiceRepository, votePaperLikeRepository, votePaperMapper, new VoteChoiceMapperImpl())) - .findByVotePaperIdAndUsername(1L, "janedoe")); + () -> votePersistenceAdapter.findByVotePaperIdAndUsername(1L, "janedoe")); verify(voteChoiceRepository).findByVotePaperIdAndCreatedBy(eq(1L), eq("janedoe")); } } From 3549a129cf6e3a78bfb7cedd19d21fea869ff635 Mon Sep 17 00:00:00 2001 From: habin Date: Thu, 23 May 2024 15:04:34 +0900 Subject: [PATCH 08/16] feat(interaction) like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit chore: logging 추가 --- .../input/scheduler/LikeCountAggregationScheduler.java | 3 +++ .../application/service/UpdateVotePaperStatisticsService.java | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java b/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java index b57f7b2e..01300834 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java @@ -2,9 +2,11 @@ import com.tune_fun.v1.interaction.application.port.input.usecase.UpdateVotePaperStatisticsUseCase; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; +@Slf4j @Component @RequiredArgsConstructor public class LikeCountAggregationScheduler { @@ -13,6 +15,7 @@ public class LikeCountAggregationScheduler { @Scheduled(fixedDelay = 1000L * 5L) public void aggregateLikeCount() { + log.info("Start to aggregate Vote Paper like count"); updateVotePaperStatisticsUseCase.updateVotePaperStatistics(); } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java index 171d0322..b4bb114b 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java @@ -5,10 +5,12 @@ import com.tune_fun.v1.interaction.application.port.output.LoadVotePaperLikeCountPort; import com.tune_fun.v1.vote.application.port.output.SaveVotePaperStatisticsPort; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.Set; +@Slf4j @Service @UseCase @RequiredArgsConstructor @@ -21,11 +23,13 @@ public class UpdateVotePaperStatisticsService implements UpdateVotePaperStatisti @Override public void updateVotePaperStatistics() { Set keys = loadVotePaperLikeCountPort.getVotePaperLikeCountKeys(); + log.info("Update vote paper statistics for vote paper like count keys: {}", keys); keys.forEach(key -> { Long likeCount = loadVotePaperLikeCountPort.getVotePaperLikeCount(key); Long votePaperId = loadVotePaperLikeCountPort.getVotePaperId(key); saveVotePaperStatPort.updateLikeCount(votePaperId, likeCount); + log.info("Update vote paper statistics for vote paper id: {} with like count: {}", votePaperId, likeCount); }); } } From 016c1fe2ddede1dcf6625c3c3b42c050adbe9843 Mon Sep 17 00:00:00 2001 From: habin Date: Thu, 23 May 2024 15:09:17 +0900 Subject: [PATCH 09/16] feat(interaction) like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: 좋아요 데이터 미존재시 생성 로직 추가 --- .../persistence/LikeCountPersistenceAdapter.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java index bc639f6c..1636b9a6 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java @@ -6,6 +6,7 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; +import java.util.Optional; import java.util.Set; @Component @@ -30,7 +31,10 @@ public Long getVotePaperLikeCount(String key) { @Override public void incrementVotePaperLikeCount(final Long votePaperId) { - redisTemplate.opsForHash().increment(getKey(votePaperId), LIKE_COUNT_HASH_KEY, 1); + getVotePaperLikeCount(votePaperId).ifPresentOrElse( + likeCount -> redisTemplate.opsForHash().increment(getKey(votePaperId), LIKE_COUNT_HASH_KEY, 1), + () -> redisTemplate.opsForHash().put(getKey(votePaperId), LIKE_COUNT_HASH_KEY, 1) + ); } @Override @@ -48,4 +52,8 @@ public Long getVotePaperId(final String key) { return Long.parseLong(key.split("::")[1]); } + public Optional getVotePaperLikeCount(final Long votePaperId) { + return Optional.ofNullable(redisTemplate.opsForHash().get(getKey(votePaperId), LIKE_COUNT_HASH_KEY)); + } + } From 3216e90b6d752aa8a2efb0c410b4ce0370136e2a Mon Sep 17 00:00:00 2001 From: habin Date: Thu, 23 May 2024 16:13:27 +0900 Subject: [PATCH 10/16] feat(interaction) like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test: 투표 게시물 좋아요 추가 API 통합 테스트 추가 --- .../v1/common/constant/Constants.java | 2 + .../LikeCountPersistenceAdapter.java | 13 ++- .../output/LoadVotePaperLikeCountPort.java | 3 + ...tePaperStatisticsCustomRepositoryImpl.java | 2 + .../VotePaperStatisticsJpaEntity.java | 2 + .../VotePaperStatisticsRepository.java | 3 + .../persistence/VotePersistenceAdapter.java | 9 +- .../output/LoadVotePaperStatisticsPort.java | 5 + .../com/tune_fun/v1/dummy/DummyService.java | 5 +- .../input/rest/LikeControllerTest.java | 109 ++++++++++++++++++ 10 files changed, 146 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/tune_fun/v1/vote/application/port/output/LoadVotePaperStatisticsPort.java create mode 100644 src/test/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeControllerTest.java diff --git a/src/main/java/com/tune_fun/v1/common/constant/Constants.java b/src/main/java/com/tune_fun/v1/common/constant/Constants.java index b1e9ef33..ee92383e 100644 --- a/src/main/java/com/tune_fun/v1/common/constant/Constants.java +++ b/src/main/java/com/tune_fun/v1/common/constant/Constants.java @@ -22,6 +22,8 @@ public final class Constants { public static final String COLON = ":"; + public static final String DOUBLE_COLON = "::"; + public static final String SEMICOLON = ";"; public static final String DOT = "."; diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java index 1636b9a6..ae21ac78 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java @@ -9,6 +9,8 @@ import java.util.Optional; import java.util.Set; +import static com.tune_fun.v1.common.constant.Constants.DOUBLE_COLON; + @Component @RequiredArgsConstructor public class LikeCountPersistenceAdapter implements SaveVotePaperLikeCountPort, LoadVotePaperLikeCountPort { @@ -26,12 +28,12 @@ public Set getVotePaperLikeCountKeys() { @Override public Long getVotePaperLikeCount(String key) { - return (Long) redisTemplate.opsForHash().get(key, LIKE_COUNT_HASH_KEY); + return Long.valueOf(String.valueOf(redisTemplate.opsForHash().get(key, LIKE_COUNT_HASH_KEY))); } @Override public void incrementVotePaperLikeCount(final Long votePaperId) { - getVotePaperLikeCount(votePaperId).ifPresentOrElse( + getVotePaperLikeCountById(votePaperId).ifPresentOrElse( likeCount -> redisTemplate.opsForHash().increment(getKey(votePaperId), LIKE_COUNT_HASH_KEY, 1), () -> redisTemplate.opsForHash().put(getKey(votePaperId), LIKE_COUNT_HASH_KEY, 1) ); @@ -44,15 +46,16 @@ public void decrementVotePaperLikeCount(final Long votePaperId) { @Override public String getKey(final Long votePaperId) { - return VOTE_PAPER_LIKE_COUNT_KEY + "::" + votePaperId; + return VOTE_PAPER_LIKE_COUNT_KEY + DOUBLE_COLON + votePaperId; } @Override public Long getVotePaperId(final String key) { - return Long.parseLong(key.split("::")[1]); + return Long.parseLong(key.split(DOUBLE_COLON)[1]); } - public Optional getVotePaperLikeCount(final Long votePaperId) { + @Override + public Optional getVotePaperLikeCountById(final Long votePaperId) { return Optional.ofNullable(redisTemplate.opsForHash().get(getKey(votePaperId), LIKE_COUNT_HASH_KEY)); } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadVotePaperLikeCountPort.java b/src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadVotePaperLikeCountPort.java index 1a03fd7b..993ce084 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadVotePaperLikeCountPort.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadVotePaperLikeCountPort.java @@ -1,5 +1,6 @@ package com.tune_fun.v1.interaction.application.port.output; +import java.util.Optional; import java.util.Set; public interface LoadVotePaperLikeCountPort { @@ -11,4 +12,6 @@ public interface LoadVotePaperLikeCountPort { String getKey(Long votePaperId); Long getVotePaperId(String key); + + Optional getVotePaperLikeCountById(Long votePaperId); } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsCustomRepositoryImpl.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsCustomRepositoryImpl.java index c0593924..2acebd1d 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsCustomRepositoryImpl.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsCustomRepositoryImpl.java @@ -3,6 +3,7 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; import java.util.Map; import java.util.Set; @@ -17,6 +18,7 @@ public class VotePaperStatisticsCustomRepositoryImpl implements VotePaperStatist public static final QVotePaperStatisticsJpaEntity VOTE_PAPER_STATISTICS = QVotePaperStatisticsJpaEntity.votePaperStatisticsJpaEntity; + @Transactional @Override public void updateLikeCount(Long votePaperId, Long likeCount) { queryFactory.update(VOTE_PAPER_STATISTICS) diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsJpaEntity.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsJpaEntity.java index 5c6ef8ea..ab07aa6c 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsJpaEntity.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsJpaEntity.java @@ -43,6 +43,8 @@ public class VotePaperStatisticsJpaEntity extends BaseEntity { public VotePaperStatisticsJpaEntity(final Long votePaperId) { this.votePaperId = votePaperId; + this.likeCount = 0L; + this.voteCount = 0L; } } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsRepository.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsRepository.java index ebf6f28e..ff775d22 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsRepository.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePaperStatisticsRepository.java @@ -2,5 +2,8 @@ import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface VotePaperStatisticsRepository extends JpaRepository, VotePaperStatisticsCustomRepository { + Optional findByVotePaperId(final Long votePaperId); } \ No newline at end of file diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java index 252ed29b..1d940327 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java @@ -44,7 +44,7 @@ public class VotePersistenceAdapter implements UpdateDeliveryAtPort, UpdateVideoUrlPort, LoadVoteChoicePort, SaveVoteChoicePort, SaveLikePort, DeleteLikePort, - SaveVotePaperStatisticsPort { + SaveVotePaperStatisticsPort, LoadVotePaperStatisticsPort { private final AccountPersistenceAdapter accountPersistenceAdapter; @@ -217,6 +217,13 @@ public void updateLikeCount(final Long votePaperId, final Long likeCount) { votePaperStatisticsRepository.updateLikeCount(votePaperId, likeCount); } + @Override + public Long getLikeCount(final Long votePaperId) { + VotePaperStatisticsJpaEntity stat = votePaperStatisticsRepository.findByVotePaperId(votePaperId) + .orElseThrow(() -> new IllegalArgumentException("VotePaperStatistics not found")); + return stat.getLikeCount(); + } + public Optional findOneAvailable(final Long votePaperId, final String username) { return votePaperRepository.findOneAvailable(votePaperId, username); } diff --git a/src/main/java/com/tune_fun/v1/vote/application/port/output/LoadVotePaperStatisticsPort.java b/src/main/java/com/tune_fun/v1/vote/application/port/output/LoadVotePaperStatisticsPort.java new file mode 100644 index 00000000..abbec849 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/vote/application/port/output/LoadVotePaperStatisticsPort.java @@ -0,0 +1,5 @@ +package com.tune_fun.v1.vote.application.port.output; + +public interface LoadVotePaperStatisticsPort { + Long getLikeCount(final Long votePaperId); +} diff --git a/src/test/java/com/tune_fun/v1/dummy/DummyService.java b/src/test/java/com/tune_fun/v1/dummy/DummyService.java index e836cf2e..63d7a621 100644 --- a/src/test/java/com/tune_fun/v1/dummy/DummyService.java +++ b/src/test/java/com/tune_fun/v1/dummy/DummyService.java @@ -52,7 +52,6 @@ import static com.tune_fun.v1.common.util.StringUtil.ulid; import static com.tune_fun.v1.otp.adapter.output.persistence.OtpType.FORGOT_PASSWORD; -import static java.util.Collections.singletonList; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; @IntegrationTest @@ -236,6 +235,8 @@ public void initVotePaper() { votePersistenceAdapter.findProgressingVotePaperByAuthor(defaultArtistUsername) .ifPresent(votePaper -> defaultVotePaper = votePaper); + votePersistenceAdapter.initializeStatistics(defaultVotePaper.getId()); + defaultVoteChoices = votePersistenceAdapter.findAllByVotePaperId(defaultVotePaper.getId()); } @@ -259,6 +260,8 @@ public void initVotePaperAllowAddChoices() { votePersistenceAdapter.findProgressingVotePaperByAuthor(defaultArtistUsername) .ifPresent(votePaper -> defaultVotePaper = votePaper); + votePersistenceAdapter.initializeStatistics(defaultVotePaper.getId()); + defaultVoteChoices = votePersistenceAdapter.findAllByVotePaperId(defaultVotePaper.getId()); } diff --git a/src/test/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeControllerTest.java b/src/test/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeControllerTest.java new file mode 100644 index 00000000..09b6eab3 --- /dev/null +++ b/src/test/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeControllerTest.java @@ -0,0 +1,109 @@ +package com.tune_fun.v1.interaction.adapter.input.rest; + +import com.tune_fun.v1.base.ControllerBaseTest; +import com.tune_fun.v1.common.config.Uris; +import com.tune_fun.v1.common.response.MessageCode; +import com.tune_fun.v1.dummy.DummyService; +import com.tune_fun.v1.interaction.adapter.input.scheduler.LikeCountAggregationScheduler; +import com.tune_fun.v1.interaction.application.port.output.LoadVotePaperLikeCountPort; +import com.tune_fun.v1.vote.application.port.output.SaveVotePaperStatisticsPort; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.restdocs.request.ParameterDescriptor; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.transaction.annotation.Transactional; + +import static com.epages.restdocs.apispec.ResourceDocumentation.resource; +import static com.epages.restdocs.apispec.ResourceSnippetParameters.builder; +import static com.tune_fun.v1.base.doc.RestDocsConfig.constraint; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.springframework.http.HttpHeaders.AUTHORIZATION; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; + +@Slf4j +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) +class LikeControllerTest extends ControllerBaseTest { + + @Autowired + private DummyService dummyService; + + @Autowired + private LoadVotePaperLikeCountPort loadVotePaperLikeCountPort; + + @SpyBean + private LikeCountAggregationScheduler likeCountAggregationScheduler; + + @SpyBean + private SaveVotePaperStatisticsPort saveVotePaperStatPort; + + @Transactional + @Test + @Order(1) + @DisplayName("투표 게시물 좋아요 추가, 성공") + void likeVotePaperSuccess() throws Exception { + dummyService.initArtistAndLogin(); + dummyService.initVotePaper(); + + dummyService.initAndLogin(); + + String accessToken = dummyService.getDefaultAccessToken(); + + Long votePaperId = dummyService.getDefaultVotePaper().getId(); + + ParameterDescriptor pathParameter = parameterWithName("votePaperId").description("투표 게시물 ID").attributes(constraint("NOT NULL")); + + mockMvc.perform( + post(Uris.LIKE_VOTE_PAPER, votePaperId) + .header(AUTHORIZATION, bearerToken(accessToken)) + .contentType(APPLICATION_JSON_VALUE) + ) + .andExpectAll(baseAssertion(MessageCode.SUCCESS)) + .andDo( + restDocs.document( + requestHeaders(authorizationHeader), + pathParameters(pathParameter), + responseFields(baseResponseFields), + resource( + builder(). + description("투표 게시물 좋아요 추가"). + pathParameters(pathParameter). + responseFields(baseResponseFields) + .build() + ) + ) + ); + + assertTrue(loadVotePaperLikeCountPort.getVotePaperLikeCountById(votePaperId).isPresent()); + awaitLikeCountAggregationScheduler(); + awaitUpdateLikeCount(votePaperId); + } + + private void awaitLikeCountAggregationScheduler() { + await().atMost(7, SECONDS).untilAsserted(this::verifyInvokeAggregateLikeCount); + } + + private void verifyInvokeAggregateLikeCount() { + verify(likeCountAggregationScheduler, times(1)).aggregateLikeCount(); + } + + private void awaitUpdateLikeCount(Long votePaperId) { + await().untilAsserted(() -> verifyInvokeUpdateLikeCount(votePaperId)); + } + + private void verifyInvokeUpdateLikeCount(Long votePaperId) { + verify(saveVotePaperStatPort, times(1)).updateLikeCount(votePaperId, 1L); + } +} \ No newline at end of file From 9f479fa34ba70e6effc4435c41e30414753709d8 Mon Sep 17 00:00:00 2001 From: habin Date: Thu, 23 May 2024 16:51:18 +0900 Subject: [PATCH 11/16] feat(interaction) like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test: 투표 게시물 좋아요 취소 API 통합 테스트 추가 --- .../adapter/input/rest/LikeController.java | 9 +-- .../LikeCountPersistenceAdapter.java | 26 ++++++-- .../persistence/VotePaperLikeRepository.java | 5 ++ .../input/usecase/UnlikeVotePaperUseCase.java | 4 +- .../port/output/DeleteLikePort.java | 2 +- .../service/UnlikeVotePaperService.java | 5 +- .../persistence/VotePersistenceAdapter.java | 4 +- .../com/tune_fun/v1/dummy/DummyService.java | 10 ++++ .../input/rest/LikeControllerTest.java | 59 +++++++++++++++++-- .../VotePersistenceAdapterTest.java | 20 ++++--- 10 files changed, 115 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java b/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java index d59caed1..8f52aa6f 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeController.java @@ -31,12 +31,9 @@ public ResponseEntity> likeVotePaper(@PathVariable(name = "votePaper return responseMapper.ok(); } - @DeleteMapping(value = Uris.LIKE_ROOT + "/{votePaperId}/{likeId}") - public ResponseEntity> unlikeVotePaper( - @PathVariable(name = "votePaperId") Long votePaperId, - @PathVariable(name = "likeId") Long likeId, - @CurrentUser final User user) { - unlikeVotePaperUseCase.unlikeVotePaper(votePaperId, likeId); + @DeleteMapping(value = Uris.LIKE_VOTE_PAPER) + public ResponseEntity> unlikeVotePaper(@PathVariable(name = "votePaperId") Long votePaperId, @CurrentUser final User user) { + unlikeVotePaperUseCase.unlikeVotePaper(votePaperId, user); return responseMapper.ok(); } diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java index ae21ac78..287dc829 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java @@ -3,6 +3,7 @@ import com.tune_fun.v1.interaction.application.port.output.LoadVotePaperLikeCountPort; import com.tune_fun.v1.interaction.application.port.output.SaveVotePaperLikeCountPort; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; @@ -11,6 +12,7 @@ import static com.tune_fun.v1.common.constant.Constants.DOUBLE_COLON; +@Slf4j @Component @RequiredArgsConstructor public class LikeCountPersistenceAdapter implements SaveVotePaperLikeCountPort, LoadVotePaperLikeCountPort { @@ -28,20 +30,34 @@ public Set getVotePaperLikeCountKeys() { @Override public Long getVotePaperLikeCount(String key) { - return Long.valueOf(String.valueOf(redisTemplate.opsForHash().get(key, LIKE_COUNT_HASH_KEY))); + log.info("Get vote paper like count for key: {}", key); + String value = String.valueOf(redisTemplate.opsForValue().get(key)); + return Long.parseLong(value); } @Override public void incrementVotePaperLikeCount(final Long votePaperId) { getVotePaperLikeCountById(votePaperId).ifPresentOrElse( - likeCount -> redisTemplate.opsForHash().increment(getKey(votePaperId), LIKE_COUNT_HASH_KEY, 1), - () -> redisTemplate.opsForHash().put(getKey(votePaperId), LIKE_COUNT_HASH_KEY, 1) + likeCount -> redisTemplate.opsForValue().increment(getKey(votePaperId)), + () -> redisTemplate.opsForValue().set(getKey(votePaperId), 1) ); } @Override public void decrementVotePaperLikeCount(final Long votePaperId) { - redisTemplate.opsForHash().increment(getKey(votePaperId), LIKE_COUNT_HASH_KEY, -1); + Optional votePaperLikeCountById = getVotePaperLikeCountById(votePaperId); + + if (votePaperLikeCountById.isEmpty()) { + redisTemplate.opsForValue().set(getKey(votePaperId), 0); + return; + } + + log.info("vote paper like count : {}", votePaperLikeCountById.get()); + + if (Long.parseLong(String.valueOf(votePaperLikeCountById.get())) == 0) + return; + + redisTemplate.opsForValue().decrement(getKey(votePaperId)); } @Override @@ -56,7 +72,7 @@ public Long getVotePaperId(final String key) { @Override public Optional getVotePaperLikeCountById(final Long votePaperId) { - return Optional.ofNullable(redisTemplate.opsForHash().get(getKey(votePaperId), LIKE_COUNT_HASH_KEY)); + return Optional.ofNullable(redisTemplate.opsForValue().get(getKey(votePaperId))); } } diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeRepository.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeRepository.java index a99b2544..ee8edd1a 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeRepository.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeRepository.java @@ -1,6 +1,11 @@ package com.tune_fun.v1.interaction.adapter.output.persistence; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; public interface VotePaperLikeRepository extends JpaRepository { + + @EntityGraph(attributePaths = {"votePaper", "liker"}) + void deleteByVotePaperIdAndLikerUsername(final Long votePaperId, final String username); + } \ No newline at end of file diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java b/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java index 146676de..6ff34238 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/input/usecase/UnlikeVotePaperUseCase.java @@ -1,8 +1,10 @@ package com.tune_fun.v1.interaction.application.port.input.usecase; +import org.springframework.security.core.userdetails.User; + @FunctionalInterface public interface UnlikeVotePaperUseCase { - void unlikeVotePaper(final Long votePaperId, final Long likeId); + void unlikeVotePaper(final Long votePaperId, final User user); } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java b/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java index 9fc99396..09f01d8f 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/output/DeleteLikePort.java @@ -1,5 +1,5 @@ package com.tune_fun.v1.interaction.application.port.output; public interface DeleteLikePort { - void deleteVotePaperLike(final Long likeId); + void deleteVotePaperLike(final Long votePaperId, final String username); } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java index f33769d2..ee73c165 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/UnlikeVotePaperService.java @@ -5,6 +5,7 @@ import com.tune_fun.v1.interaction.application.port.output.DeleteLikePort; import com.tune_fun.v1.interaction.application.port.output.SaveVotePaperLikeCountPort; import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -18,8 +19,8 @@ public class UnlikeVotePaperService implements UnlikeVotePaperUseCase { @Transactional @Override - public void unlikeVotePaper(final Long votePaperId, final Long likeId) { - deleteLikePort.deleteVotePaperLike(likeId); + public void unlikeVotePaper(final Long votePaperId, final User user) { + deleteLikePort.deleteVotePaperLike(votePaperId, user.getUsername()); saveVotePaperLikeCountPort.decrementVotePaperLikeCount(votePaperId); } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java index 1d940327..c5944a96 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java @@ -202,8 +202,8 @@ public void saveVotePaperLike(final Long votePaperId, final String username) { } @Override - public void deleteVotePaperLike(final Long likeId) { - votePaperLikeRepository.deleteById(likeId); + public void deleteVotePaperLike(final Long votePaperId, final String username) { + votePaperLikeRepository.deleteByVotePaperIdAndLikerUsername(votePaperId, username); } @Override diff --git a/src/test/java/com/tune_fun/v1/dummy/DummyService.java b/src/test/java/com/tune_fun/v1/dummy/DummyService.java index 63d7a621..d12c7845 100644 --- a/src/test/java/com/tune_fun/v1/dummy/DummyService.java +++ b/src/test/java/com/tune_fun/v1/dummy/DummyService.java @@ -13,6 +13,7 @@ import com.tune_fun.v1.account.domain.behavior.SaveDevice; import com.tune_fun.v1.base.annotation.IntegrationTest; import com.tune_fun.v1.common.util.StringUtil; +import com.tune_fun.v1.interaction.adapter.output.persistence.LikeCountPersistenceAdapter; import com.tune_fun.v1.otp.adapter.output.persistence.OtpPersistenceAdapter; import com.tune_fun.v1.otp.adapter.output.persistence.OtpType; import com.tune_fun.v1.otp.application.port.input.query.OtpQueries; @@ -92,6 +93,9 @@ public class DummyService { @Autowired private VotePersistenceAdapter votePersistenceAdapter; + @Autowired + private LikeCountPersistenceAdapter likeCountPersistenceAdapter; + @Autowired private VoteBehaviorMapper voteBehaviorMapper; @@ -316,4 +320,10 @@ public void saveVoteChoiceByRegisteredVotePaper(VotePaperCommands.Register comma Set saveVoteChoicesBehavior = voteBehaviorMapper.saveVoteChoices(command.offers()); votePersistenceAdapter.saveVoteChoice(registeredVotePaper.id(), saveVoteChoicesBehavior); } + + @Transactional + public void likeVotePaper(final Long votePaperId, final String username) { + votePersistenceAdapter.saveVotePaperLike(votePaperId, username); + likeCountPersistenceAdapter.incrementVotePaperLikeCount(votePaperId); + } } diff --git a/src/test/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeControllerTest.java b/src/test/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeControllerTest.java index 09b6eab3..1c12bcf6 100644 --- a/src/test/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeControllerTest.java +++ b/src/test/java/com/tune_fun/v1/interaction/adapter/input/rest/LikeControllerTest.java @@ -28,6 +28,7 @@ import static org.springframework.http.HttpHeaders.AUTHORIZATION; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; @@ -88,7 +89,49 @@ void likeVotePaperSuccess() throws Exception { assertTrue(loadVotePaperLikeCountPort.getVotePaperLikeCountById(votePaperId).isPresent()); awaitLikeCountAggregationScheduler(); - awaitUpdateLikeCount(votePaperId); + awaitIncrementLikeCount(votePaperId); + } + + @Transactional + @Test + @Order(2) + @DisplayName("투표 게시물 좋아요 취소, 성공") + void unlikeVotePaperSuccess() throws Exception { + dummyService.initArtistAndLogin(); + dummyService.initVotePaper(); + Long votePaperId = dummyService.getDefaultVotePaper().getId(); + + dummyService.initAndLogin(); + dummyService.likeVotePaper(votePaperId, dummyService.getDefaultAccount().getUsername()); + + String accessToken = dummyService.getDefaultAccessToken(); + + ParameterDescriptor pathParameter = parameterWithName("votePaperId").description("투표 게시물 ID").attributes(constraint("NOT NULL")); + + mockMvc.perform( + delete(Uris.LIKE_VOTE_PAPER, votePaperId) + .header(AUTHORIZATION, bearerToken(accessToken)) + .contentType(APPLICATION_JSON_VALUE) + ) + .andExpectAll(baseAssertion(MessageCode.SUCCESS)) + .andDo( + restDocs.document( + requestHeaders(authorizationHeader), + pathParameters(pathParameter), + responseFields(baseResponseFields), + resource( + builder(). + description("투표 게시물 좋아요 추가"). + pathParameters(pathParameter). + responseFields(baseResponseFields) + .build() + ) + ) + ); + + assertTrue(loadVotePaperLikeCountPort.getVotePaperLikeCountById(votePaperId).isPresent()); + awaitLikeCountAggregationScheduler(); + awaitDecrementLikeCount(votePaperId); } private void awaitLikeCountAggregationScheduler() { @@ -99,11 +142,19 @@ private void verifyInvokeAggregateLikeCount() { verify(likeCountAggregationScheduler, times(1)).aggregateLikeCount(); } - private void awaitUpdateLikeCount(Long votePaperId) { - await().untilAsserted(() -> verifyInvokeUpdateLikeCount(votePaperId)); + private void awaitIncrementLikeCount(Long votePaperId) { + await().untilAsserted(() -> verifyInvokeIncrementLikeCount(votePaperId)); } - private void verifyInvokeUpdateLikeCount(Long votePaperId) { + private void verifyInvokeIncrementLikeCount(Long votePaperId) { verify(saveVotePaperStatPort, times(1)).updateLikeCount(votePaperId, 1L); } + + private void awaitDecrementLikeCount(Long votePaperId) { + await().untilAsserted(() -> verifyInvokeDecrementLikeCount(votePaperId)); + } + + private void verifyInvokeDecrementLikeCount(Long votePaperId) { + verify(saveVotePaperStatPort, times(1)).updateLikeCount(votePaperId, 0L); + } } \ No newline at end of file diff --git a/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java b/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java index 948be93a..a200085f 100644 --- a/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java +++ b/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java @@ -758,31 +758,35 @@ void testSaveVotePaperLike4() { } /** - * Method under test: {@link VotePersistenceAdapter#deleteVotePaperLike(Long)} + * Method under test: + * {@link VotePersistenceAdapter#deleteVotePaperLike(Long, String)} */ @Test void testDeleteVotePaperLike() { // Arrange - doNothing().when(votePaperLikeRepository).deleteById(Mockito.any()); + doNothing().when(votePaperLikeRepository) + .deleteByVotePaperIdAndLikerUsername(Mockito.any(), Mockito.any()); // Act - votePersistenceAdapter.deleteVotePaperLike(1L); + votePersistenceAdapter.deleteVotePaperLike(1L, "janedoe"); // Assert that nothing has changed - verify(votePaperLikeRepository).deleteById(eq(1L)); + verify(votePaperLikeRepository).deleteByVotePaperIdAndLikerUsername(eq(1L), eq("janedoe")); } /** - * Method under test: {@link VotePersistenceAdapter#deleteVotePaperLike(Long)} + * Method under test: + * {@link VotePersistenceAdapter#deleteVotePaperLike(Long, String)} */ @Test void testDeleteVotePaperLike2() { // Arrange - doThrow(new IllegalArgumentException("foo")).when(votePaperLikeRepository).deleteById(Mockito.any()); + doThrow(new IllegalArgumentException("foo")).when(votePaperLikeRepository) + .deleteByVotePaperIdAndLikerUsername(Mockito.any(), Mockito.any()); // Act and Assert - assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.deleteVotePaperLike(1L)); - verify(votePaperLikeRepository).deleteById(eq(1L)); + assertThrows(IllegalArgumentException.class, () -> votePersistenceAdapter.deleteVotePaperLike(1L, "janedoe")); + verify(votePaperLikeRepository).deleteByVotePaperIdAndLikerUsername(eq(1L), eq("janedoe")); } /** From 9e1e3dd881e52f55225895c59f3a3339cd748e4b Mon Sep 17 00:00:00 2001 From: habin Date: Thu, 23 May 2024 17:59:21 +0900 Subject: [PATCH 12/16] feat(interaction) like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: LikeCountAggregationScheduler Correlation ID 로깅 추가 --- .../java/com/tune_fun/v1/common/filter/MDCLoggingFilter.java | 2 +- .../adapter/input/scheduler/LikeCountAggregationScheduler.java | 3 +++ .../application/service/UpdateVotePaperStatisticsService.java | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/tune_fun/v1/common/filter/MDCLoggingFilter.java b/src/main/java/com/tune_fun/v1/common/filter/MDCLoggingFilter.java index 496f7a3d..793548e6 100644 --- a/src/main/java/com/tune_fun/v1/common/filter/MDCLoggingFilter.java +++ b/src/main/java/com/tune_fun/v1/common/filter/MDCLoggingFilter.java @@ -20,7 +20,7 @@ public class MDCLoggingFilter implements Filter { @Override public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException { - MDC.put("CORRELATION_ID", StringUtil.uuid()); + MDC.put("CORRELATION_ID", StringUtil.ulid()); filterChain.doFilter(servletRequest, servletResponse); MDC.clear(); } diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java b/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java index 01300834..0d503610 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/input/scheduler/LikeCountAggregationScheduler.java @@ -1,8 +1,10 @@ package com.tune_fun.v1.interaction.adapter.input.scheduler; +import com.tune_fun.v1.common.util.StringUtil; import com.tune_fun.v1.interaction.application.port.input.usecase.UpdateVotePaperStatisticsUseCase; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.slf4j.MDC; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -15,6 +17,7 @@ public class LikeCountAggregationScheduler { @Scheduled(fixedDelay = 1000L * 5L) public void aggregateLikeCount() { + MDC.put("CORRELATION_ID", StringUtil.ulid()); log.info("Start to aggregate Vote Paper like count"); updateVotePaperStatisticsUseCase.updateVotePaperStatistics(); } diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java index b4bb114b..8330a091 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/UpdateVotePaperStatisticsService.java @@ -6,6 +6,7 @@ import com.tune_fun.v1.vote.application.port.output.SaveVotePaperStatisticsPort; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.slf4j.MDC; import org.springframework.stereotype.Service; import java.util.Set; @@ -31,5 +32,7 @@ public void updateVotePaperStatistics() { saveVotePaperStatPort.updateLikeCount(votePaperId, likeCount); log.info("Update vote paper statistics for vote paper id: {} with like count: {}", votePaperId, likeCount); }); + + MDC.clear(); } } From 8edcac8a24ee88a853ed4385b9202151e9d3ee27 Mon Sep 17 00:00:00 2001 From: habin Date: Fri, 24 May 2024 12:26:49 +0900 Subject: [PATCH 13/16] feat(interaction) like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: 투표 게시물 좋아요 이력 확인 로직 추가 --- .../v1/common/response/MessageCode.java | 1 + .../LikeCountPersistenceAdapter.java | 2 - .../VotePaperLikeCustomRepository.java | 13 +++++ .../VotePaperLikeCustomRepositoryImpl.java | 54 +++++++++++++++++++ .../persistence/VotePaperLikeRepository.java | 11 ++-- .../application/port/output/LoadLikePort.java | 9 ++++ .../service/LikeVotePaperService.java | 13 +++++ .../persistence/VotePersistenceAdapter.java | 15 +++--- .../domain/value/RegisteredVotePaperLike.java | 20 +++++++ 9 files changed, 124 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeCustomRepository.java create mode 100644 src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeCustomRepositoryImpl.java create mode 100644 src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadLikePort.java create mode 100644 src/main/java/com/tune_fun/v1/vote/domain/value/RegisteredVotePaperLike.java diff --git a/src/main/java/com/tune_fun/v1/common/response/MessageCode.java b/src/main/java/com/tune_fun/v1/common/response/MessageCode.java index d348aa18..2cd4a859 100644 --- a/src/main/java/com/tune_fun/v1/common/response/MessageCode.java +++ b/src/main/java/com/tune_fun/v1/common/response/MessageCode.java @@ -71,6 +71,7 @@ public enum MessageCode { VOTE_POLICY_OFFERS_COUNT_SHOULD_BE_MORE_THAN_TWO(BAD_REQUEST, "3207"), VOTE_POLICY_ONLY_REGISTER_CHOICE_ON_ALLOW_ADD_CHOICES_OPTION(BAD_REQUEST, "3208"), VOTE_POLICY_ONE_VOTE_CHOICE_PER_USER_ON_VOTE_PAPER(BAD_REQUEST, "3209"), + VOTE_POLICY_ALREADY_LIKED_VOTE_PAPER(BAD_REQUEST, "3210"), // 분산 락 관련 LOCK_ACQUISITION_FAILED_ERROR(INTERNAL_SERVER_ERROR, "4001"), diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java index 287dc829..c1a7adaf 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/LikeCountPersistenceAdapter.java @@ -19,8 +19,6 @@ public class LikeCountPersistenceAdapter implements SaveVotePaperLikeCountPort, private static final String VOTE_PAPER_LIKE_COUNT_KEY = "vote_paper_like_count"; - private static final String LIKE_COUNT_HASH_KEY = "like_count"; - private final RedisTemplate redisTemplate; @Override diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeCustomRepository.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeCustomRepository.java new file mode 100644 index 00000000..40980c44 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeCustomRepository.java @@ -0,0 +1,13 @@ +package com.tune_fun.v1.interaction.adapter.output.persistence; + +import com.tune_fun.v1.vote.domain.value.RegisteredVotePaperLike; + +import java.util.Optional; + +public interface VotePaperLikeCustomRepository { + + Optional findByVotePaperIdAndLikerUsername(final Long votePaperId, final String username); + + void deleteByVotePaperIdAndLikerUsername(final Long votePaperId, final String username); + +} diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeCustomRepositoryImpl.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeCustomRepositoryImpl.java new file mode 100644 index 00000000..ca04d13d --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeCustomRepositoryImpl.java @@ -0,0 +1,54 @@ +package com.tune_fun.v1.interaction.adapter.output.persistence; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import com.tune_fun.v1.account.adapter.output.persistence.QAccountJpaEntity; +import com.tune_fun.v1.vote.adapter.output.persistence.QVotePaperJpaEntity; +import com.tune_fun.v1.vote.domain.value.RegisteredVotePaperLike; +import lombok.RequiredArgsConstructor; + +import java.util.Optional; + +import static com.querydsl.core.types.Projections.fields; + +@RequiredArgsConstructor +public class VotePaperLikeCustomRepositoryImpl implements VotePaperLikeCustomRepository { + + private final JPAQueryFactory queryFactory; + + private static final QVotePaperLikeJpaEntity VOTE_PAPER_LIKE = QVotePaperLikeJpaEntity.votePaperLikeJpaEntity; + private static final QVotePaperJpaEntity VOTE_PAPER = QVotePaperJpaEntity.votePaperJpaEntity; + private static final QAccountJpaEntity ACCOUNT = QAccountJpaEntity.accountJpaEntity; + + + @Override + public Optional findByVotePaperIdAndLikerUsername(Long votePaperId, String username) { + return Optional.ofNullable( + queryFactory.select(fields(RegisteredVotePaperLike.class, + VOTE_PAPER_LIKE.id.as("id"), + VOTE_PAPER.id.as("votePaperId"), + ACCOUNT.id.as("likerAccountId"), + ACCOUNT.username.as("likerUsername"), + VOTE_PAPER_LIKE.createdAt.as("createdAt") + ) + ) + .from(VOTE_PAPER_LIKE) + .join(VOTE_PAPER_LIKE.votePaper, VOTE_PAPER).fetchJoin() + .join(VOTE_PAPER_LIKE.liker, ACCOUNT).fetchJoin() + .where(VOTE_PAPER.id.eq(votePaperId), ACCOUNT.username.eq(username)) + .fetchOne() + ); + } + + @Override + public void deleteByVotePaperIdAndLikerUsername(Long votePaperId, String username) { + + queryFactory.delete(VOTE_PAPER_LIKE) + .where( + VOTE_PAPER_LIKE.votePaper.id.eq(votePaperId) + .and(VOTE_PAPER_LIKE.liker.username.eq(username)) + ) + .execute(); + + + } +} diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeRepository.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeRepository.java index ee8edd1a..3f608185 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeRepository.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeRepository.java @@ -1,11 +1,10 @@ package com.tune_fun.v1.interaction.adapter.output.persistence; -import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; -public interface VotePaperLikeRepository extends JpaRepository { +public interface VotePaperLikeRepository extends JpaRepository, VotePaperLikeCustomRepository { - @EntityGraph(attributePaths = {"votePaper", "liker"}) - void deleteByVotePaperIdAndLikerUsername(final Long votePaperId, final String username); - -} \ No newline at end of file +// @EntityGraph(attributePaths = {"votePaper", "liker"}) +// void deleteByVotePaperIdAndLikerUsername(final Long votePaperId, final String username); + +} diff --git a/src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadLikePort.java b/src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadLikePort.java new file mode 100644 index 00000000..7c2d5915 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/interaction/application/port/output/LoadLikePort.java @@ -0,0 +1,9 @@ +package com.tune_fun.v1.interaction.application.port.output; + +import com.tune_fun.v1.vote.domain.value.RegisteredVotePaperLike; + +import java.util.Optional; + +public interface LoadLikePort { + Optional loadVotePaperLike(final Long votePaperId, final String username); +} diff --git a/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java b/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java index 0b03ebeb..60021af1 100644 --- a/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java +++ b/src/main/java/com/tune_fun/v1/interaction/application/service/LikeVotePaperService.java @@ -1,7 +1,10 @@ package com.tune_fun.v1.interaction.application.service; +import com.tune_fun.v1.common.exception.CommonApplicationException; import com.tune_fun.v1.common.hexagon.UseCase; +import com.tune_fun.v1.common.response.MessageCode; import com.tune_fun.v1.interaction.application.port.input.usecase.LikeVotePaperUseCase; +import com.tune_fun.v1.interaction.application.port.output.LoadLikePort; import com.tune_fun.v1.interaction.application.port.output.SaveLikePort; import com.tune_fun.v1.interaction.application.port.output.SaveVotePaperLikeCountPort; import lombok.RequiredArgsConstructor; @@ -9,20 +12,30 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import static com.tune_fun.v1.common.response.MessageCode.VOTE_POLICY_ALREADY_LIKED_VOTE_PAPER; + @Service @UseCase @RequiredArgsConstructor public class LikeVotePaperService implements LikeVotePaperUseCase { private final SaveLikePort saveLikePort; + private final LoadLikePort loadLikePort; private final SaveVotePaperLikeCountPort saveVotePaperLikeCountPort; @Transactional @Override public void likeVotePaper(final Long votePaperId, final User user) { + if (isVotePaperLikePresent(votePaperId, user)) + throw new CommonApplicationException(VOTE_POLICY_ALREADY_LIKED_VOTE_PAPER); + saveLikePort.saveVotePaperLike(votePaperId, user.getUsername()); saveVotePaperLikeCountPort.incrementVotePaperLikeCount(votePaperId); } + public boolean isVotePaperLikePresent(Long votePaperId, User user) { + return loadLikePort.loadVotePaperLike(votePaperId, user.getUsername()).isPresent(); + } + } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java index c5944a96..e8970c48 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java @@ -8,14 +8,12 @@ import com.tune_fun.v1.interaction.adapter.output.persistence.VotePaperLikeJpaEntity; import com.tune_fun.v1.interaction.adapter.output.persistence.VotePaperLikeRepository; import com.tune_fun.v1.interaction.application.port.output.DeleteLikePort; +import com.tune_fun.v1.interaction.application.port.output.LoadLikePort; import com.tune_fun.v1.interaction.application.port.output.SaveLikePort; import com.tune_fun.v1.vote.application.port.output.*; import com.tune_fun.v1.vote.domain.behavior.SaveVoteChoice; import com.tune_fun.v1.vote.domain.behavior.SaveVotePaper; -import com.tune_fun.v1.vote.domain.value.RegisteredVote; -import com.tune_fun.v1.vote.domain.value.RegisteredVoteChoice; -import com.tune_fun.v1.vote.domain.value.RegisteredVotePaper; -import com.tune_fun.v1.vote.domain.value.ScrollableVotePaper; +import com.tune_fun.v1.vote.domain.value.*; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.KeysetScrollPosition; import org.springframework.data.domain.ScrollPosition; @@ -43,8 +41,8 @@ public class VotePersistenceAdapter implements LoadVotePaperPort, SaveVotePaperPort, DeleteVotePaperPort, UpdateDeliveryAtPort, UpdateVideoUrlPort, LoadVoteChoicePort, SaveVoteChoicePort, - SaveLikePort, DeleteLikePort, - SaveVotePaperStatisticsPort, LoadVotePaperStatisticsPort { + LoadLikePort, SaveLikePort, DeleteLikePort, + LoadVotePaperStatisticsPort, SaveVotePaperStatisticsPort { private final AccountPersistenceAdapter accountPersistenceAdapter; @@ -185,6 +183,11 @@ public void saveVoteChoice(final Long votePaperId, final Set beh voteChoiceRepository.saveAll(updatedVoteChoices); } + @Override + public Optional loadVotePaperLike(Long votePaperId, String username) { + return votePaperLikeRepository.findByVotePaperIdAndLikerUsername(votePaperId, username); + } + @Override public void saveVotePaperLike(final Long votePaperId, final String username) { AccountJpaEntity account = accountPersistenceAdapter.loadAccountByUsername(username) diff --git a/src/main/java/com/tune_fun/v1/vote/domain/value/RegisteredVotePaperLike.java b/src/main/java/com/tune_fun/v1/vote/domain/value/RegisteredVotePaperLike.java new file mode 100644 index 00000000..27dd66e5 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/vote/domain/value/RegisteredVotePaperLike.java @@ -0,0 +1,20 @@ +package com.tune_fun.v1.vote.domain.value; + +import lombok.*; + +import java.time.LocalDateTime; + +@Builder +@Getter +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode +public final class RegisteredVotePaperLike { + + private Long id; + private Long votePaperId; + private String likerAccountId; + private String likerUsername; + private LocalDateTime createdAt; + +} From 080319d95d662822745e536e6ab08e8613e37997 Mon Sep 17 00:00:00 2001 From: habin Date: Sat, 25 May 2024 14:42:29 +0900 Subject: [PATCH 14/16] feat(interaction) like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit docs: Interaction API 문서 추가 --- src/docs/asciidoc/index.adoc | 3 ++- src/docs/asciidoc/interaction-api.adoc | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/docs/asciidoc/interaction-api.adoc diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc index 4146dad3..23d38b72 100644 --- a/src/docs/asciidoc/index.adoc +++ b/src/docs/asciidoc/index.adoc @@ -13,4 +13,5 @@ include::common/message.adoc[] include::account-api.adoc[] include::oauth2-api.adoc[] include::otp-api.adoc[] -include::vote-api.adoc[] \ No newline at end of file +include::vote-api.adoc[] +include::interaction-api.adoc[] \ No newline at end of file diff --git a/src/docs/asciidoc/interaction-api.adoc b/src/docs/asciidoc/interaction-api.adoc new file mode 100644 index 00000000..8796a59f --- /dev/null +++ b/src/docs/asciidoc/interaction-api.adoc @@ -0,0 +1,14 @@ +[[Interaction-API]] +== Like API + +=== 투표 게시물 좋아요 등록 API + +==== 성공 + +operation::like-vote-paper-success[snipeets='http-request,http-response,path-parameter,response-fields'] + +=== 투표 게시물 좋아요 취소 API + +==== 성공 + +operation::unlike-vote-paper-success[snipeets='http-request,http-response,path-parameter,response-fields'] \ No newline at end of file From de76c934a55a9751ab0298ba3b1b8cf80f5c5328 Mon Sep 17 00:00:00 2001 From: habin Date: Sat, 25 May 2024 15:24:24 +0900 Subject: [PATCH 15/16] feat(vote-paper) register, choice-register, get MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: Offer API Spec에 music-image 추가 --- .../VotePaperLikeCustomRepositoryImpl.java | 4 +-- .../adapter/input/rest/VoteController.java | 4 +-- .../input/rest/VotePaperController.java | 10 +++---- .../adapter/output/persistence/Offer.java | 7 +++-- .../output/persistence/VoteChoiceMapper.java | 3 ++ .../port/input/command/VotePaperCommands.java | 5 ++-- .../service/VoteBehaviorMapper.java | 1 - .../vote/domain/behavior/SaveVoteChoice.java | 1 + .../domain/value/RegisteredVoteChoice.java | 1 + .../domain/value/RegisteredVotePaperLike.java | 2 +- .../resources/messages/messages.properties | 1 + .../messages/messages_en_US.properties | 1 + .../messages/messages_ko_KR.properties | 1 + .../api/CustomResponseControllerTest.java | 2 +- .../common/api/MessageCodeControllerTest.java | 6 ++-- .../com/tune_fun/v1/dummy/DummyService.java | 8 ++--- .../input/rest/VotePaperControllerIT.java | 29 +++++++------------ .../VotePersistenceAdapterTest.java | 2 +- 18 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeCustomRepositoryImpl.java b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeCustomRepositoryImpl.java index ca04d13d..390c4272 100644 --- a/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeCustomRepositoryImpl.java +++ b/src/main/java/com/tune_fun/v1/interaction/adapter/output/persistence/VotePaperLikeCustomRepositoryImpl.java @@ -32,8 +32,8 @@ public Optional findByVotePaperIdAndLikerUsername(Long ) ) .from(VOTE_PAPER_LIKE) - .join(VOTE_PAPER_LIKE.votePaper, VOTE_PAPER).fetchJoin() - .join(VOTE_PAPER_LIKE.liker, ACCOUNT).fetchJoin() + .join(VOTE_PAPER_LIKE.votePaper, VOTE_PAPER) + .join(VOTE_PAPER_LIKE.liker, ACCOUNT) .where(VOTE_PAPER.id.eq(votePaperId), ACCOUNT.username.eq(username)) .fetchOne() ); diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/input/rest/VoteController.java b/src/main/java/com/tune_fun/v1/vote/adapter/input/rest/VoteController.java index 2676b172..b19050ea 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/input/rest/VoteController.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/input/rest/VoteController.java @@ -25,8 +25,8 @@ public class VoteController { // @PreAuthorize("hasPermission(#votePaperId, 'VOTE', 'REGISTER_VOTE')") @PostMapping(value = Uris.REGISTER_VOTE) - public ResponseEntity> registerVote(@PathVariable(name = "votePaperId") @NotNull(message = "{vote.paper.offerId.not_null}") final Long votePaperId, - @PathVariable(name = "voteChoiceId") @NotNull(message = "{vote.choice.offerId.not_null}") final Long voteChoiceId, + public ResponseEntity> registerVote(@PathVariable(name = "votePaperId") @NotNull(message = "{vote.paper.id.not_null}") final Long votePaperId, + @PathVariable(name = "voteChoiceId") @NotNull(message = "{vote.choice.id.not_null}") final Long voteChoiceId, @CurrentUser final User user) { registerVoteUseCase.register(votePaperId, voteChoiceId, user); return responseMapper.ok(); diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperController.java b/src/main/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperController.java index 043df88f..d5b79384 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperController.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperController.java @@ -49,7 +49,7 @@ public ResponseEntity> getVotePapers(@RequestP } @GetMapping(value = Uris.VOTE_PAPER_ROOT + "/{votePaperId}") - public ResponseEntity> getVotePaper(@PathVariable("votePaperId") @NotNull(message = "{vote.paper.offerId.not_null}") final Long votePaperId, + public ResponseEntity> getVotePaper(@PathVariable("votePaperId") @NotNull(message = "{vote.paper.id.not_null}") final Long votePaperId, @CurrentUser final User user) { FullVotePaper votePaper = getVotePaperUseCase.getVotePaper(votePaperId); return responseMapper.ok(MessageCode.SUCCESS, votePaper); @@ -66,7 +66,7 @@ public ResponseEntity> registerVotePaper(@Valid @RequestBo @PreAuthorize("hasRole('NORMAL')") @PostMapping(value = Uris.VOTE_PAPER_CHOICE) - public ResponseEntity> registerVotePaperChoice(@PathVariable("votePaperId") @NotNull(message = "{vote.paper.offerId.not_null}") final Long votePaperId, + public ResponseEntity> registerVotePaperChoice(@PathVariable("votePaperId") @NotNull(message = "{vote.paper.id.not_null}") final Long votePaperId, @Valid @RequestBody final VotePaperCommands.Offer offer, @CurrentUser final User user) { registerVoteChoiceUseCase.registerVoteChoice(votePaperId, offer, user); @@ -75,7 +75,7 @@ public ResponseEntity> registerVotePaperChoice(@PathVariab @PreAuthorize("hasRole('ARTIST')") @PatchMapping(value = Uris.UPDATE_VOTE_PAPER_DELIVERY_DATE) - public ResponseEntity> updateDeliveryDate(@PathVariable("votePaperId") @NotNull(message = "{vote.paper.offerId.not_null}") final Long votePaperId, + public ResponseEntity> updateDeliveryDate(@PathVariable("votePaperId") @NotNull(message = "{vote.paper.id.not_null}") final Long votePaperId, @Valid @RequestBody final VotePaperCommands.UpdateDeliveryDate command, @CurrentUser final User user) { updateVotePaperDeliveryDateUseCase.updateDeliveryDate(votePaperId, command, user); @@ -84,7 +84,7 @@ public ResponseEntity> updateDeliveryDate(@PathVariable("v @PreAuthorize("hasRole('ARTIST')") @PatchMapping(value = Uris.UPDATE_VOTE_PAPER_VIDEO_URL) - public ResponseEntity> updateVideoUrl(@PathVariable("votePaperId") @NotNull(message = "{vote.paper.offerId.not_null}") final Long votePaperId, + public ResponseEntity> updateVideoUrl(@PathVariable("votePaperId") @NotNull(message = "{vote.paper.id.not_null}") final Long votePaperId, @Valid @RequestBody final VotePaperCommands.UpdateVideoUrl command, @CurrentUser final User user) { updateVotePaperVideoUrlUseCase.updateVideoUrl(votePaperId, command, user); @@ -93,7 +93,7 @@ public ResponseEntity> updateVideoUrl(@PathVariable("voteP @PreAuthorize("hasRole('ARTIST')") @DeleteMapping(value = Uris.VOTE_PAPER_ROOT) - public ResponseEntity> deleteVotePaper(@RequestParam(name = "vote_paper_id") Long votePaperId, + public ResponseEntity> deleteVotePaper(@RequestParam(name = "vote_paper_id") @NotNull(message = "{vote.paper.id.not_null}") Long votePaperId, @CurrentUser User user) { deleteVotePaperUseCase.delete(votePaperId, user); return responseMapper.ok(MessageCode.SUCCESS); diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/Offer.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/Offer.java index e23946b4..41e688b6 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/Offer.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/Offer.java @@ -5,10 +5,11 @@ /** * 투표 선택지의 제안 사항 * - * @param offerId Spotify Music ID - * @param music 노래명 + * @param offerId Spotify Music ID + * @param music 노래명 + * @param musicImage 노래 이미지 * @param artistName 아티스트 */ @Embeddable -public record Offer(String offerId, String music, String artistName) { +public record Offer(String offerId, String music, String musicImage, String artistName) { } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteChoiceMapper.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteChoiceMapper.java index 234849b4..4f57ea00 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteChoiceMapper.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VoteChoiceMapper.java @@ -24,6 +24,7 @@ public abstract class VoteChoiceMapper { @Mapping(target = "votePaperId", source = "votePaper.id") @Mapping(target = "offerId", source = "offer.offerId") @Mapping(target = "music", source = "offer.music") + @Mapping(target = "musicImage", source = "offer.musicImage") @Mapping(target = "artistName", source = "offer.artistName") public abstract RegisteredVoteChoice registeredVoteChoice(final VoteChoiceJpaEntity voteChoiceJpaEntity); @@ -32,6 +33,7 @@ public abstract class VoteChoiceMapper { @Mapping(target = "createdAt", ignore = true) @Mapping(target = "updatedAt", ignore = true) @Mapping(target = "uuid", ignore = true) + @Mapping(target = "offer", ignore = true) public abstract VoteChoiceJpaEntity.VoteChoiceJpaEntityBuilder updateVoteChoice(VotePaperJpaEntity votePaperJpaEntity, @MappingTarget final VoteChoiceJpaEntity.VoteChoiceJpaEntityBuilder voteChoiceJpaEntityBuilder); @@ -47,6 +49,7 @@ public abstract class VoteChoiceMapper { @Named("voteChoiceOffer") @Mapping(target = "offerId", source = "id") @Mapping(target = "music", source = "music") + @Mapping(target = "musicImage", source = "musicImage") @Mapping(target = "artistName", source = "artistName") public abstract Offer voteChoiceOffer(final SaveVoteChoice behavior); diff --git a/src/main/java/com/tune_fun/v1/vote/application/port/input/command/VotePaperCommands.java b/src/main/java/com/tune_fun/v1/vote/application/port/input/command/VotePaperCommands.java index dab21d5b..3650f551 100644 --- a/src/main/java/com/tune_fun/v1/vote/application/port/input/command/VotePaperCommands.java +++ b/src/main/java/com/tune_fun/v1/vote/application/port/input/command/VotePaperCommands.java @@ -11,7 +11,6 @@ import org.hibernate.validator.constraints.URL; import java.time.LocalDateTime; -import java.util.List; import java.util.Set; public class VotePaperCommands { @@ -20,7 +19,7 @@ public class VotePaperCommands { @Period(start = "voteStartAt", end = "voteEndAt", message = "{vote.paper.vote_period.not_match}") public record Register( @NotBlank(message = "{vote.paper.title.not_blank}") String title, - @NotBlank(message = "{vote.paper.content.not_blank}") String content, + String content, @NotNull(message = "{vote.paper.option.not_null}") @Enum(message = "{vote.paper.option.valid}", target = VotePaperOption.class) VotePaperOption option, @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @@ -49,6 +48,8 @@ public record Offer( @NotBlank(message = "{vote.paper.offer.music.not_blank}") String music, + String musicImage, + @NotBlank(message = "{vote.paper.offer.artist_name.not_blank}") String artistName ) { diff --git a/src/main/java/com/tune_fun/v1/vote/application/service/VoteBehaviorMapper.java b/src/main/java/com/tune_fun/v1/vote/application/service/VoteBehaviorMapper.java index 4da9f78a..7c48707b 100644 --- a/src/main/java/com/tune_fun/v1/vote/application/service/VoteBehaviorMapper.java +++ b/src/main/java/com/tune_fun/v1/vote/application/service/VoteBehaviorMapper.java @@ -29,7 +29,6 @@ public abstract class VoteBehaviorMapper { public abstract Set saveVoteChoices(final Set offers); @Named("saveVoteChoice") - @Mapping(target = "artistName", source = "artistName") public abstract SaveVoteChoice saveVoteChoice(final VotePaperCommands.Offer offer); @Mapping(target = "title", source = "event", qualifiedByName = "votePaperRegisterNotificationTitle") diff --git a/src/main/java/com/tune_fun/v1/vote/domain/behavior/SaveVoteChoice.java b/src/main/java/com/tune_fun/v1/vote/domain/behavior/SaveVoteChoice.java index f0b29957..0e82a097 100644 --- a/src/main/java/com/tune_fun/v1/vote/domain/behavior/SaveVoteChoice.java +++ b/src/main/java/com/tune_fun/v1/vote/domain/behavior/SaveVoteChoice.java @@ -3,6 +3,7 @@ public record SaveVoteChoice( String id, String music, + String musicImage, String artistName ) { diff --git a/src/main/java/com/tune_fun/v1/vote/domain/value/RegisteredVoteChoice.java b/src/main/java/com/tune_fun/v1/vote/domain/value/RegisteredVoteChoice.java index eb080ab9..183a06e6 100644 --- a/src/main/java/com/tune_fun/v1/vote/domain/value/RegisteredVoteChoice.java +++ b/src/main/java/com/tune_fun/v1/vote/domain/value/RegisteredVoteChoice.java @@ -7,6 +7,7 @@ public record RegisteredVoteChoice( Long votePaperId, String offerId, String music, + String musicImage, String artistName ) implements BasePayload { } diff --git a/src/main/java/com/tune_fun/v1/vote/domain/value/RegisteredVotePaperLike.java b/src/main/java/com/tune_fun/v1/vote/domain/value/RegisteredVotePaperLike.java index 27dd66e5..e5205c47 100644 --- a/src/main/java/com/tune_fun/v1/vote/domain/value/RegisteredVotePaperLike.java +++ b/src/main/java/com/tune_fun/v1/vote/domain/value/RegisteredVotePaperLike.java @@ -13,7 +13,7 @@ public final class RegisteredVotePaperLike { private Long id; private Long votePaperId; - private String likerAccountId; + private Long likerAccountId; private String likerUsername; private LocalDateTime createdAt; diff --git a/src/main/resources/messages/messages.properties b/src/main/resources/messages/messages.properties index 8548a041..72f74f74 100644 --- a/src/main/resources/messages/messages.properties +++ b/src/main/resources/messages/messages.properties @@ -43,5 +43,6 @@ 3207='\uC544\uD2F0\uC2A4\uD2B8\uAC00 \uC0AC\uC804 \uCD94\uAC00' \uC635\uC158\uC5D0\uC11C\uB294 \uC120\uD0DD\uC9C0\uAC00 2\uAC1C \uC774\uC0C1\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4. 3208='\uCC38\uC5EC\uC790\uAC00 \uC9C1\uC811 \uCD94\uAC00' \uC635\uC158\uC778 \uD22C\uD45C \uAC8C\uC2DC\uBB3C\uC5D0\uB9CC \uCC38\uC5EC\uC790\uAC00 \uC9C1\uC811 \uCD94\uAC00\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. 3209=\uD22C\uD45C \uAC8C\uC2DC\uBB3C\uC5D0 \uD55C\uAC1C\uC758 \uC120\uD0DD\uC9C0\uB9CC \uCD94\uAC00\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. +3210=\uD22C\uD45C \uAC8C\uC2DC\uBB3C\uC5D0 \uC774\uBBF8 \uC88B\uC544\uC694\uB97C \uB204\uB974\uC168\uC2B5\uB2C8\uB2E4. 4001=\uB370\uC774\uD130\uB97C \uCC98\uB9AC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. 4002=\uB370\uC774\uD130\uB97C \uCC98\uB9AC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. diff --git a/src/main/resources/messages/messages_en_US.properties b/src/main/resources/messages/messages_en_US.properties index 2b7af4f7..ac514932 100644 --- a/src/main/resources/messages/messages_en_US.properties +++ b/src/main/resources/messages/messages_en_US.properties @@ -43,5 +43,6 @@ 3207=The 'Artist adding in advance' option requires at least two choices. 3208=Participants can only add directly to voting posts, which are the 'Add Directly by Participants' option. 3209=You can only add one option to your voting post. +3210=You've already liked the voting post. 4001=data could not be processed. 4002=Unable to process data. diff --git a/src/main/resources/messages/messages_ko_KR.properties b/src/main/resources/messages/messages_ko_KR.properties index 8548a041..72f74f74 100644 --- a/src/main/resources/messages/messages_ko_KR.properties +++ b/src/main/resources/messages/messages_ko_KR.properties @@ -43,5 +43,6 @@ 3207='\uC544\uD2F0\uC2A4\uD2B8\uAC00 \uC0AC\uC804 \uCD94\uAC00' \uC635\uC158\uC5D0\uC11C\uB294 \uC120\uD0DD\uC9C0\uAC00 2\uAC1C \uC774\uC0C1\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4. 3208='\uCC38\uC5EC\uC790\uAC00 \uC9C1\uC811 \uCD94\uAC00' \uC635\uC158\uC778 \uD22C\uD45C \uAC8C\uC2DC\uBB3C\uC5D0\uB9CC \uCC38\uC5EC\uC790\uAC00 \uC9C1\uC811 \uCD94\uAC00\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. 3209=\uD22C\uD45C \uAC8C\uC2DC\uBB3C\uC5D0 \uD55C\uAC1C\uC758 \uC120\uD0DD\uC9C0\uB9CC \uCD94\uAC00\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. +3210=\uD22C\uD45C \uAC8C\uC2DC\uBB3C\uC5D0 \uC774\uBBF8 \uC88B\uC544\uC694\uB97C \uB204\uB974\uC168\uC2B5\uB2C8\uB2E4. 4001=\uB370\uC774\uD130\uB97C \uCC98\uB9AC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. 4002=\uB370\uC774\uD130\uB97C \uCC98\uB9AC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. diff --git a/src/test/java/com/tune_fun/v1/common/api/CustomResponseControllerTest.java b/src/test/java/com/tune_fun/v1/common/api/CustomResponseControllerTest.java index c993effc..99f8daaf 100644 --- a/src/test/java/com/tune_fun/v1/common/api/CustomResponseControllerTest.java +++ b/src/test/java/com/tune_fun/v1/common/api/CustomResponseControllerTest.java @@ -35,7 +35,7 @@ void getCustomResponseExample() throws Exception { } private static CustomResponseFieldsSnippet customResponseFields(FieldDescriptor... fieldDescriptors) { - return new CustomResponseFieldsSnippet(CustomResponseControllerTest.CUSTOM_RESPONSE_SNIPPET_FILE, Arrays.asList(fieldDescriptors), true); + return new CustomResponseFieldsSnippet(CUSTOM_RESPONSE_SNIPPET_FILE, Arrays.asList(fieldDescriptors), true); } } diff --git a/src/test/java/com/tune_fun/v1/common/api/MessageCodeControllerTest.java b/src/test/java/com/tune_fun/v1/common/api/MessageCodeControllerTest.java index 13987d4f..9d42cd89 100644 --- a/src/test/java/com/tune_fun/v1/common/api/MessageCodeControllerTest.java +++ b/src/test/java/com/tune_fun/v1/common/api/MessageCodeControllerTest.java @@ -26,7 +26,7 @@ class MessageCodeControllerTest extends ControllerBaseTest { void getMessageCodes() throws Exception { mockMvc.perform(get(Uris.MESSAGE_CODES).contentType(APPLICATION_JSON_VALUE)) .andExpect(status().isOk()) - .andDo(restDocs.document(messageCodeResponseFields(MESSAGE_CODE_SNIPPET_FILE, fieldDescriptors()))); + .andDo(restDocs.document(messageCodeResponseFields(fieldDescriptors()))); } private List fieldDescriptors() { @@ -45,8 +45,8 @@ private List fieldDescriptors() { return fieldDescriptors; } - private static MessageCodeResponseFieldsSnippet messageCodeResponseFields(String snippetFilePrefix, List fieldDescriptors) { - return new MessageCodeResponseFieldsSnippet(snippetFilePrefix, fieldDescriptors, true); + private static MessageCodeResponseFieldsSnippet messageCodeResponseFields(List fieldDescriptors) { + return new MessageCodeResponseFieldsSnippet(MESSAGE_CODE_SNIPPET_FILE, fieldDescriptors, true); } } diff --git a/src/test/java/com/tune_fun/v1/dummy/DummyService.java b/src/test/java/com/tune_fun/v1/dummy/DummyService.java index d12c7845..9de0c433 100644 --- a/src/test/java/com/tune_fun/v1/dummy/DummyService.java +++ b/src/test/java/com/tune_fun/v1/dummy/DummyService.java @@ -222,8 +222,8 @@ public void verifyOtp(OtpType otpType, String token) throws Exception { @Transactional public void initVotePaper() { Set offers = Set.of( - new VotePaperCommands.Offer(ulid(), "Love Lee", "AKMU"), - new VotePaperCommands.Offer(ulid(), "Dolphin", "오마이걸") + new VotePaperCommands.Offer(ulid(), "Love Lee", ulid(), "AKMU"), + new VotePaperCommands.Offer(ulid(), "Dolphin", ulid(), "오마이걸") ); LocalDateTime voteStartAt = LocalDateTime.now().plusDays(1); @@ -247,8 +247,8 @@ public void initVotePaper() { @Transactional public void initVotePaperAllowAddChoices() { Set offers = Set.of( - new VotePaperCommands.Offer(ulid(), "KNOCK (With 박문치)", "권진아"), - new VotePaperCommands.Offer(ulid(), "Orange, You're Not a Joke to Me!", "스텔라장 (Stella Jang)") + new VotePaperCommands.Offer(ulid(), "KNOCK (With 박문치)", ulid(), "권진아"), + new VotePaperCommands.Offer(ulid(), "Orange, You're Not a Joke to Me!", ulid(), "스텔라장 (Stella Jang)") ); LocalDateTime voteStartAt = LocalDateTime.now().plusDays(1); diff --git a/src/test/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperControllerIT.java b/src/test/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperControllerIT.java index 5e9cdf46..b7619d2e 100644 --- a/src/test/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperControllerIT.java +++ b/src/test/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperControllerIT.java @@ -12,7 +12,6 @@ import com.tune_fun.v1.vote.application.port.input.command.VotePaperCommands; import com.tune_fun.v1.vote.application.port.output.LoadVoteChoicePort; import com.tune_fun.v1.vote.application.port.output.LoadVotePaperPort; -import com.tune_fun.v1.vote.application.port.output.SendVoteNotificationPort; import com.tune_fun.v1.vote.domain.event.VotePaperDeadlineEvent; import com.tune_fun.v1.vote.domain.event.VotePaperRegisterEvent; import com.tune_fun.v1.vote.domain.event.VotePaperUpdateDeliveryDateEvent; @@ -46,6 +45,7 @@ import static com.epages.restdocs.apispec.ResourceDocumentation.resource; import static com.epages.restdocs.apispec.ResourceSnippetParameters.builder; import static com.tune_fun.v1.base.doc.RestDocsConfig.constraint; +import static com.tune_fun.v1.common.constant.Constants.EMPTY_STRING; import static com.tune_fun.v1.common.util.StringUtil.ulid; import static java.nio.charset.StandardCharsets.UTF_8; import static java.time.LocalDateTime.now; @@ -89,12 +89,6 @@ class VotePaperControllerIT extends ControllerBaseTest { @SpyBean private VoteEventListener voteEventListener; -// @SpyBean -// private ScheduleVotePaperDeadlineService scheduleVotePaperDeadlineService; - - @SpyBean - private SendVoteNotificationPort sendVoteNotificationPort; - @Value("${event.sqs.send-vote-paper-upload-notification.queue-name}") private String votePaperUploadQueue; @@ -207,6 +201,7 @@ void getVotePaperSuccess() throws Exception { fieldWithPath("data.choices[].id").description("아이디").attributes(constraint("NOT NULL")), fieldWithPath("data.choices[].offer_id").description("Spotify Music ID").attributes(constraint("NOT BLANK")), fieldWithPath("data.choices[].music").description("노래명").attributes(constraint("NOT BLANK")), + fieldWithPath("data.choices[].music_image").description("노래 이미지 URL").attributes(constraint(EMPTY_STRING)), fieldWithPath("data.choices[].artist_name").description("아티스트명").attributes(constraint("NOT BLANK")), fieldWithPath("data.choices[].vote_paper_id").description("투표 게시물 ID").attributes(constraint("NOT NULL")) ); @@ -231,8 +226,9 @@ void getVotePaperSuccess() throws Exception { .andExpect(jsonPath("data.updated_at", notNullValue())) .andExpect(jsonPath("data.choices", notNullValue())) .andExpect(jsonPath("data.choices[*].id", notNullValue())) - .andExpect(jsonPath("data.choices[*].music", notNullValue())) .andExpect(jsonPath("data.choices[*].offer_id", notNullValue())) + .andExpect(jsonPath("data.choices[*].music", notNullValue())) + .andExpect(jsonPath("data.choices[*].music_image", notNullValue())) .andExpect(jsonPath("data.choices[*].artist_name", notNullValue())) .andExpect(jsonPath("data.choices[*].vote_paper_id", notNullValue())) .andDo( @@ -263,8 +259,8 @@ void registerVotePaperSuccess() throws Exception { String accessToken = dummyService.getDefaultArtistAccessToken(); Set offers = Set.of( - new VotePaperCommands.Offer(ulid(), "KNOCK (With 박문치)", "권진아"), - new VotePaperCommands.Offer(ulid(), "Orange, You're Not a Joke to Me!", "스텔라장 (Stella Jang)") + new VotePaperCommands.Offer(ulid(), "KNOCK (With 박문치)", ulid(), "권진아"), + new VotePaperCommands.Offer(ulid(), "Orange, You're Not a Joke to Me!", ulid(), "스텔라장 (Stella Jang)") ); LocalDateTime voteStartAt = now().plusSeconds(3); @@ -277,13 +273,14 @@ void registerVotePaperSuccess() throws Exception { FieldDescriptor[] requestDescriptors = { fieldWithPath("title").description("투표 게시물 제목").attributes(constraint("NOT BLANK")), - fieldWithPath("content").description("투표 게시물 내용").attributes(constraint("NOT BLANK")), + fieldWithPath("content").description("투표 게시물 내용").attributes(constraint(EMPTY_STRING)), fieldWithPath("option").description("투표 종류").attributes(constraint("NOT BLANK, allow-add-choices || deny-add-choices")), fieldWithPath("vote_start_at").description("투표 시작 시간").attributes(constraint("NOT NULL & FUTURE & BEFORE(vote_end_at)")), fieldWithPath("vote_end_at").description("투표 종료 시간").attributes(constraint("NOT NULL & FUTURE & AFTER(vote_start_at)")), fieldWithPath("offers").description("투표 선택지 목록").attributes(constraint("NOT EMPTY")), fieldWithPath("offers[].id").description("아이디").attributes(constraint("NOT NULL")), fieldWithPath("offers[].music").description("노래명").attributes(constraint("NOT BLANK")), + fieldWithPath("offers[].music_image").description("노래 이미지 URL").attributes(constraint(EMPTY_STRING)), fieldWithPath("offers[].artist_name").description("아티스트명").attributes(constraint("NOT BLANK")) }; @@ -312,10 +309,6 @@ void registerVotePaperSuccess() throws Exception { awaitReceiveMessage(votePaperUploadQueue); verify(voteMessageConsumer).consumeVotePaperUploadEvent(any(VotePaperRegisterEvent.class)); verify(voteEventListener).handleVotePaperDeadlineEvent(any(VotePaperDeadlineEvent.class)); -// verify(scheduleVotePaperDeadlineService).scheduleVotePaperDeadlineAction(any(VotePaperDeadlineEvent.class)); - - // TODO : GitHub Actions 에서는 테스트 실패함. 원인 파악 필요 -// verify(firebaseMessagingMediator).sendMulticastMessageByTokens(any()); Optional votePaperOptional = loadVotePaperPort.loadRegisteredVotePaper(dummyService.getDefaultArtistUsername()); assertTrue(votePaperOptional.isPresent()); @@ -343,9 +336,6 @@ void registerVotePaperSuccess() throws Exception { assertThat(readArtistName, hasItems("권진아", "스텔라장 (Stella Jang)")); -// TODO : 수동 테스트가 필요함 -// Thread.sleep(5000); -// verify(sendVoteNotificationPort).notification(any(SendVotePaperEndNotification.class)); } @Transactional @@ -367,10 +357,11 @@ void registerVotePaperChoiceSuccess() throws Exception { FieldDescriptor[] requestDescriptors = { fieldWithPath("id").description("Spotify Music ID").attributes(constraint("NOT BLANK")), fieldWithPath("music").description("노래명").attributes(constraint("NOT BLANK")), + fieldWithPath("music_image").description("노래 이미지 URL").attributes(constraint(EMPTY_STRING)), fieldWithPath("artist_name").description("아티스트명").attributes(constraint("NOT BLANK")), }; - VotePaperCommands.Offer command = new VotePaperCommands.Offer(ulid(), "이별이란 어느 별에 (Feat. 조광일)", "HYNN (박혜원)"); + VotePaperCommands.Offer command = new VotePaperCommands.Offer(ulid(), "이별이란 어느 별에 (Feat. 조광일)", ulid(), "HYNN (박혜원)"); mockMvc.perform( post(Uris.VOTE_PAPER_CHOICE, votePaperId) diff --git a/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java b/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java index a200085f..3e3c8488 100644 --- a/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java +++ b/src/test/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapterTest.java @@ -620,7 +620,7 @@ void testLoadVoteChoiceByUsername() { when(voteChoiceRepository.findByVotePaperIdAndCreatedBy(Mockito.any(), Mockito.any())) .thenReturn(ofResult); when(voteChoiceMapper.registeredVoteChoice(Mockito.any())) - .thenReturn(new RegisteredVoteChoice(1L, 1L, "42", "Music", "Artist Name")); + .thenReturn(new RegisteredVoteChoice(1L, 1L, "42", "Music", "Music Image", "Artist Name")); // Act votePersistenceAdapter.loadVoteChoiceByUsername(1L, "janedoe"); From a7b486c1678cdc46c7962d64a6ac98174a652262 Mon Sep 17 00:00:00 2001 From: habin Date: Sat, 25 May 2024 15:36:25 +0900 Subject: [PATCH 16/16] feat(vote-paper) get MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: ResponseBody Payload에 is_voted(투표 여부) 추가 --- .../vote/adapter/input/rest/VotePaperController.java | 2 +- .../output/persistence/VotePersistenceAdapter.java | 6 +++--- .../port/input/usecase/GetVotePaperUseCase.java | 3 ++- .../v1/vote/application/port/output/LoadVotePort.java | 3 ++- .../vote/application/service/GetVotePaperService.java | 10 ++++++++-- .../vote/application/service/RegisterVoteService.java | 2 +- .../v1/vote/application/service/VoteValueMapper.java | 3 ++- .../tune_fun/v1/vote/domain/value/FullVotePaper.java | 4 +++- .../vote/adapter/input/rest/VotePaperControllerIT.java | 6 ++++-- 9 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperController.java b/src/main/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperController.java index d5b79384..e01ba6a1 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperController.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperController.java @@ -51,7 +51,7 @@ public ResponseEntity> getVotePapers(@RequestP @GetMapping(value = Uris.VOTE_PAPER_ROOT + "/{votePaperId}") public ResponseEntity> getVotePaper(@PathVariable("votePaperId") @NotNull(message = "{vote.paper.id.not_null}") final Long votePaperId, @CurrentUser final User user) { - FullVotePaper votePaper = getVotePaperUseCase.getVotePaper(votePaperId); + FullVotePaper votePaper = getVotePaperUseCase.getVotePaper(votePaperId, user); return responseMapper.ok(MessageCode.SUCCESS, votePaper); } diff --git a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java index e8970c48..69e0a499 100644 --- a/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java +++ b/src/main/java/com/tune_fun/v1/vote/adapter/output/persistence/VotePersistenceAdapter.java @@ -61,12 +61,12 @@ public List loadVoterIdsByVotePaperUuid(final String uuid) { } @Override - public Optional loadVoteByVoterAndVotePaperId(String voter, Long voteChoiceId) { - return voteRepository.findByVoterUsernameAndVotePaperId(voter, voteChoiceId); + public Optional loadVoteByVoterAndVotePaperId(final String voter, final Long votePaperId) { + return voteRepository.findByVoterUsernameAndVotePaperId(voter, votePaperId); } @Override - public void saveVote(Long voteChoiceId, String username) { + public void saveVote(final Long voteChoiceId, final String username) { VoteChoiceJpaEntity voteChoice = voteChoiceRepository.findById(voteChoiceId) .orElseThrow(() -> new IllegalArgumentException("VoteChoice not found")); diff --git a/src/main/java/com/tune_fun/v1/vote/application/port/input/usecase/GetVotePaperUseCase.java b/src/main/java/com/tune_fun/v1/vote/application/port/input/usecase/GetVotePaperUseCase.java index 3f57f91e..1a3d66a4 100644 --- a/src/main/java/com/tune_fun/v1/vote/application/port/input/usecase/GetVotePaperUseCase.java +++ b/src/main/java/com/tune_fun/v1/vote/application/port/input/usecase/GetVotePaperUseCase.java @@ -1,10 +1,11 @@ package com.tune_fun.v1.vote.application.port.input.usecase; import com.tune_fun.v1.vote.domain.value.FullVotePaper; +import org.springframework.security.core.userdetails.User; @FunctionalInterface public interface GetVotePaperUseCase { - FullVotePaper getVotePaper(final Long votePaperId); + FullVotePaper getVotePaper(final Long votePaperId, final User user); } diff --git a/src/main/java/com/tune_fun/v1/vote/application/port/output/LoadVotePort.java b/src/main/java/com/tune_fun/v1/vote/application/port/output/LoadVotePort.java index d3708f56..b94f12ca 100644 --- a/src/main/java/com/tune_fun/v1/vote/application/port/output/LoadVotePort.java +++ b/src/main/java/com/tune_fun/v1/vote/application/port/output/LoadVotePort.java @@ -8,5 +8,6 @@ public interface LoadVotePort { List loadVoterIdsByVotePaperUuid(final String uuid); - Optional loadVoteByVoterAndVotePaperId(final String voter, final Long voteChoiceId); + Optional loadVoteByVoterAndVotePaperId(final String voter, final Long votePaperId); + } diff --git a/src/main/java/com/tune_fun/v1/vote/application/service/GetVotePaperService.java b/src/main/java/com/tune_fun/v1/vote/application/service/GetVotePaperService.java index 0b5eaf2a..ae5a1ba7 100644 --- a/src/main/java/com/tune_fun/v1/vote/application/service/GetVotePaperService.java +++ b/src/main/java/com/tune_fun/v1/vote/application/service/GetVotePaperService.java @@ -5,13 +5,17 @@ import com.tune_fun.v1.vote.application.port.input.usecase.GetVotePaperUseCase; import com.tune_fun.v1.vote.application.port.output.LoadVoteChoicePort; import com.tune_fun.v1.vote.application.port.output.LoadVotePaperPort; +import com.tune_fun.v1.vote.application.port.output.LoadVotePort; import com.tune_fun.v1.vote.domain.value.FullVotePaper; +import com.tune_fun.v1.vote.domain.value.RegisteredVote; import com.tune_fun.v1.vote.domain.value.RegisteredVoteChoice; import com.tune_fun.v1.vote.domain.value.RegisteredVotePaper; import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Optional; import static com.tune_fun.v1.common.response.MessageCode.VOTE_PAPER_NOT_FOUND; @@ -22,15 +26,17 @@ public class GetVotePaperService implements GetVotePaperUseCase { private final LoadVotePaperPort loadVotePaperPort; private final LoadVoteChoicePort loadVoteChoicePort; + private final LoadVotePort loadVotePort; private final VoteValueMapper voteValueMapper; @Override - public FullVotePaper getVotePaper(final Long votePaperId) { + public FullVotePaper getVotePaper(final Long votePaperId, final User user) { RegisteredVotePaper registeredVotePaper = loadVotePaperPort.loadRegisteredVotePaper(votePaperId) .orElseThrow(() -> new CommonApplicationException(VOTE_PAPER_NOT_FOUND)); List registeredVoteChoices = loadVoteChoicePort.loadRegisteredVoteChoice(votePaperId); + Optional registeredVote = loadVotePort.loadVoteByVoterAndVotePaperId(user.getUsername(), votePaperId); - return voteValueMapper.fullVotePaper(registeredVotePaper, registeredVoteChoices); + return voteValueMapper.fullVotePaper(registeredVotePaper, registeredVoteChoices, registeredVote.isPresent()); } } diff --git a/src/main/java/com/tune_fun/v1/vote/application/service/RegisterVoteService.java b/src/main/java/com/tune_fun/v1/vote/application/service/RegisterVoteService.java index c63a0e13..4f00a1ee 100644 --- a/src/main/java/com/tune_fun/v1/vote/application/service/RegisterVoteService.java +++ b/src/main/java/com/tune_fun/v1/vote/application/service/RegisterVoteService.java @@ -21,7 +21,7 @@ public class RegisterVoteService implements RegisterVoteUseCase { private final SaveVotePort saveVotePort; @Override - public void register(Long votePaperId, final Long voteChoiceId, final User user) { + public void register(final Long votePaperId, final Long voteChoiceId, final User user) { if (loadVotePort.loadVoteByVoterAndVotePaperId(user.getUsername(), votePaperId).isPresent()) throw new CommonApplicationException(VOTE_POLICY_ONE_VOTE_PER_USER); diff --git a/src/main/java/com/tune_fun/v1/vote/application/service/VoteValueMapper.java b/src/main/java/com/tune_fun/v1/vote/application/service/VoteValueMapper.java index a83691d8..c150725d 100644 --- a/src/main/java/com/tune_fun/v1/vote/application/service/VoteValueMapper.java +++ b/src/main/java/com/tune_fun/v1/vote/application/service/VoteValueMapper.java @@ -20,12 +20,13 @@ public abstract class VoteValueMapper { @Mapping(target = "content", source = "votePaper.content") @Mapping(target = "option", source = "votePaper.option") @Mapping(target = "videoUrl", source = "votePaper.videoUrl") + @Mapping(target = "isVoted", source = "isVoted") @Mapping(target = "voteStartAt", source = "votePaper.voteStartAt") @Mapping(target = "voteEndAt", source = "votePaper.voteEndAt") @Mapping(target = "deliveryAt", source = "votePaper.deliveryAt") @Mapping(target = "createdAt", source = "votePaper.createdAt") @Mapping(target = "updatedAt", source = "votePaper.updatedAt") @Mapping(target = "choices", source = "voteChoices") - public abstract FullVotePaper fullVotePaper(final RegisteredVotePaper votePaper, final List voteChoices); + public abstract FullVotePaper fullVotePaper(final RegisteredVotePaper votePaper, final List voteChoices, Boolean isVoted); } diff --git a/src/main/java/com/tune_fun/v1/vote/domain/value/FullVotePaper.java b/src/main/java/com/tune_fun/v1/vote/domain/value/FullVotePaper.java index 9b6fdaf5..fcc10478 100644 --- a/src/main/java/com/tune_fun/v1/vote/domain/value/FullVotePaper.java +++ b/src/main/java/com/tune_fun/v1/vote/domain/value/FullVotePaper.java @@ -16,6 +16,8 @@ public record FullVotePaper( VotePaperOption option, String videoUrl, + Boolean isVoted, + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime voteStartAt, @@ -30,7 +32,7 @@ public record FullVotePaper( @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updatedAt, - + Set choices ) implements BasePayload { diff --git a/src/test/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperControllerIT.java b/src/test/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperControllerIT.java index b7619d2e..f839d68a 100644 --- a/src/test/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperControllerIT.java +++ b/src/test/java/com/tune_fun/v1/vote/adapter/input/rest/VotePaperControllerIT.java @@ -172,10 +172,10 @@ void getVotePapersSuccess() throws Exception { @Order(2) @DisplayName("투표 게시물 상세 조회, 성공") void getVotePaperSuccess() throws Exception { - dummyService.initAndLogin(); dummyService.initArtistAndLogin(); - dummyService.initVotePaper(); + + dummyService.initAndLogin(); dummyService.registerVote(); Long votePaperId = dummyService.getDefaultVotePaper().getId(); @@ -192,6 +192,7 @@ void getVotePaperSuccess() throws Exception { fieldWithPath("data.content").description("투표 게시물 내용").attributes(constraint("NOT NULL")), fieldWithPath("data.option").description("투표 종류").attributes(constraint("NOT NULL, allow-add-choices || deny-add-choices")), fieldWithPath("data.video_url").description("투표 게시물 영상 URL").attributes(constraint("NULL or NOT NULL")), + fieldWithPath("data.is_voted").description("투표 여부").attributes(constraint("NOT NULL")), fieldWithPath("data.vote_start_at").description("투표 시작 시간").attributes(constraint("NOT NULL")), fieldWithPath("data.vote_end_at").description("투표 종료 시간").attributes(constraint("NOT NULL")), fieldWithPath("data.delivery_at").description("투표 게시물 영상 제공일").attributes(constraint("NULL or NOT NULL")), @@ -219,6 +220,7 @@ void getVotePaperSuccess() throws Exception { .andExpect(jsonPath("data.content", notNullValue())) .andExpect(jsonPath("data.option", notNullValue())) .andExpect(jsonPath("data.video_url", nullValue())) + .andExpectAll(jsonPath("data.is_voted", notNullValue()), jsonPath("data.is_voted", is(true))) .andExpect(jsonPath("data.vote_start_at", notNullValue())) .andExpect(jsonPath("data.vote_end_at", notNullValue())) .andExpect(jsonPath("data.delivery_at", nullValue()))