From 78b120d3970886ec753234dff961fa84ca441c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Wed, 24 Apr 2024 19:43:22 +0900 Subject: [PATCH 01/41] =?UTF-8?q?refactor(coin):=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=EB=A5=BC=20=EC=97=90=EB=9F=AC=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A3=BC=EC=9E=85=EC=9C=BC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/coin/domain/CoinAccount.java | 8 ++++---- .../repository/CoinAccountRepository.java | 7 ++++--- .../AlreadyAwardedTodayException.java | 10 ---------- .../AlreadyCreateAccountException.java | 10 ---------- .../exception/CancelOthersTradeException.java | 10 ---------- .../CoinAccountNotFoundException.java | 10 ---------- .../exception/CoinNotEnoughException.java | 10 ---------- .../exception/MoneyNotEnoughException.java | 10 ---------- .../exception/PriceNotFoundException.java | 10 ---------- .../exception/RandomInstanceException.java | 10 ---------- .../TradeAlreadyFinishedException.java | 10 ---------- .../exception/TradeNotFoundException.java | 10 ---------- .../domain/coin/service/CoinService.java | 19 ++++++++----------- .../coin/service/NoPeriodException.java | 10 ---------- .../bumawiki/global/util/RandomUtil.java | 5 +++-- 15 files changed, 19 insertions(+), 130 deletions(-) delete mode 100644 src/main/java/com/project/bumawiki/domain/coin/exception/AlreadyAwardedTodayException.java delete mode 100644 src/main/java/com/project/bumawiki/domain/coin/exception/AlreadyCreateAccountException.java delete mode 100644 src/main/java/com/project/bumawiki/domain/coin/exception/CancelOthersTradeException.java delete mode 100644 src/main/java/com/project/bumawiki/domain/coin/exception/CoinAccountNotFoundException.java delete mode 100644 src/main/java/com/project/bumawiki/domain/coin/exception/CoinNotEnoughException.java delete mode 100644 src/main/java/com/project/bumawiki/domain/coin/exception/MoneyNotEnoughException.java delete mode 100644 src/main/java/com/project/bumawiki/domain/coin/exception/PriceNotFoundException.java delete mode 100644 src/main/java/com/project/bumawiki/domain/coin/exception/RandomInstanceException.java delete mode 100644 src/main/java/com/project/bumawiki/domain/coin/exception/TradeAlreadyFinishedException.java delete mode 100644 src/main/java/com/project/bumawiki/domain/coin/exception/TradeNotFoundException.java delete mode 100644 src/main/java/com/project/bumawiki/domain/coin/service/NoPeriodException.java diff --git a/src/main/java/com/project/bumawiki/domain/coin/domain/CoinAccount.java b/src/main/java/com/project/bumawiki/domain/coin/domain/CoinAccount.java index 5ac1f783..6a5feab8 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/domain/CoinAccount.java +++ b/src/main/java/com/project/bumawiki/domain/coin/domain/CoinAccount.java @@ -2,8 +2,8 @@ import java.time.LocalDateTime; -import com.project.bumawiki.domain.coin.exception.CoinNotEnoughException; -import com.project.bumawiki.domain.coin.exception.MoneyNotEnoughException; +import com.project.bumawiki.global.error.exception.BumawikiException; +import com.project.bumawiki.global.error.exception.ErrorCode; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -37,7 +37,7 @@ public CoinAccount(Long userId, Long money) { public void buyCoin(Long coinPrice, Long coinCount) { if (this.money < coinPrice * coinCount) { - throw new MoneyNotEnoughException(); + throw new BumawikiException(ErrorCode.MONEY_NOT_ENOUGH); } this.money -= coinPrice * coinCount; this.coin += coinCount; @@ -45,7 +45,7 @@ public void buyCoin(Long coinPrice, Long coinCount) { public void sellCoin(Long coinPrice, Long coinCount) { if (this.coin < coinCount) { - throw new CoinNotEnoughException(); + throw new BumawikiException(ErrorCode.COIN_NOT_ENOUGH); } this.coin -= coinCount; this.money += coinPrice * coinCount; diff --git a/src/main/java/com/project/bumawiki/domain/coin/domain/repository/CoinAccountRepository.java b/src/main/java/com/project/bumawiki/domain/coin/domain/repository/CoinAccountRepository.java index b8355ad8..89d3191b 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/domain/repository/CoinAccountRepository.java +++ b/src/main/java/com/project/bumawiki/domain/coin/domain/repository/CoinAccountRepository.java @@ -8,7 +8,8 @@ import org.springframework.data.jpa.repository.Query; import com.project.bumawiki.domain.coin.domain.CoinAccount; -import com.project.bumawiki.domain.coin.exception.CoinAccountNotFoundException; +import com.project.bumawiki.global.error.exception.BumawikiException; +import com.project.bumawiki.global.error.exception.ErrorCode; public interface CoinAccountRepository extends JpaRepository { Optional findByUserId(Long userId); @@ -17,12 +18,12 @@ public interface CoinAccountRepository extends JpaRepository default CoinAccount getByUserId(Long userId) { return findByUserId(userId) - .orElseThrow(CoinAccountNotFoundException::new); + .orElseThrow(() -> new BumawikiException(ErrorCode.COIN_ACCOUNT_NOT_FOUND_EXCEPTION)); } default CoinAccount getById(Long id) { return findById(id) - .orElseThrow(CoinAccountNotFoundException::new); + .orElseThrow(() -> new BumawikiException(ErrorCode.COIN_ACCOUNT_NOT_FOUND_EXCEPTION)); } @Query(value = "select c from CoinAccount c where c.coin > 0") diff --git a/src/main/java/com/project/bumawiki/domain/coin/exception/AlreadyAwardedTodayException.java b/src/main/java/com/project/bumawiki/domain/coin/exception/AlreadyAwardedTodayException.java deleted file mode 100644 index f06321b3..00000000 --- a/src/main/java/com/project/bumawiki/domain/coin/exception/AlreadyAwardedTodayException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.project.bumawiki.domain.coin.exception; - -import com.project.bumawiki.global.error.exception.BumawikiException; -import com.project.bumawiki.global.error.exception.ErrorCode; - -public class AlreadyAwardedTodayException extends BumawikiException { - public AlreadyAwardedTodayException() { - super(ErrorCode.ALREADY_AWARDED); - } -} diff --git a/src/main/java/com/project/bumawiki/domain/coin/exception/AlreadyCreateAccountException.java b/src/main/java/com/project/bumawiki/domain/coin/exception/AlreadyCreateAccountException.java deleted file mode 100644 index 741126a3..00000000 --- a/src/main/java/com/project/bumawiki/domain/coin/exception/AlreadyCreateAccountException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.project.bumawiki.domain.coin.exception; - -import com.project.bumawiki.global.error.exception.BumawikiException; -import com.project.bumawiki.global.error.exception.ErrorCode; - -public class AlreadyCreateAccountException extends BumawikiException { - public AlreadyCreateAccountException() { - super(ErrorCode.ALREADY_CREATED); - } -} diff --git a/src/main/java/com/project/bumawiki/domain/coin/exception/CancelOthersTradeException.java b/src/main/java/com/project/bumawiki/domain/coin/exception/CancelOthersTradeException.java deleted file mode 100644 index 90eb83a8..00000000 --- a/src/main/java/com/project/bumawiki/domain/coin/exception/CancelOthersTradeException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.project.bumawiki.domain.coin.exception; - -import com.project.bumawiki.global.error.exception.BumawikiException; -import com.project.bumawiki.global.error.exception.ErrorCode; - -public class CancelOthersTradeException extends BumawikiException { - public CancelOthersTradeException() { - super(ErrorCode.CANCEL_OTHERS_TRADE); - } -} diff --git a/src/main/java/com/project/bumawiki/domain/coin/exception/CoinAccountNotFoundException.java b/src/main/java/com/project/bumawiki/domain/coin/exception/CoinAccountNotFoundException.java deleted file mode 100644 index c5c636e7..00000000 --- a/src/main/java/com/project/bumawiki/domain/coin/exception/CoinAccountNotFoundException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.project.bumawiki.domain.coin.exception; - -import com.project.bumawiki.global.error.exception.BumawikiException; -import com.project.bumawiki.global.error.exception.ErrorCode; - -public class CoinAccountNotFoundException extends BumawikiException { - public CoinAccountNotFoundException() { - super(ErrorCode.COIN_ACCOUNT_NOT_FOUND_EXCEPTION); - } -} diff --git a/src/main/java/com/project/bumawiki/domain/coin/exception/CoinNotEnoughException.java b/src/main/java/com/project/bumawiki/domain/coin/exception/CoinNotEnoughException.java deleted file mode 100644 index 8bab9513..00000000 --- a/src/main/java/com/project/bumawiki/domain/coin/exception/CoinNotEnoughException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.project.bumawiki.domain.coin.exception; - -import com.project.bumawiki.global.error.exception.BumawikiException; -import com.project.bumawiki.global.error.exception.ErrorCode; - -public class CoinNotEnoughException extends BumawikiException { - public CoinNotEnoughException() { - super(ErrorCode.COIN_NOT_ENOUGH); - } -} diff --git a/src/main/java/com/project/bumawiki/domain/coin/exception/MoneyNotEnoughException.java b/src/main/java/com/project/bumawiki/domain/coin/exception/MoneyNotEnoughException.java deleted file mode 100644 index c336df70..00000000 --- a/src/main/java/com/project/bumawiki/domain/coin/exception/MoneyNotEnoughException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.project.bumawiki.domain.coin.exception; - -import com.project.bumawiki.global.error.exception.BumawikiException; -import com.project.bumawiki.global.error.exception.ErrorCode; - -public class MoneyNotEnoughException extends BumawikiException { - public MoneyNotEnoughException() { - super(ErrorCode.MONEY_NOT_ENOUGH); - } -} diff --git a/src/main/java/com/project/bumawiki/domain/coin/exception/PriceNotFoundException.java b/src/main/java/com/project/bumawiki/domain/coin/exception/PriceNotFoundException.java deleted file mode 100644 index bdcaf26f..00000000 --- a/src/main/java/com/project/bumawiki/domain/coin/exception/PriceNotFoundException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.project.bumawiki.domain.coin.exception; - -import com.project.bumawiki.global.error.exception.BumawikiException; -import com.project.bumawiki.global.error.exception.ErrorCode; - -public class PriceNotFoundException extends BumawikiException { - public PriceNotFoundException() { - super(ErrorCode.PRICE_NOT_FOUND); - } -} diff --git a/src/main/java/com/project/bumawiki/domain/coin/exception/RandomInstanceException.java b/src/main/java/com/project/bumawiki/domain/coin/exception/RandomInstanceException.java deleted file mode 100644 index 58f037c3..00000000 --- a/src/main/java/com/project/bumawiki/domain/coin/exception/RandomInstanceException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.project.bumawiki.domain.coin.exception; - -import com.project.bumawiki.global.error.exception.BumawikiException; -import com.project.bumawiki.global.error.exception.ErrorCode; - -public class RandomInstanceException extends BumawikiException { - public RandomInstanceException() { - super(ErrorCode.RANDOM_INSTANCE); - } -} diff --git a/src/main/java/com/project/bumawiki/domain/coin/exception/TradeAlreadyFinishedException.java b/src/main/java/com/project/bumawiki/domain/coin/exception/TradeAlreadyFinishedException.java deleted file mode 100644 index 9a878a91..00000000 --- a/src/main/java/com/project/bumawiki/domain/coin/exception/TradeAlreadyFinishedException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.project.bumawiki.domain.coin.exception; - -import com.project.bumawiki.global.error.exception.BumawikiException; -import com.project.bumawiki.global.error.exception.ErrorCode; - -public class TradeAlreadyFinishedException extends BumawikiException { - public TradeAlreadyFinishedException() { - super(ErrorCode.TRADE_ALREADY_FINISHED); - } -} diff --git a/src/main/java/com/project/bumawiki/domain/coin/exception/TradeNotFoundException.java b/src/main/java/com/project/bumawiki/domain/coin/exception/TradeNotFoundException.java deleted file mode 100644 index a844977d..00000000 --- a/src/main/java/com/project/bumawiki/domain/coin/exception/TradeNotFoundException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.project.bumawiki.domain.coin.exception; - -import com.project.bumawiki.global.error.exception.BumawikiException; -import com.project.bumawiki.global.error.exception.ErrorCode; - -public class TradeNotFoundException extends BumawikiException { - public TradeNotFoundException() { - super(ErrorCode.TRADE_NOT_FOUND); - } -} diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java index 8c689bcd..49e42d53 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java @@ -19,13 +19,10 @@ import com.project.bumawiki.domain.coin.domain.repository.PriceRepository; import com.project.bumawiki.domain.coin.domain.repository.TradeRepository; import com.project.bumawiki.domain.coin.domain.type.TradeStatus; -import com.project.bumawiki.domain.coin.exception.AlreadyAwardedTodayException; -import com.project.bumawiki.domain.coin.exception.AlreadyCreateAccountException; -import com.project.bumawiki.domain.coin.exception.CancelOthersTradeException; -import com.project.bumawiki.domain.coin.exception.TradeAlreadyFinishedException; -import com.project.bumawiki.domain.coin.exception.TradeNotFoundException; import com.project.bumawiki.domain.user.domain.User; import com.project.bumawiki.domain.user.domain.repository.UserRepository; +import com.project.bumawiki.global.error.exception.BumawikiException; +import com.project.bumawiki.global.error.exception.ErrorCode; import lombok.RequiredArgsConstructor; @@ -43,7 +40,7 @@ public CoinAccount createCoinAccount(User user) { boolean alreadyCreatedAccount = coinAccountRepository.existsByUserId(user.getId()); if (alreadyCreatedAccount) { - throw new AlreadyCreateAccountException(); + throw new BumawikiException(ErrorCode.ALREADY_CREATED); } CoinAccount coinAccount = new CoinAccount( user.getId(), @@ -142,21 +139,21 @@ public List getPriceByPeriod(String period) { return priceRepository.findAllAfterStartedTime(threeHoursAgo); } - throw new NoPeriodException(); + throw new BumawikiException(ErrorCode.NO_PERIOD); } public void cancelTrade(Long tradeId, User user) { Trade trade = tradeRepository.findById(tradeId) - .orElseThrow(TradeNotFoundException::new); + .orElseThrow(() -> new BumawikiException(ErrorCode.TRADE_NOT_FOUND)); if (trade.getTradeStatus() != TradeStatus.BUYING && trade.getTradeStatus() != TradeStatus.SELLING) { - throw new TradeAlreadyFinishedException(); + throw new BumawikiException(ErrorCode.TRADE_ALREADY_FINISHED); } CoinAccount byId = coinAccountRepository.getById(trade.getCoinAccountId()); if (!byId.getUserId().equals(user.getId())) { - throw new CancelOthersTradeException(); + throw new BumawikiException(ErrorCode.CANCEL_OTHERS_TRADE); } trade.updateTradeStatus(TradeStatus.CANCELLED); @@ -173,7 +170,7 @@ public Long dailyCheck(User user) { CoinAccount account = coinAccountRepository.getByUserId(user.getId()); if (account.wasRewardedToday()) { - throw new AlreadyAwardedTodayException(); + throw new BumawikiException(ErrorCode.ALREADY_AWARDED); } account.addMoney(randomNumber); account.updateLastRewardedTimeNow(); diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/NoPeriodException.java b/src/main/java/com/project/bumawiki/domain/coin/service/NoPeriodException.java deleted file mode 100644 index fa9bb83c..00000000 --- a/src/main/java/com/project/bumawiki/domain/coin/service/NoPeriodException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.project.bumawiki.domain.coin.service; - -import com.project.bumawiki.global.error.exception.BumawikiException; -import com.project.bumawiki.global.error.exception.ErrorCode; - -public class NoPeriodException extends BumawikiException { - public NoPeriodException() { - super(ErrorCode.NO_PERIOD); - } -} diff --git a/src/main/java/com/project/bumawiki/global/util/RandomUtil.java b/src/main/java/com/project/bumawiki/global/util/RandomUtil.java index 7a36f606..099bbf2a 100644 --- a/src/main/java/com/project/bumawiki/global/util/RandomUtil.java +++ b/src/main/java/com/project/bumawiki/global/util/RandomUtil.java @@ -3,7 +3,8 @@ import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; -import com.project.bumawiki.domain.coin.exception.RandomInstanceException; +import com.project.bumawiki.global.error.exception.BumawikiException; +import com.project.bumawiki.global.error.exception.ErrorCode; public class RandomUtil { public static SecureRandom getRandomInstance() { @@ -11,7 +12,7 @@ public static SecureRandom getRandomInstance() { try { random = SecureRandom.getInstanceStrong(); } catch (NoSuchAlgorithmException e) { - throw new RandomInstanceException(); + throw new BumawikiException(ErrorCode.RANDOM_INSTANCE); } return random; } From cc10fc08056c2dc759f19bb23e4f9dcfaf99bfde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Wed, 24 Apr 2024 19:46:38 +0900 Subject: [PATCH 02/41] =?UTF-8?q?refactor(coin):=20controller=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=EB=A5=BC=20presentation=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{controller => presentation}/CoinController.java | 12 ++++++------ .../dto/CoinAccountResponse.java | 2 +- .../dto/PriceResponse.java | 2 +- .../dto/RankingResponse.java | 2 +- .../dto/TradeRequest.java | 2 +- .../dto/TradeResponse.java | 2 +- .../bumawiki/domain/coin/service/CoinService.java | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) rename src/main/java/com/project/bumawiki/domain/coin/{controller => presentation}/CoinController.java (88%) rename src/main/java/com/project/bumawiki/domain/coin/{controller => presentation}/dto/CoinAccountResponse.java (87%) rename src/main/java/com/project/bumawiki/domain/coin/{controller => presentation}/dto/PriceResponse.java (83%) rename src/main/java/com/project/bumawiki/domain/coin/{controller => presentation}/dto/RankingResponse.java (89%) rename src/main/java/com/project/bumawiki/domain/coin/{controller => presentation}/dto/TradeRequest.java (86%) rename src/main/java/com/project/bumawiki/domain/coin/{controller => presentation}/dto/TradeResponse.java (90%) diff --git a/src/main/java/com/project/bumawiki/domain/coin/controller/CoinController.java b/src/main/java/com/project/bumawiki/domain/coin/presentation/CoinController.java similarity index 88% rename from src/main/java/com/project/bumawiki/domain/coin/controller/CoinController.java rename to src/main/java/com/project/bumawiki/domain/coin/presentation/CoinController.java index 43146cd3..2735bbdc 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/controller/CoinController.java +++ b/src/main/java/com/project/bumawiki/domain/coin/presentation/CoinController.java @@ -1,4 +1,4 @@ -package com.project.bumawiki.domain.coin.controller; +package com.project.bumawiki.domain.coin.presentation; import java.util.List; @@ -17,11 +17,11 @@ import com.project.bumawiki.domain.auth.annotation.LoginRequired; import com.project.bumawiki.domain.auth.service.QueryAuthService; -import com.project.bumawiki.domain.coin.controller.dto.CoinAccountResponse; -import com.project.bumawiki.domain.coin.controller.dto.PriceResponse; -import com.project.bumawiki.domain.coin.controller.dto.RankingResponse; -import com.project.bumawiki.domain.coin.controller.dto.TradeRequest; -import com.project.bumawiki.domain.coin.controller.dto.TradeResponse; +import com.project.bumawiki.domain.coin.presentation.dto.CoinAccountResponse; +import com.project.bumawiki.domain.coin.presentation.dto.PriceResponse; +import com.project.bumawiki.domain.coin.presentation.dto.RankingResponse; +import com.project.bumawiki.domain.coin.presentation.dto.TradeRequest; +import com.project.bumawiki.domain.coin.presentation.dto.TradeResponse; import com.project.bumawiki.domain.coin.service.CoinService; import jakarta.validation.Valid; diff --git a/src/main/java/com/project/bumawiki/domain/coin/controller/dto/CoinAccountResponse.java b/src/main/java/com/project/bumawiki/domain/coin/presentation/dto/CoinAccountResponse.java similarity index 87% rename from src/main/java/com/project/bumawiki/domain/coin/controller/dto/CoinAccountResponse.java rename to src/main/java/com/project/bumawiki/domain/coin/presentation/dto/CoinAccountResponse.java index 7c80e9e7..2c0c3f24 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/controller/dto/CoinAccountResponse.java +++ b/src/main/java/com/project/bumawiki/domain/coin/presentation/dto/CoinAccountResponse.java @@ -1,4 +1,4 @@ -package com.project.bumawiki.domain.coin.controller.dto; +package com.project.bumawiki.domain.coin.presentation.dto; import java.time.LocalDateTime; diff --git a/src/main/java/com/project/bumawiki/domain/coin/controller/dto/PriceResponse.java b/src/main/java/com/project/bumawiki/domain/coin/presentation/dto/PriceResponse.java similarity index 83% rename from src/main/java/com/project/bumawiki/domain/coin/controller/dto/PriceResponse.java rename to src/main/java/com/project/bumawiki/domain/coin/presentation/dto/PriceResponse.java index f509fe90..aa53487a 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/controller/dto/PriceResponse.java +++ b/src/main/java/com/project/bumawiki/domain/coin/presentation/dto/PriceResponse.java @@ -1,4 +1,4 @@ -package com.project.bumawiki.domain.coin.controller.dto; +package com.project.bumawiki.domain.coin.presentation.dto; import java.time.LocalDateTime; diff --git a/src/main/java/com/project/bumawiki/domain/coin/controller/dto/RankingResponse.java b/src/main/java/com/project/bumawiki/domain/coin/presentation/dto/RankingResponse.java similarity index 89% rename from src/main/java/com/project/bumawiki/domain/coin/controller/dto/RankingResponse.java rename to src/main/java/com/project/bumawiki/domain/coin/presentation/dto/RankingResponse.java index 3c1a107c..1f34c079 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/controller/dto/RankingResponse.java +++ b/src/main/java/com/project/bumawiki/domain/coin/presentation/dto/RankingResponse.java @@ -1,4 +1,4 @@ -package com.project.bumawiki.domain.coin.controller.dto; +package com.project.bumawiki.domain.coin.presentation.dto; import com.project.bumawiki.domain.coin.domain.CoinAccount; import com.project.bumawiki.domain.user.domain.User; diff --git a/src/main/java/com/project/bumawiki/domain/coin/controller/dto/TradeRequest.java b/src/main/java/com/project/bumawiki/domain/coin/presentation/dto/TradeRequest.java similarity index 86% rename from src/main/java/com/project/bumawiki/domain/coin/controller/dto/TradeRequest.java rename to src/main/java/com/project/bumawiki/domain/coin/presentation/dto/TradeRequest.java index ba922ab5..8987eda4 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/controller/dto/TradeRequest.java +++ b/src/main/java/com/project/bumawiki/domain/coin/presentation/dto/TradeRequest.java @@ -1,4 +1,4 @@ -package com.project.bumawiki.domain.coin.controller.dto; +package com.project.bumawiki.domain.coin.presentation.dto; import com.project.bumawiki.domain.coin.domain.TradeWithoutTradeStatusAndCoinAccountId; diff --git a/src/main/java/com/project/bumawiki/domain/coin/controller/dto/TradeResponse.java b/src/main/java/com/project/bumawiki/domain/coin/presentation/dto/TradeResponse.java similarity index 90% rename from src/main/java/com/project/bumawiki/domain/coin/controller/dto/TradeResponse.java rename to src/main/java/com/project/bumawiki/domain/coin/presentation/dto/TradeResponse.java index ec61e31b..8d31a996 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/controller/dto/TradeResponse.java +++ b/src/main/java/com/project/bumawiki/domain/coin/presentation/dto/TradeResponse.java @@ -1,4 +1,4 @@ -package com.project.bumawiki.domain.coin.controller.dto; +package com.project.bumawiki.domain.coin.presentation.dto; import java.time.LocalDateTime; diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java index 49e42d53..e451b1b7 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java @@ -10,7 +10,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.project.bumawiki.domain.coin.controller.dto.RankingResponse; import com.project.bumawiki.domain.coin.domain.CoinAccount; import com.project.bumawiki.domain.coin.domain.Price; import com.project.bumawiki.domain.coin.domain.Trade; @@ -19,6 +18,7 @@ import com.project.bumawiki.domain.coin.domain.repository.PriceRepository; import com.project.bumawiki.domain.coin.domain.repository.TradeRepository; import com.project.bumawiki.domain.coin.domain.type.TradeStatus; +import com.project.bumawiki.domain.coin.presentation.dto.RankingResponse; import com.project.bumawiki.domain.user.domain.User; import com.project.bumawiki.domain.user.domain.repository.UserRepository; import com.project.bumawiki.global.error.exception.BumawikiException; From d766810f6aa43bbc887869208f44db73f6add4d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Wed, 24 Apr 2024 19:56:57 +0900 Subject: [PATCH 03/41] =?UTF-8?q?refactor(coin):=20findCoinAccountByUser?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bumawiki/domain/coin/presentation/CoinController.java | 2 +- .../com/project/bumawiki/domain/coin/service/CoinService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/project/bumawiki/domain/coin/presentation/CoinController.java b/src/main/java/com/project/bumawiki/domain/coin/presentation/CoinController.java index 2735bbdc..1e867b9a 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/presentation/CoinController.java +++ b/src/main/java/com/project/bumawiki/domain/coin/presentation/CoinController.java @@ -46,7 +46,7 @@ public CoinAccountResponse createCoinAccount() { @LoginRequired public CoinAccountResponse findOwnAccount() { return CoinAccountResponse.from( - coinService.findByUser(queryAuthService.getCurrentUser()) + coinService.findCoinAccountByUser(queryAuthService.getCurrentUser()) ); } diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java index e451b1b7..9d088f13 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java @@ -51,7 +51,7 @@ public CoinAccount createCoinAccount(User user) { } @Transactional(readOnly = true) - public CoinAccount findByUser(User currentUserWithLogin) { + public CoinAccount findCoinAccountByUser(User currentUserWithLogin) { return coinAccountRepository.getByUserId(currentUserWithLogin.getId()); } From 105ae39b7178ffa2c4369f3888fb3faa66747cc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Wed, 24 Apr 2024 20:33:22 +0900 Subject: [PATCH 04/41] =?UTF-8?q?refactor(coin):=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=96=B4=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../implementation/CoinAccountCreator.java | 18 +++++ .../implementation/CoinAccountReader.java | 37 ++++++++++ .../coin/implementation/PriceReader.java | 29 ++++++++ .../coin/implementation/TradeCreator.java | 17 +++++ .../coin/implementation/TradeReader.java | 26 +++++++ .../domain/coin/service/CoinService.java | 68 ++++++++++--------- 6 files changed, 163 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountCreator.java create mode 100644 src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountReader.java create mode 100644 src/main/java/com/project/bumawiki/domain/coin/implementation/PriceReader.java create mode 100644 src/main/java/com/project/bumawiki/domain/coin/implementation/TradeCreator.java create mode 100644 src/main/java/com/project/bumawiki/domain/coin/implementation/TradeReader.java diff --git a/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountCreator.java b/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountCreator.java new file mode 100644 index 00000000..74b54072 --- /dev/null +++ b/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountCreator.java @@ -0,0 +1,18 @@ +package com.project.bumawiki.domain.coin.implementation; + +import com.project.bumawiki.domain.coin.domain.CoinAccount; +import com.project.bumawiki.domain.coin.domain.repository.CoinAccountRepository; +import com.project.bumawiki.global.annotation.Implementation; + +import lombok.RequiredArgsConstructor; + +@Implementation +@RequiredArgsConstructor +public class CoinAccountCreator { + + private final CoinAccountRepository coinAccountRepository; + + public CoinAccount create(CoinAccount coinAccount) { + return coinAccountRepository.save(coinAccount); + } +} diff --git a/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountReader.java b/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountReader.java new file mode 100644 index 00000000..b59ab349 --- /dev/null +++ b/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountReader.java @@ -0,0 +1,37 @@ +package com.project.bumawiki.domain.coin.implementation; + +import java.util.List; + +import org.springframework.data.domain.Pageable; + +import com.project.bumawiki.domain.coin.domain.CoinAccount; +import com.project.bumawiki.domain.coin.domain.repository.CoinAccountRepository; +import com.project.bumawiki.global.annotation.Implementation; +import com.project.bumawiki.global.error.exception.BumawikiException; +import com.project.bumawiki.global.error.exception.ErrorCode; + +import lombok.RequiredArgsConstructor; + +@Implementation +@RequiredArgsConstructor +public class CoinAccountReader { + + private final CoinAccountRepository coinAccountRepository; + + public boolean existsByUserId(Long userId) { + return coinAccountRepository.existsByUserId(userId); + } + + public CoinAccount getById(Long id) { + return coinAccountRepository.findById(id) + .orElseThrow(() -> new BumawikiException(ErrorCode.COIN_ACCOUNT_NOT_FOUND_EXCEPTION)); + } + + public CoinAccount getByUserId(Long userId) { + return coinAccountRepository.getByUserId(userId); + } + + public List getRanking(Pageable pageable, Long price) { + return coinAccountRepository.getRanking(pageable, price); + } +} diff --git a/src/main/java/com/project/bumawiki/domain/coin/implementation/PriceReader.java b/src/main/java/com/project/bumawiki/domain/coin/implementation/PriceReader.java new file mode 100644 index 00000000..8deda909 --- /dev/null +++ b/src/main/java/com/project/bumawiki/domain/coin/implementation/PriceReader.java @@ -0,0 +1,29 @@ +package com.project.bumawiki.domain.coin.implementation; + +import java.time.LocalDateTime; +import java.util.List; + +import com.project.bumawiki.domain.coin.domain.Price; +import com.project.bumawiki.domain.coin.domain.repository.PriceRepository; +import com.project.bumawiki.global.annotation.Implementation; + +import lombok.RequiredArgsConstructor; + +@Implementation +@RequiredArgsConstructor +public class PriceReader { + + private final PriceRepository priceRepository; + + public Price getRecentPrice() { + return priceRepository.getRecentPrice(); + } + + public List findAllByOrderByStartedTime() { + return priceRepository.findAllByOrderByStartedTime(); + } + + public List findAllAfterStartedTime(LocalDateTime localDateTime) { + return priceRepository.findAllAfterStartedTime(localDateTime); + } +} diff --git a/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeCreator.java b/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeCreator.java new file mode 100644 index 00000000..7cfd923b --- /dev/null +++ b/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeCreator.java @@ -0,0 +1,17 @@ +package com.project.bumawiki.domain.coin.implementation; + +import com.project.bumawiki.domain.coin.domain.Trade; +import com.project.bumawiki.domain.coin.domain.repository.TradeRepository; +import com.project.bumawiki.global.annotation.Implementation; + +import lombok.RequiredArgsConstructor; + +@Implementation +@RequiredArgsConstructor +public class TradeCreator { + private final TradeRepository tradeRepository; + + public Trade create(Trade trade) { + return tradeRepository.save(trade); + } +} diff --git a/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeReader.java b/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeReader.java new file mode 100644 index 00000000..8ce7fb05 --- /dev/null +++ b/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeReader.java @@ -0,0 +1,26 @@ +package com.project.bumawiki.domain.coin.implementation; + +import java.util.List; + +import com.project.bumawiki.domain.coin.domain.Trade; +import com.project.bumawiki.domain.coin.domain.repository.TradeRepository; +import com.project.bumawiki.global.annotation.Implementation; +import com.project.bumawiki.global.error.exception.BumawikiException; +import com.project.bumawiki.global.error.exception.ErrorCode; + +import lombok.RequiredArgsConstructor; + +@Implementation +@RequiredArgsConstructor +public class TradeReader { + private final TradeRepository tradeRepository; + + public Trade findById(Long tradeId) { + return tradeRepository.findById(tradeId) + .orElseThrow(() -> new BumawikiException(ErrorCode.TRADE_NOT_FOUND)); + } + + public List findAllByCoinAccountIdOrderByTradedTimeDesc(Long accountId) { + return tradeRepository.findAllByCoinAccountIdOrderByTradedTimeDesc(accountId); + } +} diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java index 9d088f13..122710e7 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java @@ -14,13 +14,15 @@ import com.project.bumawiki.domain.coin.domain.Price; import com.project.bumawiki.domain.coin.domain.Trade; import com.project.bumawiki.domain.coin.domain.TradeWithoutTradeStatusAndCoinAccountId; -import com.project.bumawiki.domain.coin.domain.repository.CoinAccountRepository; -import com.project.bumawiki.domain.coin.domain.repository.PriceRepository; -import com.project.bumawiki.domain.coin.domain.repository.TradeRepository; import com.project.bumawiki.domain.coin.domain.type.TradeStatus; +import com.project.bumawiki.domain.coin.implementation.CoinAccountCreator; +import com.project.bumawiki.domain.coin.implementation.CoinAccountReader; +import com.project.bumawiki.domain.coin.implementation.PriceReader; +import com.project.bumawiki.domain.coin.implementation.TradeCreator; +import com.project.bumawiki.domain.coin.implementation.TradeReader; import com.project.bumawiki.domain.coin.presentation.dto.RankingResponse; import com.project.bumawiki.domain.user.domain.User; -import com.project.bumawiki.domain.user.domain.repository.UserRepository; +import com.project.bumawiki.domain.user.implementation.UserReader; import com.project.bumawiki.global.error.exception.BumawikiException; import com.project.bumawiki.global.error.exception.ErrorCode; @@ -31,33 +33,36 @@ @RequiredArgsConstructor public class CoinService { public static final Long FIRST_MONEY = 10000000L; - private final CoinAccountRepository coinAccountRepository; - private final PriceRepository priceRepository; - private final TradeRepository tradeRepository; - private final UserRepository userRepository; + private final CoinAccountReader coinAccountReader; + private final CoinAccountCreator coinAccountCreator; + private final PriceReader priceReader; + private final TradeReader tradeReader; + private final TradeCreator tradeCreator; + private final UserReader userReader; public CoinAccount createCoinAccount(User user) { - boolean alreadyCreatedAccount = coinAccountRepository.existsByUserId(user.getId()); + boolean alreadyCreatedAccount = coinAccountReader.existsByUserId(user.getId()); if (alreadyCreatedAccount) { throw new BumawikiException(ErrorCode.ALREADY_CREATED); } + CoinAccount coinAccount = new CoinAccount( user.getId(), FIRST_MONEY ); - return coinAccountRepository.save(coinAccount); + return coinAccountCreator.create(coinAccount); } @Transactional(readOnly = true) public CoinAccount findCoinAccountByUser(User currentUserWithLogin) { - return coinAccountRepository.getByUserId(currentUserWithLogin.getId()); + return coinAccountReader.getByUserId(currentUserWithLogin.getId()); } public Trade buyCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User user) { - CoinAccount coinAccount = coinAccountRepository.getByUserId(user.getId()); - Price nowPrice = priceRepository.getRecentPrice(); + CoinAccount coinAccount = coinAccountReader.getByUserId(user.getId()); + Price nowPrice = getRecentPrice(); Trade trade = coinData.toTrade(coinAccount); @@ -67,13 +72,13 @@ public Trade buyCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User user buyLater(trade); } - return tradeRepository.save(trade); + return tradeCreator.create(trade); } @Transactional public Trade sellCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User user) { - CoinAccount coinAccount = coinAccountRepository.getByUserId(user.getId()); - Price nowPrice = priceRepository.getRecentPrice(); + CoinAccount coinAccount = coinAccountReader.getByUserId(user.getId()); + Price nowPrice = getRecentPrice(); Trade trade = coinData.toTrade(coinAccount); @@ -83,7 +88,7 @@ public Trade sellCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User use sellLater(trade); } - return tradeRepository.save(trade); + return tradeCreator.create(trade); } private void sellLater(Trade trade) { @@ -106,51 +111,50 @@ private void buyNow(Trade trade, CoinAccount coinAccount) { @Transactional(readOnly = true) public List getTrades(Long accountId) { - return tradeRepository.findAllByCoinAccountIdOrderByTradedTimeDesc(accountId); + return tradeReader.findAllByCoinAccountIdOrderByTradedTimeDesc(accountId); } public List getPriceByPeriod(String period) { if (period.equals("full")) { - return priceRepository.findAllByOrderByStartedTime(); + return priceReader.findAllByOrderByStartedTime(); } if (period.equals("halfMonth")) { LocalDateTime twoWeeksAgo = LocalDateTime.now().minusWeeks(2); - return priceRepository.findAllAfterStartedTime(twoWeeksAgo); + return priceReader.findAllAfterStartedTime(twoWeeksAgo); } if (period.equals("week")) { LocalDateTime oneWeekAgo = LocalDateTime.now().minusWeeks(1); - return priceRepository.findAllAfterStartedTime(oneWeekAgo); + return priceReader.findAllAfterStartedTime(oneWeekAgo); } if (period.equals("day")) { LocalDateTime oneDayAgo = LocalDateTime.now().minusDays(1); - return priceRepository.findAllAfterStartedTime(oneDayAgo); + return priceReader.findAllAfterStartedTime(oneDayAgo); } if (period.equals("halfDay")) { LocalDateTime halfDayAgo = LocalDateTime.now().minusHours(12); - return priceRepository.findAllAfterStartedTime(halfDayAgo); + return priceReader.findAllAfterStartedTime(halfDayAgo); } if (period.equals("threeHours")) { LocalDateTime threeHoursAgo = LocalDateTime.now().minusHours(3); - return priceRepository.findAllAfterStartedTime(threeHoursAgo); + return priceReader.findAllAfterStartedTime(threeHoursAgo); } throw new BumawikiException(ErrorCode.NO_PERIOD); } public void cancelTrade(Long tradeId, User user) { - Trade trade = tradeRepository.findById(tradeId) - .orElseThrow(() -> new BumawikiException(ErrorCode.TRADE_NOT_FOUND)); + Trade trade = tradeReader.findById(tradeId); if (trade.getTradeStatus() != TradeStatus.BUYING && trade.getTradeStatus() != TradeStatus.SELLING) { throw new BumawikiException(ErrorCode.TRADE_ALREADY_FINISHED); } - CoinAccount byId = coinAccountRepository.getById(trade.getCoinAccountId()); + CoinAccount byId = coinAccountReader.getById(trade.getCoinAccountId()); if (!byId.getUserId().equals(user.getId())) { throw new BumawikiException(ErrorCode.CANCEL_OTHERS_TRADE); @@ -167,7 +171,7 @@ public Long dailyCheck(User user) { Long randomNumber = (random.nextLong(max - min + 1) + min); randomNumber -= randomNumber % 10000; - CoinAccount account = coinAccountRepository.getByUserId(user.getId()); + CoinAccount account = coinAccountReader.getByUserId(user.getId()); if (account.wasRewardedToday()) { throw new BumawikiException(ErrorCode.ALREADY_AWARDED); @@ -179,18 +183,18 @@ public Long dailyCheck(User user) { } public List getRanking(Pageable pageable) { - Price recentPrice = priceRepository.getRecentPrice(); - return coinAccountRepository.getRanking(pageable, recentPrice.getPrice()) + Price recentPrice = getRecentPrice(); + return coinAccountReader.getRanking(pageable, recentPrice.getPrice()) .stream() .map(ranking -> new RankingResponse( ranking, recentPrice.getPrice(), - userRepository.getById(ranking.getUserId()) + userReader.getById(ranking.getUserId()) ) ).toList(); } public Price getRecentPrice() { - return priceRepository.getRecentPrice(); + return priceReader.getRecentPrice(); } } From 0030a7863f5a35f09542e1b89a9a721bed6db2ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Wed, 24 Apr 2024 20:36:33 +0900 Subject: [PATCH 05/41] refactor(coin): if -> switch-case --- .../domain/coin/service/CoinService.java | 51 +++++++++---------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java index 122710e7..9695dbf6 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java @@ -115,33 +115,30 @@ public List getTrades(Long accountId) { } public List getPriceByPeriod(String period) { - if (period.equals("full")) { - return priceReader.findAllByOrderByStartedTime(); - } - - if (period.equals("halfMonth")) { - LocalDateTime twoWeeksAgo = LocalDateTime.now().minusWeeks(2); - return priceReader.findAllAfterStartedTime(twoWeeksAgo); - } - - if (period.equals("week")) { - LocalDateTime oneWeekAgo = LocalDateTime.now().minusWeeks(1); - return priceReader.findAllAfterStartedTime(oneWeekAgo); - } - - if (period.equals("day")) { - LocalDateTime oneDayAgo = LocalDateTime.now().minusDays(1); - return priceReader.findAllAfterStartedTime(oneDayAgo); - } - - if (period.equals("halfDay")) { - LocalDateTime halfDayAgo = LocalDateTime.now().minusHours(12); - return priceReader.findAllAfterStartedTime(halfDayAgo); - } - - if (period.equals("threeHours")) { - LocalDateTime threeHoursAgo = LocalDateTime.now().minusHours(3); - return priceReader.findAllAfterStartedTime(threeHoursAgo); + switch (period) { + case "full" -> { + return priceReader.findAllByOrderByStartedTime(); + } + case "halfMonth" -> { + LocalDateTime twoWeeksAgo = LocalDateTime.now().minusWeeks(2); + return priceReader.findAllAfterStartedTime(twoWeeksAgo); + } + case "week" -> { + LocalDateTime oneWeekAgo = LocalDateTime.now().minusWeeks(1); + return priceReader.findAllAfterStartedTime(oneWeekAgo); + } + case "day" -> { + LocalDateTime oneDayAgo = LocalDateTime.now().minusDays(1); + return priceReader.findAllAfterStartedTime(oneDayAgo); + } + case "halfDay" -> { + LocalDateTime halfDayAgo = LocalDateTime.now().minusHours(12); + return priceReader.findAllAfterStartedTime(halfDayAgo); + } + case "threeHours" -> { + LocalDateTime threeHoursAgo = LocalDateTime.now().minusHours(3); + return priceReader.findAllAfterStartedTime(threeHoursAgo); + } } throw new BumawikiException(ErrorCode.NO_PERIOD); From 9e0806c170b8ed83989c0dad8128f1759fa29c87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Wed, 24 Apr 2024 21:46:45 +0900 Subject: [PATCH 06/41] =?UTF-8?q?refactor(coin):=20=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=EB=A5=BC=20Validator=EC=97=90=EC=84=9C=20=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../implementation/CoinAccountValidator.java | 27 +++++++++++++++++++ .../coin/implementation/TradeValidator.java | 25 +++++++++++++++++ .../domain/coin/service/CoinService.java | 23 +++++++--------- 3 files changed, 61 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountValidator.java create mode 100644 src/main/java/com/project/bumawiki/domain/coin/implementation/TradeValidator.java diff --git a/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountValidator.java b/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountValidator.java new file mode 100644 index 00000000..4abeec35 --- /dev/null +++ b/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountValidator.java @@ -0,0 +1,27 @@ +package com.project.bumawiki.domain.coin.implementation; + +import com.project.bumawiki.domain.coin.domain.CoinAccount; +import com.project.bumawiki.global.annotation.Implementation; +import com.project.bumawiki.global.error.exception.BumawikiException; +import com.project.bumawiki.global.error.exception.ErrorCode; + +import lombok.RequiredArgsConstructor; + +@Implementation +@RequiredArgsConstructor +public class CoinAccountValidator { + + private final CoinAccountReader coinAccountReader; + + public void checkAlreadyCreatedAccount(Long userId) { + if (coinAccountReader.existsByUserId(userId)) { + throw new BumawikiException(ErrorCode.ALREADY_CREATED); + } + } + + public void checkAlreadyRewardedToday(CoinAccount account) { + if (account.wasRewardedToday()) { + throw new BumawikiException(ErrorCode.ALREADY_AWARDED); + } + } +} diff --git a/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeValidator.java b/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeValidator.java new file mode 100644 index 00000000..35af957f --- /dev/null +++ b/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeValidator.java @@ -0,0 +1,25 @@ +package com.project.bumawiki.domain.coin.implementation; + +import com.project.bumawiki.domain.coin.domain.type.TradeStatus; +import com.project.bumawiki.global.annotation.Implementation; +import com.project.bumawiki.global.error.exception.BumawikiException; +import com.project.bumawiki.global.error.exception.ErrorCode; + +import lombok.RequiredArgsConstructor; + +@Implementation +@RequiredArgsConstructor +public class TradeValidator { + + public void checkTradeStatusIsNotBuyingAndSelling(TradeStatus tradeStatus) { + if (tradeStatus != TradeStatus.BUYING && tradeStatus != TradeStatus.SELLING) { + throw new BumawikiException(ErrorCode.TRADE_ALREADY_FINISHED); + } + } + + public void checkTradeOwnership(Long coinAccountUserId, Long userId) { + if (!coinAccountUserId.equals(userId)) { + throw new BumawikiException(ErrorCode.CANCEL_OTHERS_TRADE); + } + } +} diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java index 9695dbf6..3de889ae 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java @@ -17,9 +17,11 @@ import com.project.bumawiki.domain.coin.domain.type.TradeStatus; import com.project.bumawiki.domain.coin.implementation.CoinAccountCreator; import com.project.bumawiki.domain.coin.implementation.CoinAccountReader; +import com.project.bumawiki.domain.coin.implementation.CoinAccountValidator; import com.project.bumawiki.domain.coin.implementation.PriceReader; import com.project.bumawiki.domain.coin.implementation.TradeCreator; import com.project.bumawiki.domain.coin.implementation.TradeReader; +import com.project.bumawiki.domain.coin.implementation.TradeValidator; import com.project.bumawiki.domain.coin.presentation.dto.RankingResponse; import com.project.bumawiki.domain.user.domain.User; import com.project.bumawiki.domain.user.implementation.UserReader; @@ -35,17 +37,15 @@ public class CoinService { public static final Long FIRST_MONEY = 10000000L; private final CoinAccountReader coinAccountReader; private final CoinAccountCreator coinAccountCreator; + private final CoinAccountValidator coinAccountValidator; private final PriceReader priceReader; private final TradeReader tradeReader; private final TradeCreator tradeCreator; private final UserReader userReader; + private final TradeValidator tradeValidator; public CoinAccount createCoinAccount(User user) { - boolean alreadyCreatedAccount = coinAccountReader.existsByUserId(user.getId()); - - if (alreadyCreatedAccount) { - throw new BumawikiException(ErrorCode.ALREADY_CREATED); - } + coinAccountValidator.checkAlreadyCreatedAccount(user.getId()); CoinAccount coinAccount = new CoinAccount( user.getId(), @@ -147,15 +147,11 @@ public List getPriceByPeriod(String period) { public void cancelTrade(Long tradeId, User user) { Trade trade = tradeReader.findById(tradeId); - if (trade.getTradeStatus() != TradeStatus.BUYING && trade.getTradeStatus() != TradeStatus.SELLING) { - throw new BumawikiException(ErrorCode.TRADE_ALREADY_FINISHED); - } + tradeValidator.checkTradeStatusIsNotBuyingAndSelling(trade.getTradeStatus()); CoinAccount byId = coinAccountReader.getById(trade.getCoinAccountId()); - if (!byId.getUserId().equals(user.getId())) { - throw new BumawikiException(ErrorCode.CANCEL_OTHERS_TRADE); - } + tradeValidator.checkTradeOwnership(byId.getUserId(), user.getId()); trade.updateTradeStatus(TradeStatus.CANCELLED); } @@ -170,9 +166,8 @@ public Long dailyCheck(User user) { CoinAccount account = coinAccountReader.getByUserId(user.getId()); - if (account.wasRewardedToday()) { - throw new BumawikiException(ErrorCode.ALREADY_AWARDED); - } + coinAccountValidator.checkAlreadyRewardedToday(account); + account.addMoney(randomNumber); account.updateLastRewardedTimeNow(); From 87c23b72a0b69f3af65909dcba2196ed4fd82c78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Wed, 24 Apr 2024 22:00:37 +0900 Subject: [PATCH 07/41] refactor(coin): Long -> long --- .../com/project/bumawiki/domain/coin/service/CoinService.java | 2 +- .../project/bumawiki/domain/coin/service/PriceScheduler.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java index 3de889ae..ea6ff2c3 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java @@ -161,7 +161,7 @@ public Long dailyCheck(User user) { long max = 200000; SecureRandom random = getRandomInstance(); - Long randomNumber = (random.nextLong(max - min + 1) + min); + long randomNumber = (random.nextLong(max - min + 1) + min); randomNumber -= randomNumber % 10000; CoinAccount account = coinAccountReader.getByUserId(user.getId()); diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java b/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java index f2abccd6..0d7ff4d3 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java @@ -31,9 +31,11 @@ void changePrice() { Price recentPrice = priceRepository.getRecentPrice(); Long max = recentPrice.getPrice() + CHANGE_MONEY_RANGE; Long min = Math.max(recentPrice.getPrice() - CHANGE_MONEY_RANGE, 0L); + long max = recentPrice.getPrice() + CHANGE_MONEY_RANGE; + long min = Math.max(recentPrice.getPrice() - CHANGE_MONEY_RANGE, 0L); SecureRandom random = getRandomInstance(); - Long randomPrice = random.nextLong(max - min + 1L) + min; + long randomPrice = random.nextLong(max - min + 1L) + min; Price newPrice; if (randomPrice == 0) { restartCoin(); From 1e594bd4434142d45fdcb04b5f1aac96f632628d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Wed, 24 Apr 2024 22:06:49 +0900 Subject: [PATCH 08/41] =?UTF-8?q?refactor(coin):=20PriceScheduler=EB=A5=BC?= =?UTF-8?q?=20=EB=B9=84=EC=A6=88=EB=8B=88=EC=8A=A4=EC=99=80=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EB=A0=88=EC=9D=B4=EC=96=B4=EB=A1=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../implementation/CoinAccountReader.java | 4 ++ .../coin/implementation/PriceCreator.java | 17 ++++++++ .../coin/implementation/TradeReader.java | 5 +++ .../domain/coin/service/PriceScheduler.java | 42 ++++++++++--------- 4 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/project/bumawiki/domain/coin/implementation/PriceCreator.java diff --git a/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountReader.java b/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountReader.java index b59ab349..d8d2ab00 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountReader.java +++ b/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountReader.java @@ -34,4 +34,8 @@ public CoinAccount getByUserId(Long userId) { public List getRanking(Pageable pageable, Long price) { return coinAccountRepository.getRanking(pageable, price); } + + public List findAllByCoinGreaterThan0() { + return coinAccountRepository.findAllByCoinGreaterThan0(); + } } diff --git a/src/main/java/com/project/bumawiki/domain/coin/implementation/PriceCreator.java b/src/main/java/com/project/bumawiki/domain/coin/implementation/PriceCreator.java new file mode 100644 index 00000000..a228016a --- /dev/null +++ b/src/main/java/com/project/bumawiki/domain/coin/implementation/PriceCreator.java @@ -0,0 +1,17 @@ +package com.project.bumawiki.domain.coin.implementation; + +import com.project.bumawiki.domain.coin.domain.Price; +import com.project.bumawiki.domain.coin.domain.repository.PriceRepository; +import com.project.bumawiki.global.annotation.Implementation; + +import lombok.RequiredArgsConstructor; + +@Implementation +@RequiredArgsConstructor +public class PriceCreator { + private final PriceRepository priceRepository; + + public Price create(Price price) { + return priceRepository.save(price); + } +} diff --git a/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeReader.java b/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeReader.java index 8ce7fb05..dd3daeb3 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeReader.java +++ b/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeReader.java @@ -4,6 +4,7 @@ import com.project.bumawiki.domain.coin.domain.Trade; import com.project.bumawiki.domain.coin.domain.repository.TradeRepository; +import com.project.bumawiki.domain.coin.domain.type.TradeStatus; import com.project.bumawiki.global.annotation.Implementation; import com.project.bumawiki.global.error.exception.BumawikiException; import com.project.bumawiki.global.error.exception.ErrorCode; @@ -23,4 +24,8 @@ public Trade findById(Long tradeId) { public List findAllByCoinAccountIdOrderByTradedTimeDesc(Long accountId) { return tradeRepository.findAllByCoinAccountIdOrderByTradedTimeDesc(accountId); } + + public List findAllByTradeStatus(TradeStatus tradeStatus) { + return tradeRepository.findAllByTradeStatus(tradeStatus); + } } diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java b/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java index 0d7ff4d3..ea2e833a 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java @@ -11,10 +11,13 @@ import com.project.bumawiki.domain.coin.domain.CoinAccount; import com.project.bumawiki.domain.coin.domain.Price; import com.project.bumawiki.domain.coin.domain.Trade; -import com.project.bumawiki.domain.coin.domain.repository.CoinAccountRepository; -import com.project.bumawiki.domain.coin.domain.repository.PriceRepository; -import com.project.bumawiki.domain.coin.domain.repository.TradeRepository; import com.project.bumawiki.domain.coin.domain.type.TradeStatus; +import com.project.bumawiki.domain.coin.implementation.CoinAccountCreator; +import com.project.bumawiki.domain.coin.implementation.CoinAccountReader; +import com.project.bumawiki.domain.coin.implementation.PriceCreator; +import com.project.bumawiki.domain.coin.implementation.PriceReader; +import com.project.bumawiki.domain.coin.implementation.TradeCreator; +import com.project.bumawiki.domain.coin.implementation.TradeReader; import lombok.RequiredArgsConstructor; @@ -22,15 +25,16 @@ @RequiredArgsConstructor public class PriceScheduler { private static final Long CHANGE_MONEY_RANGE = 200000L; - private final PriceRepository priceRepository; - private final TradeRepository tradeRepository; - private final CoinAccountRepository coinAccountRepository; + private final PriceReader priceReader; + private final PriceCreator priceCreator; + private final TradeReader tradeReader; + private final TradeCreator tradeCreator; + private final CoinAccountReader coinAccountReader; + private final CoinAccountCreator coinAccountCreator; @Scheduled(fixedRate = 180000) void changePrice() { - Price recentPrice = priceRepository.getRecentPrice(); - Long max = recentPrice.getPrice() + CHANGE_MONEY_RANGE; - Long min = Math.max(recentPrice.getPrice() - CHANGE_MONEY_RANGE, 0L); + Price recentPrice = priceReader.getRecentPrice(); long max = recentPrice.getPrice() + CHANGE_MONEY_RANGE; long min = Math.max(recentPrice.getPrice() - CHANGE_MONEY_RANGE, 0L); @@ -44,13 +48,13 @@ void changePrice() { newPrice = new Price(randomPrice - randomPrice % 100); } - priceRepository.save(newPrice); + priceCreator.create(newPrice); processBuyingTrade(newPrice); processSellingTrade(newPrice); } private void restartCoin() { - List coinAccounts = coinAccountRepository.findAllByCoinGreaterThan0(); + List coinAccounts = coinAccountReader.findAllByCoinGreaterThan0(); for (CoinAccount coinAccount : coinAccounts) { Trade trade = new Trade( @@ -62,35 +66,35 @@ private void restartCoin() { ); coinAccount.sellCoin(0L, coinAccount.getCoin()); - tradeRepository.save(trade); - coinAccountRepository.save(coinAccount); + tradeCreator.create(trade); + coinAccountCreator.create(coinAccount); } } private void processSellingTrade(Price newPrice) { - List sellingTrades = tradeRepository.findAllByTradeStatus(TradeStatus.SELLING); + List sellingTrades = tradeReader.findAllByTradeStatus(TradeStatus.SELLING); for (Trade sellingTrade : sellingTrades) { if (sellingTrade.getCoinPrice() <= newPrice.getPrice()) { - CoinAccount tradingAccount = coinAccountRepository.getById(sellingTrade.getCoinAccountId()); + CoinAccount tradingAccount = coinAccountReader.getById(sellingTrade.getCoinAccountId()); tradingAccount.sellCoin(sellingTrade.getCoinPrice(), sellingTrade.getCoinCount()); sellingTrade.updateTradeStatus(TradeStatus.SOLD); - tradeRepository.save(sellingTrade); + tradeCreator.create(sellingTrade); } } } private void processBuyingTrade(Price newPrice) { - List buyingTrades = tradeRepository.findAllByTradeStatus(TradeStatus.BUYING); + List buyingTrades = tradeReader.findAllByTradeStatus(TradeStatus.BUYING); for (Trade buyingTrade : buyingTrades) { if (buyingTrade.getCoinPrice() >= newPrice.getPrice()) { - CoinAccount tradingAccount = coinAccountRepository.getById(buyingTrade.getCoinAccountId()); + CoinAccount tradingAccount = coinAccountReader.getById(buyingTrade.getCoinAccountId()); tradingAccount.buyCoin(buyingTrade.getCoinPrice(), buyingTrade.getCoinCount()); buyingTrade.updateTradeStatus(TradeStatus.BOUGHT); - tradeRepository.save(buyingTrade); + tradeCreator.create(buyingTrade); } } } From 4e770e3a6afd62e7a1b5e7687b7b54e4e2e2edc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Wed, 24 Apr 2024 22:22:18 +0900 Subject: [PATCH 09/41] =?UTF-8?q?refactor(coin):=20Command=EC=99=80=20Quer?= =?UTF-8?q?y=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/presentation/CoinController.java | 107 ------------------ .../presentation/CommandCoinController.java | 66 +++++++++++ .../presentation/QueryCoinController.java | 63 +++++++++++ ...inService.java => CommandCoinService.java} | 71 +----------- .../domain/coin/service/QueryCoinService.java | 87 ++++++++++++++ 5 files changed, 219 insertions(+), 175 deletions(-) delete mode 100644 src/main/java/com/project/bumawiki/domain/coin/presentation/CoinController.java create mode 100644 src/main/java/com/project/bumawiki/domain/coin/presentation/CommandCoinController.java create mode 100644 src/main/java/com/project/bumawiki/domain/coin/presentation/QueryCoinController.java rename src/main/java/com/project/bumawiki/domain/coin/service/{CoinService.java => CommandCoinService.java} (63%) create mode 100644 src/main/java/com/project/bumawiki/domain/coin/service/QueryCoinService.java diff --git a/src/main/java/com/project/bumawiki/domain/coin/presentation/CoinController.java b/src/main/java/com/project/bumawiki/domain/coin/presentation/CoinController.java deleted file mode 100644 index 1e867b9a..00000000 --- a/src/main/java/com/project/bumawiki/domain/coin/presentation/CoinController.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.project.bumawiki.domain.coin.presentation; - -import java.util.List; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.web.PageableDefault; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; - -import com.project.bumawiki.domain.auth.annotation.LoginRequired; -import com.project.bumawiki.domain.auth.service.QueryAuthService; -import com.project.bumawiki.domain.coin.presentation.dto.CoinAccountResponse; -import com.project.bumawiki.domain.coin.presentation.dto.PriceResponse; -import com.project.bumawiki.domain.coin.presentation.dto.RankingResponse; -import com.project.bumawiki.domain.coin.presentation.dto.TradeRequest; -import com.project.bumawiki.domain.coin.presentation.dto.TradeResponse; -import com.project.bumawiki.domain.coin.service.CoinService; - -import jakarta.validation.Valid; -import lombok.RequiredArgsConstructor; - -@RestController -@RequiredArgsConstructor -@RequestMapping("/api/coins") -public class CoinController { - private final CoinService coinService; - private final QueryAuthService queryAuthService; - - @PostMapping - @LoginRequired - public CoinAccountResponse createCoinAccount() { - return CoinAccountResponse.from( - coinService.createCoinAccount(queryAuthService.getCurrentUser()) - ); - } - - @GetMapping("/mine") - @LoginRequired - public CoinAccountResponse findOwnAccount() { - return CoinAccountResponse.from( - coinService.findCoinAccountByUser(queryAuthService.getCurrentUser()) - ); - } - - @PostMapping("/buy") - @LoginRequired - public TradeResponse buyCoin(@Valid @RequestBody TradeRequest tradeRequest) { - return TradeResponse.from( - coinService.buyCoin(tradeRequest.toEntity(), queryAuthService.getCurrentUser()) - ); - } - - @PostMapping("/sell") - @LoginRequired - public TradeResponse sellCoin(@Valid @RequestBody TradeRequest tradeRequest) { - return TradeResponse.from( - coinService.sellCoin(tradeRequest.toEntity(), queryAuthService.getCurrentUser()) - ); - } - - @GetMapping("/trades/{accountId}") - public List getTrades(@PathVariable Long accountId) { - return coinService.getTrades(accountId) - .stream() - .map(TradeResponse::from) - .toList(); - } - - @GetMapping("/graph") - public List getGraph(@RequestParam String period) { - return coinService.getPriceByPeriod(period) - .stream() - .map(PriceResponse::from) - .toList(); - } - - @DeleteMapping("/{tradeId}") - @LoginRequired - @ResponseStatus(HttpStatus.ACCEPTED) - public void cancelTrade(@PathVariable Long tradeId) { - coinService.cancelTrade(tradeId, queryAuthService.getCurrentUser()); - } - - @PostMapping("/daily") - @LoginRequired - public Long dailyCheck() { - return coinService.dailyCheck(queryAuthService.getCurrentUser()); - } - - @GetMapping("/ranking") - public List getRanking(@PageableDefault Pageable pageable) { - return coinService.getRanking(pageable); - } - - @GetMapping("/prices") - public PriceResponse getRecentPrice() { - return PriceResponse.from(coinService.getRecentPrice()); - } -} diff --git a/src/main/java/com/project/bumawiki/domain/coin/presentation/CommandCoinController.java b/src/main/java/com/project/bumawiki/domain/coin/presentation/CommandCoinController.java new file mode 100644 index 00000000..602a76be --- /dev/null +++ b/src/main/java/com/project/bumawiki/domain/coin/presentation/CommandCoinController.java @@ -0,0 +1,66 @@ +package com.project.bumawiki.domain.coin.presentation; + +import org.springframework.http.HttpStatus; +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.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.project.bumawiki.domain.auth.annotation.LoginRequired; +import com.project.bumawiki.domain.auth.service.QueryAuthService; +import com.project.bumawiki.domain.coin.presentation.dto.CoinAccountResponse; +import com.project.bumawiki.domain.coin.presentation.dto.TradeRequest; +import com.project.bumawiki.domain.coin.presentation.dto.TradeResponse; +import com.project.bumawiki.domain.coin.service.CommandCoinService; + +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/coins") +public class CommandCoinController { + + private final CommandCoinService commandCoinService; + private final QueryAuthService queryAuthService; + + @PostMapping + @LoginRequired + public CoinAccountResponse createCoinAccount() { + return CoinAccountResponse.from( + commandCoinService.createCoinAccount(queryAuthService.getCurrentUser()) + ); + } + + @PostMapping("/buy") + @LoginRequired + public TradeResponse buyCoin(@Valid @RequestBody TradeRequest tradeRequest) { + return TradeResponse.from( + commandCoinService.buyCoin(tradeRequest.toEntity(), queryAuthService.getCurrentUser()) + ); + } + + @PostMapping("/sell") + @LoginRequired + public TradeResponse sellCoin(@Valid @RequestBody TradeRequest tradeRequest) { + return TradeResponse.from( + commandCoinService.sellCoin(tradeRequest.toEntity(), queryAuthService.getCurrentUser()) + ); + } + + @PostMapping("/daily") + @LoginRequired + public Long dailyCheck() { + return commandCoinService.dailyCheck(queryAuthService.getCurrentUser()); + } + + @DeleteMapping("/{tradeId}") + @LoginRequired + @ResponseStatus(HttpStatus.ACCEPTED) + public void cancelTrade(@PathVariable Long tradeId) { + commandCoinService.cancelTrade(tradeId, queryAuthService.getCurrentUser()); + } +} diff --git a/src/main/java/com/project/bumawiki/domain/coin/presentation/QueryCoinController.java b/src/main/java/com/project/bumawiki/domain/coin/presentation/QueryCoinController.java new file mode 100644 index 00000000..9f2868e8 --- /dev/null +++ b/src/main/java/com/project/bumawiki/domain/coin/presentation/QueryCoinController.java @@ -0,0 +1,63 @@ +package com.project.bumawiki.domain.coin.presentation; + +import java.util.List; + +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.project.bumawiki.domain.auth.annotation.LoginRequired; +import com.project.bumawiki.domain.auth.service.QueryAuthService; +import com.project.bumawiki.domain.coin.presentation.dto.CoinAccountResponse; +import com.project.bumawiki.domain.coin.presentation.dto.PriceResponse; +import com.project.bumawiki.domain.coin.presentation.dto.RankingResponse; +import com.project.bumawiki.domain.coin.presentation.dto.TradeResponse; +import com.project.bumawiki.domain.coin.service.QueryCoinService; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/coins") +public class QueryCoinController { + private final QueryCoinService queryCoinService; + private final QueryAuthService queryAuthService; + + @GetMapping("/mine") + @LoginRequired + public CoinAccountResponse findOwnAccount() { + return CoinAccountResponse.from( + queryCoinService.findCoinAccountByUser(queryAuthService.getCurrentUser()) + ); + } + + @GetMapping("/trades/{accountId}") + public List getTrades(@PathVariable Long accountId) { + return queryCoinService.getTrades(accountId) + .stream() + .map(TradeResponse::from) + .toList(); + } + + @GetMapping("/graph") + public List getGraph(@RequestParam String period) { + return queryCoinService.getPriceByPeriod(period) + .stream() + .map(PriceResponse::from) + .toList(); + } + + @GetMapping("/ranking") + public List getRanking(@PageableDefault Pageable pageable) { + return queryCoinService.getRanking(pageable); + } + + @GetMapping("/prices") + public PriceResponse getRecentPrice() { + return PriceResponse.from(queryCoinService.getRecentPrice()); + } +} diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java similarity index 63% rename from src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java rename to src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java index ea6ff2c3..b3612043 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/CoinService.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java @@ -3,10 +3,7 @@ import static com.project.bumawiki.global.util.RandomUtil.*; import java.security.SecureRandom; -import java.time.LocalDateTime; -import java.util.List; -import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -22,18 +19,14 @@ import com.project.bumawiki.domain.coin.implementation.TradeCreator; import com.project.bumawiki.domain.coin.implementation.TradeReader; import com.project.bumawiki.domain.coin.implementation.TradeValidator; -import com.project.bumawiki.domain.coin.presentation.dto.RankingResponse; import com.project.bumawiki.domain.user.domain.User; -import com.project.bumawiki.domain.user.implementation.UserReader; -import com.project.bumawiki.global.error.exception.BumawikiException; -import com.project.bumawiki.global.error.exception.ErrorCode; import lombok.RequiredArgsConstructor; @Service @Transactional @RequiredArgsConstructor -public class CoinService { +public class CommandCoinService { public static final Long FIRST_MONEY = 10000000L; private final CoinAccountReader coinAccountReader; private final CoinAccountCreator coinAccountCreator; @@ -41,7 +34,6 @@ public class CoinService { private final PriceReader priceReader; private final TradeReader tradeReader; private final TradeCreator tradeCreator; - private final UserReader userReader; private final TradeValidator tradeValidator; public CoinAccount createCoinAccount(User user) { @@ -55,14 +47,9 @@ public CoinAccount createCoinAccount(User user) { return coinAccountCreator.create(coinAccount); } - @Transactional(readOnly = true) - public CoinAccount findCoinAccountByUser(User currentUserWithLogin) { - return coinAccountReader.getByUserId(currentUserWithLogin.getId()); - } - public Trade buyCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User user) { CoinAccount coinAccount = coinAccountReader.getByUserId(user.getId()); - Price nowPrice = getRecentPrice(); + Price nowPrice = priceReader.getRecentPrice(); Trade trade = coinData.toTrade(coinAccount); @@ -75,10 +62,9 @@ public Trade buyCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User user return tradeCreator.create(trade); } - @Transactional public Trade sellCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User user) { CoinAccount coinAccount = coinAccountReader.getByUserId(user.getId()); - Price nowPrice = getRecentPrice(); + Price nowPrice = priceReader.getRecentPrice(); Trade trade = coinData.toTrade(coinAccount); @@ -109,41 +95,6 @@ private void buyNow(Trade trade, CoinAccount coinAccount) { trade.updateTradeStatus(TradeStatus.BOUGHT); } - @Transactional(readOnly = true) - public List getTrades(Long accountId) { - return tradeReader.findAllByCoinAccountIdOrderByTradedTimeDesc(accountId); - } - - public List getPriceByPeriod(String period) { - switch (period) { - case "full" -> { - return priceReader.findAllByOrderByStartedTime(); - } - case "halfMonth" -> { - LocalDateTime twoWeeksAgo = LocalDateTime.now().minusWeeks(2); - return priceReader.findAllAfterStartedTime(twoWeeksAgo); - } - case "week" -> { - LocalDateTime oneWeekAgo = LocalDateTime.now().minusWeeks(1); - return priceReader.findAllAfterStartedTime(oneWeekAgo); - } - case "day" -> { - LocalDateTime oneDayAgo = LocalDateTime.now().minusDays(1); - return priceReader.findAllAfterStartedTime(oneDayAgo); - } - case "halfDay" -> { - LocalDateTime halfDayAgo = LocalDateTime.now().minusHours(12); - return priceReader.findAllAfterStartedTime(halfDayAgo); - } - case "threeHours" -> { - LocalDateTime threeHoursAgo = LocalDateTime.now().minusHours(3); - return priceReader.findAllAfterStartedTime(threeHoursAgo); - } - } - - throw new BumawikiException(ErrorCode.NO_PERIOD); - } - public void cancelTrade(Long tradeId, User user) { Trade trade = tradeReader.findById(tradeId); @@ -173,20 +124,4 @@ public Long dailyCheck(User user) { return randomNumber; } - - public List getRanking(Pageable pageable) { - Price recentPrice = getRecentPrice(); - return coinAccountReader.getRanking(pageable, recentPrice.getPrice()) - .stream() - .map(ranking -> new RankingResponse( - ranking, - recentPrice.getPrice(), - userReader.getById(ranking.getUserId()) - ) - ).toList(); - } - - public Price getRecentPrice() { - return priceReader.getRecentPrice(); - } } diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/QueryCoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/QueryCoinService.java new file mode 100644 index 00000000..9b6f0fc6 --- /dev/null +++ b/src/main/java/com/project/bumawiki/domain/coin/service/QueryCoinService.java @@ -0,0 +1,87 @@ +package com.project.bumawiki.domain.coin.service; + +import java.time.LocalDateTime; +import java.util.List; + +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.project.bumawiki.domain.coin.domain.CoinAccount; +import com.project.bumawiki.domain.coin.domain.Price; +import com.project.bumawiki.domain.coin.domain.Trade; +import com.project.bumawiki.domain.coin.implementation.CoinAccountReader; +import com.project.bumawiki.domain.coin.implementation.PriceReader; +import com.project.bumawiki.domain.coin.implementation.TradeReader; +import com.project.bumawiki.domain.coin.presentation.dto.RankingResponse; +import com.project.bumawiki.domain.user.domain.User; +import com.project.bumawiki.domain.user.implementation.UserReader; +import com.project.bumawiki.global.error.exception.BumawikiException; +import com.project.bumawiki.global.error.exception.ErrorCode; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class QueryCoinService { + + private final CoinAccountReader coinAccountReader; + private final TradeReader tradeReader; + private final PriceReader priceReader; + private final UserReader userReader; + + public CoinAccount findCoinAccountByUser(User currentUserWithLogin) { + return coinAccountReader.getByUserId(currentUserWithLogin.getId()); + } + + public List getTrades(Long accountId) { + return tradeReader.findAllByCoinAccountIdOrderByTradedTimeDesc(accountId); + } + + public List getPriceByPeriod(String period) { + switch (period) { + case "full" -> { + return priceReader.findAllByOrderByStartedTime(); + } + case "halfMonth" -> { + LocalDateTime twoWeeksAgo = LocalDateTime.now().minusWeeks(2); + return priceReader.findAllAfterStartedTime(twoWeeksAgo); + } + case "week" -> { + LocalDateTime oneWeekAgo = LocalDateTime.now().minusWeeks(1); + return priceReader.findAllAfterStartedTime(oneWeekAgo); + } + case "day" -> { + LocalDateTime oneDayAgo = LocalDateTime.now().minusDays(1); + return priceReader.findAllAfterStartedTime(oneDayAgo); + } + case "halfDay" -> { + LocalDateTime halfDayAgo = LocalDateTime.now().minusHours(12); + return priceReader.findAllAfterStartedTime(halfDayAgo); + } + case "threeHours" -> { + LocalDateTime threeHoursAgo = LocalDateTime.now().minusHours(3); + return priceReader.findAllAfterStartedTime(threeHoursAgo); + } + } + + throw new BumawikiException(ErrorCode.NO_PERIOD); + } + + public List getRanking(Pageable pageable) { + Price recentPrice = getRecentPrice(); + return coinAccountReader.getRanking(pageable, recentPrice.getPrice()) + .stream() + .map(ranking -> new RankingResponse( + ranking, + recentPrice.getPrice(), + userReader.getById(ranking.getUserId()) + ) + ).toList(); + } + + public Price getRecentPrice() { + return priceReader.getRecentPrice(); + } +} From 9402dd46f67aaee23a2e6f3a2ceee44cf28eb5c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Thu, 25 Apr 2024 08:48:58 +0900 Subject: [PATCH 10/41] =?UTF-8?q?test(coin):=20=EC=BD=94=EC=9D=B8=5F?= =?UTF-8?q?=EA=B3=84=EC=A0=95=5F=EC=83=9D=EC=84=B1=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinServiceTest.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java new file mode 100644 index 00000000..ec43a649 --- /dev/null +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -0,0 +1,43 @@ +package com.project.bumawiki.domain.coin.service; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.RepeatedTest; +import org.springframework.beans.factory.annotation.Autowired; + +import com.project.bumawiki.domain.coin.domain.repository.CoinAccountRepository; +import com.project.bumawiki.domain.user.domain.User; +import com.project.bumawiki.domain.user.domain.repository.UserRepository; +import com.project.bumawiki.global.service.FixtureGenerator; +import com.project.bumawiki.global.service.ServiceTest; + +class CommandCoinServiceTest extends ServiceTest { + @Autowired + private CommandCoinService commandCoinService; + + @Autowired + private UserRepository userRepository; + + @Autowired + private CoinAccountRepository coinAccountRepository; + + @RepeatedTest(REPEAT_COUNT) + void 코인_계정_생성하기() { + // given + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + // when + commandCoinService.createCoinAccount(user); + + // then + assertAll( + () -> { + assertThat(coinAccountRepository.findByUserId(user.getId()).isPresent()).isEqualTo(true); + assertThat(coinAccountRepository.findByUserId(user.getId()).get().getUserId()).isEqualTo(user.getId()); + } + ); + } +} From eba71b7cd777ca0acba320ea445d384a76be17be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Thu, 25 Apr 2024 17:57:48 +0900 Subject: [PATCH 11/41] =?UTF-8?q?refactor(coin):=20TradeWithoutTradeStatus?= =?UTF-8?q?AndCoinAccountId=EB=A5=BC=20record=EC=97=90=EC=84=9C=20class?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...adeWithoutTradeStatusAndCoinAccountId.java | 19 +++++++++++++++---- .../coin/service/CommandCoinService.java | 4 ++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java b/src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java index 8eaacac5..5f706ea9 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java +++ b/src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java @@ -2,10 +2,21 @@ import com.project.bumawiki.domain.coin.domain.type.TradeStatus; -public record TradeWithoutTradeStatusAndCoinAccountId( - Long coinPrice, - Long coinCount -) { +import jakarta.validation.constraints.Positive; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class TradeWithoutTradeStatusAndCoinAccountId { + @Positive + private Long coinPrice; + + @Positive + private Long coinCount; + public Trade toTrade(CoinAccount coinAccount) { return new Trade( coinPrice, diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java index b3612043..034c97eb 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java @@ -53,7 +53,7 @@ public Trade buyCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User user Trade trade = coinData.toTrade(coinAccount); - if (coinData.coinPrice() >= nowPrice.getPrice()) { + if (coinData.getCoinPrice() >= nowPrice.getPrice()) { buyNow(trade, coinAccount); } else { buyLater(trade); @@ -68,7 +68,7 @@ public Trade sellCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User use Trade trade = coinData.toTrade(coinAccount); - if (coinData.coinPrice() <= nowPrice.getPrice()) { + if (coinData.getCoinPrice() <= nowPrice.getPrice()) { sellNow(trade, coinAccount); } else { sellLater(trade); From c6ce56ff6d9afb86e913593c5432201f7be38e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Thu, 25 Apr 2024 17:58:10 +0900 Subject: [PATCH 12/41] =?UTF-8?q?test(coin):=20=EC=BD=94=EC=9D=B8=5F?= =?UTF-8?q?=EA=B5=AC=EB=A7=A4=ED=95=98=EA=B8=B0=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinServiceTest.java | 41 +++++++++++++++++++ .../global/service/FixtureGenerator.java | 5 +++ 2 files changed, 46 insertions(+) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index ec43a649..c282724d 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -3,10 +3,15 @@ import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; +import java.util.Objects; + import org.junit.jupiter.api.RepeatedTest; import org.springframework.beans.factory.annotation.Autowired; +import com.project.bumawiki.domain.coin.domain.CoinAccount; +import com.project.bumawiki.domain.coin.domain.TradeWithoutTradeStatusAndCoinAccountId; import com.project.bumawiki.domain.coin.domain.repository.CoinAccountRepository; +import com.project.bumawiki.domain.coin.domain.repository.TradeRepository; import com.project.bumawiki.domain.user.domain.User; import com.project.bumawiki.domain.user.domain.repository.UserRepository; import com.project.bumawiki.global.service.FixtureGenerator; @@ -22,6 +27,9 @@ class CommandCoinServiceTest extends ServiceTest { @Autowired private CoinAccountRepository coinAccountRepository; + @Autowired + private TradeRepository tradeRepository; + @RepeatedTest(REPEAT_COUNT) void 코인_계정_생성하기() { // given @@ -40,4 +48,37 @@ class CommandCoinServiceTest extends ServiceTest { } ); } + + @RepeatedTest(REPEAT_COUNT) + void 코인_구매하기() { + // given + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + TradeWithoutTradeStatusAndCoinAccountId coinData = FixtureGenerator + .getRandomTradeWithoutTradeStatusAndCoinAccountId(); + + CoinAccount coinAccount = new CoinAccount( + user.getId(), + CommandCoinService.FIRST_MONEY + ); + + coinAccountRepository.save(coinAccount); + + // when + commandCoinService.buyCoin(coinData, user); + + // then + Long accountId = Objects.requireNonNull(coinAccountRepository.findByUserId(user.getId()).orElse(null)).getId(); + assertAll( + () -> assertThat(tradeRepository.findAll().size()).isEqualTo(1), + () -> assertThat( + tradeRepository.findAllByCoinAccountIdOrderByTradedTimeDesc(accountId).get(0).getCoinPrice() + ).isEqualTo(coinData.getCoinPrice()), + () -> assertThat( + tradeRepository.findAllByCoinAccountIdOrderByTradedTimeDesc(accountId).get(0).getCoinCount() + ).isEqualTo(coinData.getCoinCount()) + ); + } } diff --git a/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java b/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java index 1ea5e7bd..04312b99 100644 --- a/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java +++ b/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java @@ -7,6 +7,7 @@ import net.jqwik.api.Arbitraries; import net.jqwik.api.arbitraries.StringArbitrary; +import com.project.bumawiki.domain.coin.domain.TradeWithoutTradeStatusAndCoinAccountId; import com.project.bumawiki.domain.docs.domain.Docs; import com.project.bumawiki.domain.docs.domain.VersionDocs; import com.project.bumawiki.domain.thumbsup.domain.ThumbsUp; @@ -56,4 +57,8 @@ public static StringArbitrary getDefaultStringBuilder() { .ascii() .ofMinLength(1); } + + public static TradeWithoutTradeStatusAndCoinAccountId getRandomTradeWithoutTradeStatusAndCoinAccountId() { + return fixtureGenerator.giveMeOne(TradeWithoutTradeStatusAndCoinAccountId.class); + } } From a019c67465c8292c32d2b1571be49c2050bcde09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Thu, 25 Apr 2024 20:01:26 +0900 Subject: [PATCH 13/41] =?UTF-8?q?test(coin):=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinService.java | 18 +++++++++--------- .../coin/service/CommandCoinServiceTest.java | 5 +++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java index 034c97eb..90ccb7db 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java @@ -62,6 +62,15 @@ public Trade buyCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User user return tradeCreator.create(trade); } + private void buyLater(Trade trade) { + trade.updateTradeStatus(TradeStatus.BUYING); + } + + private void buyNow(Trade trade, CoinAccount coinAccount) { + coinAccount.buyCoin(trade.getCoinPrice(), trade.getCoinCount()); + trade.updateTradeStatus(TradeStatus.BOUGHT); + } + public Trade sellCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User user) { CoinAccount coinAccount = coinAccountReader.getByUserId(user.getId()); Price nowPrice = priceReader.getRecentPrice(); @@ -86,15 +95,6 @@ private void sellNow(Trade trade, CoinAccount coinAccount) { trade.updateTradeStatus(TradeStatus.SOLD); } - private void buyLater(Trade trade) { - trade.updateTradeStatus(TradeStatus.BUYING); - } - - private void buyNow(Trade trade, CoinAccount coinAccount) { - coinAccount.buyCoin(trade.getCoinPrice(), trade.getCoinCount()); - trade.updateTradeStatus(TradeStatus.BOUGHT); - } - public void cancelTrade(Long tradeId, User user) { Trade trade = tradeReader.findById(tradeId); diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index c282724d..d02789a1 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -81,4 +81,9 @@ class CommandCoinServiceTest extends ServiceTest { ).isEqualTo(coinData.getCoinCount()) ); } + + @RepeatedTest(REPEAT_COUNT) + void 코인_판매하기() { + + } } From ec36792ddd4503ff715e99d73f6698341963559c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Fri, 26 Apr 2024 08:46:46 +0900 Subject: [PATCH 14/41] =?UTF-8?q?refactor(coin):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...adeWithoutTradeStatusAndCoinAccountId.java | 3 + .../coin/service/CommandCoinServiceTest.java | 86 ++++++++++++------- .../global/service/FixtureGenerator.java | 9 +- 3 files changed, 64 insertions(+), 34 deletions(-) diff --git a/src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java b/src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java index 5f706ea9..eae511f7 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java +++ b/src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java @@ -2,6 +2,7 @@ import com.project.bumawiki.domain.coin.domain.type.TradeStatus; +import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Positive; import lombok.AllArgsConstructor; import lombok.Getter; @@ -11,9 +12,11 @@ @NoArgsConstructor @AllArgsConstructor public class TradeWithoutTradeStatusAndCoinAccountId { + @NotNull @Positive private Long coinPrice; + @NotNull @Positive private Long coinCount; diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index d02789a1..81228015 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -1,16 +1,18 @@ package com.project.bumawiki.domain.coin.service; +import static com.navercorp.fixturemonkey.api.experimental.JavaGetterMethodPropertySelector.*; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; -import java.util.Objects; - +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.RepeatedTest; import org.springframework.beans.factory.annotation.Autowired; import com.project.bumawiki.domain.coin.domain.CoinAccount; +import com.project.bumawiki.domain.coin.domain.Price; import com.project.bumawiki.domain.coin.domain.TradeWithoutTradeStatusAndCoinAccountId; import com.project.bumawiki.domain.coin.domain.repository.CoinAccountRepository; +import com.project.bumawiki.domain.coin.domain.repository.PriceRepository; import com.project.bumawiki.domain.coin.domain.repository.TradeRepository; import com.project.bumawiki.domain.user.domain.User; import com.project.bumawiki.domain.user.domain.repository.UserRepository; @@ -30,6 +32,9 @@ class CommandCoinServiceTest extends ServiceTest { @Autowired private TradeRepository tradeRepository; + @Autowired + private PriceRepository priceRepository; + @RepeatedTest(REPEAT_COUNT) void 코인_계정_생성하기() { // given @@ -49,37 +54,54 @@ class CommandCoinServiceTest extends ServiceTest { ); } - @RepeatedTest(REPEAT_COUNT) - void 코인_구매하기() { - // given - User user = FixtureGenerator.getDefaultUserBuilder().sample(); - - userRepository.save(user); - - TradeWithoutTradeStatusAndCoinAccountId coinData = FixtureGenerator - .getRandomTradeWithoutTradeStatusAndCoinAccountId(); - - CoinAccount coinAccount = new CoinAccount( - user.getId(), - CommandCoinService.FIRST_MONEY - ); - - coinAccountRepository.save(coinAccount); - - // when - commandCoinService.buyCoin(coinData, user); + @Nested + class 코인_구매하기 { + @Nested + class 구매_가격이_시세보다_높거나_같을_때 { + @RepeatedTest(REPEAT_COUNT) + void 잔고가_충분할_경우() { + // given + Price price = priceRepository.getRecentPrice(); + System.out.println(price.getPrice()); + + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + TradeWithoutTradeStatusAndCoinAccountId coinData = FixtureGenerator + .getRandomTradeWithoutTradeStatusAndCoinAccountId() + .setPostCondition( + javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinPrice), + Long.class, + it -> it < CommandCoinService.FIRST_MONEY / 100L + ) + .set(javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinCount), price.getPrice()/100000L) + .sample(); + + CoinAccount coinAccount = new CoinAccount( + user.getId(), + CommandCoinService.FIRST_MONEY + ); + + coinAccountRepository.save(coinAccount); + + // when + commandCoinService.buyCoin(coinData, user); + + // then + assertAll( + () -> assertThat(tradeRepository.findAll().size()).isEqualTo(1), + () -> assertThat( + coinAccount.getMoney() > coinData.getCoinPrice() * coinData.getCoinCount() + ).isEqualTo(true) + ); + } - // then - Long accountId = Objects.requireNonNull(coinAccountRepository.findByUserId(user.getId()).orElse(null)).getId(); - assertAll( - () -> assertThat(tradeRepository.findAll().size()).isEqualTo(1), - () -> assertThat( - tradeRepository.findAllByCoinAccountIdOrderByTradedTimeDesc(accountId).get(0).getCoinPrice() - ).isEqualTo(coinData.getCoinPrice()), - () -> assertThat( - tradeRepository.findAllByCoinAccountIdOrderByTradedTimeDesc(accountId).get(0).getCoinCount() - ).isEqualTo(coinData.getCoinCount()) - ); + // @RepeatedTest(REPEAT_COUNT) + // void 잔고가_충분하지_않을_경우() { + // + // } + } } @RepeatedTest(REPEAT_COUNT) diff --git a/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java b/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java index 04312b99..18a23994 100644 --- a/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java +++ b/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java @@ -58,7 +58,12 @@ public static StringArbitrary getDefaultStringBuilder() { .ofMinLength(1); } - public static TradeWithoutTradeStatusAndCoinAccountId getRandomTradeWithoutTradeStatusAndCoinAccountId() { - return fixtureGenerator.giveMeOne(TradeWithoutTradeStatusAndCoinAccountId.class); + public static ArbitraryBuilder getRandomTradeWithoutTradeStatusAndCoinAccountId() { + return fixtureGenerator.giveMeBuilder(TradeWithoutTradeStatusAndCoinAccountId.class) + .setPostCondition( + javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinCount), + Long.class, + it -> it > 0 + ); } } From ceec041f75de65929b7b03012b843dab56b21894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Sat, 27 Apr 2024 22:12:20 +0900 Subject: [PATCH 15/41] =?UTF-8?q?refactor(coin):=20coinPrice=EB=A5=BC=20?= =?UTF-8?q?=ED=98=84=EC=9E=AC=20=EC=8B=9C=EC=84=B8=EB=A5=BC=20=EA=B8=B0?= =?UTF-8?q?=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EB=9E=9C=EB=8D=A4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bumawiki/domain/coin/service/CommandCoinServiceTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index 81228015..2c707320 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -62,7 +62,6 @@ class 구매_가격이_시세보다_높거나_같을_때 { void 잔고가_충분할_경우() { // given Price price = priceRepository.getRecentPrice(); - System.out.println(price.getPrice()); User user = FixtureGenerator.getDefaultUserBuilder().sample(); @@ -73,9 +72,9 @@ class 구매_가격이_시세보다_높거나_같을_때 { .setPostCondition( javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinPrice), Long.class, - it -> it < CommandCoinService.FIRST_MONEY / 100L + it -> it < price.getPrice() / 100L ) - .set(javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinCount), price.getPrice()/100000L) + .set(javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinCount), price.getPrice() / 100000L) .sample(); CoinAccount coinAccount = new CoinAccount( From 948c885585350d1650a3d8bf650043ebb8476ab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Sat, 27 Apr 2024 22:19:07 +0900 Subject: [PATCH 16/41] =?UTF-8?q?refactor(coin):=20=EC=BD=94=EC=9D=B8=20?= =?UTF-8?q?=EA=B5=AC=EB=A7=A4=ED=95=98=EA=B8=B0=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=A1=B0=EA=B1=B4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bumawiki/domain/coin/service/CommandCoinServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index 2c707320..ab137406 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -91,7 +91,7 @@ class 구매_가격이_시세보다_높거나_같을_때 { assertAll( () -> assertThat(tradeRepository.findAll().size()).isEqualTo(1), () -> assertThat( - coinAccount.getMoney() > coinData.getCoinPrice() * coinData.getCoinCount() + coinAccount.getMoney() >= coinData.getCoinPrice() * coinData.getCoinCount() ).isEqualTo(true) ); } From e6374f95641849170fb3037daba95a1901644949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Sat, 27 Apr 2024 22:49:35 +0900 Subject: [PATCH 17/41] =?UTF-8?q?test(coin):=20=EC=BD=94=EC=9D=B8=20?= =?UTF-8?q?=EA=B5=AC=EB=A7=A4=ED=95=A0=20=EB=96=84=20=EC=9E=94=EA=B3=A0?= =?UTF-8?q?=EA=B0=80=20=EB=B6=80=EC=A1=B1=ED=95=A0=20=EA=B2=BD=EC=9A=B0?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinServiceTest.java | 118 +++++++++++------- .../global/service/FixtureGenerator.java | 5 + 2 files changed, 80 insertions(+), 43 deletions(-) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index ab137406..32e631df 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -16,6 +16,8 @@ import com.project.bumawiki.domain.coin.domain.repository.TradeRepository; import com.project.bumawiki.domain.user.domain.User; import com.project.bumawiki.domain.user.domain.repository.UserRepository; +import com.project.bumawiki.global.error.exception.BumawikiException; +import com.project.bumawiki.global.error.exception.ErrorCode; import com.project.bumawiki.global.service.FixtureGenerator; import com.project.bumawiki.global.service.ServiceTest; @@ -56,50 +58,80 @@ class CommandCoinServiceTest extends ServiceTest { @Nested class 코인_구매하기 { - @Nested - class 구매_가격이_시세보다_높거나_같을_때 { - @RepeatedTest(REPEAT_COUNT) - void 잔고가_충분할_경우() { - // given - Price price = priceRepository.getRecentPrice(); - - User user = FixtureGenerator.getDefaultUserBuilder().sample(); - - userRepository.save(user); - - TradeWithoutTradeStatusAndCoinAccountId coinData = FixtureGenerator - .getRandomTradeWithoutTradeStatusAndCoinAccountId() - .setPostCondition( - javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinPrice), - Long.class, - it -> it < price.getPrice() / 100L - ) - .set(javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinCount), price.getPrice() / 100000L) - .sample(); - - CoinAccount coinAccount = new CoinAccount( - user.getId(), - CommandCoinService.FIRST_MONEY - ); - - coinAccountRepository.save(coinAccount); - - // when - commandCoinService.buyCoin(coinData, user); - - // then - assertAll( - () -> assertThat(tradeRepository.findAll().size()).isEqualTo(1), - () -> assertThat( - coinAccount.getMoney() >= coinData.getCoinPrice() * coinData.getCoinCount() - ).isEqualTo(true) - ); - } + @RepeatedTest(REPEAT_COUNT) + void 잔고가_충분하지_않을_경우() { + // given + Price price = priceRepository.getRecentPrice(); + + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + TradeWithoutTradeStatusAndCoinAccountId coinData = FixtureGenerator + .getRandomTradeWithoutTradeStatusAndCoinAccountId() + .setPostCondition( + javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinPrice), + Long.class, + it -> it >= price.getPrice() + ) + .set(javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinCount), price.getPrice() / 10000L) + .sample(); + + CoinAccount coinAccount = new CoinAccount( + user.getId(), + FixtureGenerator.getDefaultLongArbitrary() + .lessOrEqual(coinData.getCoinCount() * coinData.getCoinPrice() - 1L) + .sample() + ); + + coinAccountRepository.save(coinAccount); + + // when + BumawikiException exception = assertThrows( + BumawikiException.class, + () -> commandCoinService.buyCoin(coinData, user) + ); + + // then + assertThat(exception.getErrorCode()).isEqualTo(ErrorCode.MONEY_NOT_ENOUGH); + } - // @RepeatedTest(REPEAT_COUNT) - // void 잔고가_충분하지_않을_경우() { - // - // } + @RepeatedTest(REPEAT_COUNT) + void 구매_가격이_시세보다_높거나_같을_때() { + // given + Price price = priceRepository.getRecentPrice(); + + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + TradeWithoutTradeStatusAndCoinAccountId coinData = FixtureGenerator + .getRandomTradeWithoutTradeStatusAndCoinAccountId() + .setPostCondition( + javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinPrice), + Long.class, + it -> it < price.getPrice() / 100L + ) + .set(javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinCount), price.getPrice() / 100000L) + .sample(); + + CoinAccount coinAccount = new CoinAccount( + user.getId(), + CommandCoinService.FIRST_MONEY + ); + + coinAccountRepository.save(coinAccount); + + // when + commandCoinService.buyCoin(coinData, user); + + // then + assertAll( + () -> assertThat(tradeRepository.findAll().size()).isEqualTo(1), + () -> assertThat( + coinAccount.getMoney() >= coinData.getCoinPrice() * coinData.getCoinCount() + ).isEqualTo(true) + ); } } diff --git a/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java b/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java index 18a23994..d8b394bd 100644 --- a/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java +++ b/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java @@ -5,6 +5,7 @@ import java.util.Collections; import net.jqwik.api.Arbitraries; +import net.jqwik.api.arbitraries.LongArbitrary; import net.jqwik.api.arbitraries.StringArbitrary; import com.project.bumawiki.domain.coin.domain.TradeWithoutTradeStatusAndCoinAccountId; @@ -58,6 +59,10 @@ public static StringArbitrary getDefaultStringBuilder() { .ofMinLength(1); } + public static LongArbitrary getDefaultLongArbitrary() { + return Arbitraries.longs(); + } + public static ArbitraryBuilder getRandomTradeWithoutTradeStatusAndCoinAccountId() { return fixtureGenerator.giveMeBuilder(TradeWithoutTradeStatusAndCoinAccountId.class) .setPostCondition( From 501e7973d03fd3439f28c55c3ea627894bb997ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Sun, 28 Apr 2024 20:30:12 +0900 Subject: [PATCH 18/41] =?UTF-8?q?refactor(coin):=20=EC=BD=94=EC=9D=B8=20?= =?UTF-8?q?=EA=B0=9C=EC=88=98,=20=EA=B0=80=EA=B2=A9=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinServiceTest.java | 110 ++++++++++++++---- 1 file changed, 88 insertions(+), 22 deletions(-) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index 32e631df..625230c8 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -1,6 +1,5 @@ package com.project.bumawiki.domain.coin.service; -import static com.navercorp.fixturemonkey.api.experimental.JavaGetterMethodPropertySelector.*; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; @@ -67,20 +66,25 @@ class 코인_구매하기 { userRepository.save(user); - TradeWithoutTradeStatusAndCoinAccountId coinData = FixtureGenerator - .getRandomTradeWithoutTradeStatusAndCoinAccountId() - .setPostCondition( - javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinPrice), - Long.class, - it -> it >= price.getPrice() - ) - .set(javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinCount), price.getPrice() / 10000L) - .sample(); + Long coinCount = 0L; + Long coinPrice = 0L; + + while (coinCount * coinPrice <= 0) { + coinCount = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(0L) + .sample(); + coinPrice = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(1000000L) + .sample(); + } + + TradeWithoutTradeStatusAndCoinAccountId coinData = + new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); CoinAccount coinAccount = new CoinAccount( user.getId(), FixtureGenerator.getDefaultLongArbitrary() - .lessOrEqual(coinData.getCoinCount() * coinData.getCoinPrice() - 1L) + .between(0L, coinData.getCoinCount() * coinData.getCoinPrice() - 200000L) .sample() ); @@ -105,23 +109,32 @@ class 코인_구매하기 { userRepository.save(user); - TradeWithoutTradeStatusAndCoinAccountId coinData = FixtureGenerator - .getRandomTradeWithoutTradeStatusAndCoinAccountId() - .setPostCondition( - javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinPrice), - Long.class, - it -> it < price.getPrice() / 100L - ) - .set(javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinCount), price.getPrice() / 100000L) - .sample(); + Long coinCount = 0L; + Long coinPrice = 0L; + + while (coinCount * coinPrice <= 0) { + coinCount = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(0L) + .sample(); + coinPrice = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(price.getPrice()) + .sample(); + } + + TradeWithoutTradeStatusAndCoinAccountId coinData = + new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); CoinAccount coinAccount = new CoinAccount( user.getId(), - CommandCoinService.FIRST_MONEY + FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(coinData.getCoinCount() * coinData.getCoinPrice()) + .sample() ); coinAccountRepository.save(coinAccount); + Long moneyBeforeBuyCoin = coinAccount.getMoney(); + // when commandCoinService.buyCoin(coinData, user); @@ -129,7 +142,60 @@ class 코인_구매하기 { assertAll( () -> assertThat(tradeRepository.findAll().size()).isEqualTo(1), () -> assertThat( - coinAccount.getMoney() >= coinData.getCoinPrice() * coinData.getCoinCount() + moneyBeforeBuyCoin >= coinData.getCoinPrice() * coinData.getCoinCount() + ).isEqualTo(true), + () -> assertThat( + coinData.getCoinPrice() >= price.getPrice() + ).isEqualTo(true) + ); + } + + @RepeatedTest(REPEAT_COUNT) + void 구매_가격이_시세보다_낮을_때() { + // given + Price price = priceRepository.getRecentPrice(); + + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + Long coinCount = 0L; + Long coinPrice = 0L; + + while (coinCount * coinPrice <= 0) { + coinCount = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(0L) + .sample(); + coinPrice = FixtureGenerator.getDefaultLongArbitrary() + .between(0L, price.getPrice() - 1L) + .sample(); + } + + TradeWithoutTradeStatusAndCoinAccountId coinData = + new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + + CoinAccount coinAccount = new CoinAccount( + user.getId(), + FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(coinData.getCoinCount() * coinData.getCoinPrice()) + .sample() + ); + + coinAccountRepository.save(coinAccount); + + Long moneyBeforeBuyCoin = coinAccount.getMoney(); + + // when + commandCoinService.buyCoin(coinData, user); + + // then + assertAll( + () -> assertThat(tradeRepository.findAll().size()).isEqualTo(1), + () -> assertThat( + moneyBeforeBuyCoin >= coinData.getCoinPrice() * coinData.getCoinCount() + ).isEqualTo(true), + () -> assertThat( + coinData.getCoinPrice() < price.getPrice() ).isEqualTo(true) ); } From b675dd9334d2c67c52726b2b56954da3e8c0388d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Sun, 28 Apr 2024 20:32:19 +0900 Subject: [PATCH 19/41] =?UTF-8?q?refactor(coin):=20=EC=95=88=20=EC=93=B0?= =?UTF-8?q?=EB=8A=94=20=EB=B3=80=EC=88=98=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinServiceTest.java | 147 +++++++++++++++++- 1 file changed, 143 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index 625230c8..0b18e658 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -60,8 +60,6 @@ class 코인_구매하기 { @RepeatedTest(REPEAT_COUNT) void 잔고가_충분하지_않을_경우() { // given - Price price = priceRepository.getRecentPrice(); - User user = FixtureGenerator.getDefaultUserBuilder().sample(); userRepository.save(user); @@ -201,8 +199,149 @@ class 코인_구매하기 { } } - @RepeatedTest(REPEAT_COUNT) - void 코인_판매하기() { + @Nested + class 코인_판매하기 { + @RepeatedTest(REPEAT_COUNT) + void 잔고가_충분하지_않을_경우() { + // given + Price price = priceRepository.getRecentPrice(); + + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + userRepository.save(user); + + Long coinCount = 0L; + Long coinPrice = 0L; + + while (coinCount * coinPrice <= 0) { + coinCount = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(0L) + .sample(); + coinPrice = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(1000000L) + .sample(); + } + + TradeWithoutTradeStatusAndCoinAccountId coinData = + new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + + CoinAccount coinAccount = new CoinAccount( + user.getId(), + FixtureGenerator.getDefaultLongArbitrary() + .between(0L, coinData.getCoinCount() * coinData.getCoinPrice() - 200000L) + .sample() + ); + + coinAccountRepository.save(coinAccount); + + // when + BumawikiException exception = assertThrows( + BumawikiException.class, + () -> commandCoinService.buyCoin(coinData, user) + ); + + // then + assertThat(exception.getErrorCode()).isEqualTo(ErrorCode.MONEY_NOT_ENOUGH); + } + + @RepeatedTest(REPEAT_COUNT) + void 구매_가격이_시세보다_높거나_같을_때() { + // given + Price price = priceRepository.getRecentPrice(); + + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + Long coinCount = 0L; + Long coinPrice = 0L; + + while (coinCount * coinPrice <= 0) { + coinCount = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(0L) + .sample(); + coinPrice = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(price.getPrice()) + .sample(); + } + + TradeWithoutTradeStatusAndCoinAccountId coinData = + new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + + CoinAccount coinAccount = new CoinAccount( + user.getId(), + FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(coinData.getCoinCount() * coinData.getCoinPrice()) + .sample() + ); + + coinAccountRepository.save(coinAccount); + + Long moneyBeforeBuyCoin = coinAccount.getMoney(); + + // when + commandCoinService.buyCoin(coinData, user); + + // then + assertAll( + () -> assertThat(tradeRepository.findAll().size()).isEqualTo(1), + () -> assertThat( + moneyBeforeBuyCoin >= coinData.getCoinPrice() * coinData.getCoinCount() + ).isEqualTo(true), + () -> assertThat( + coinData.getCoinPrice() >= price.getPrice() + ).isEqualTo(true) + ); + } + + @RepeatedTest(REPEAT_COUNT) + void 구매_가격이_시세보다_낮을_때() { + // given + Price price = priceRepository.getRecentPrice(); + + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + Long coinCount = 0L; + Long coinPrice = 0L; + + while (coinCount * coinPrice <= 0) { + coinCount = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(0L) + .sample(); + coinPrice = FixtureGenerator.getDefaultLongArbitrary() + .between(0L, price.getPrice() - 1L) + .sample(); + } + + TradeWithoutTradeStatusAndCoinAccountId coinData = + new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + + CoinAccount coinAccount = new CoinAccount( + user.getId(), + FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(coinData.getCoinCount() * coinData.getCoinPrice()) + .sample() + ); + + coinAccountRepository.save(coinAccount); + + Long moneyBeforeBuyCoin = coinAccount.getMoney(); + + // when + commandCoinService.buyCoin(coinData, user); + + // then + assertAll( + () -> assertThat(tradeRepository.findAll().size()).isEqualTo(1), + () -> assertThat( + moneyBeforeBuyCoin >= coinData.getCoinPrice() * coinData.getCoinCount() + ).isEqualTo(true), + () -> assertThat( + coinData.getCoinPrice() < price.getPrice() + ).isEqualTo(true) + ); + } } } From 51d88477a91960d0459ca003bc75d0d92fd6cb3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Sun, 28 Apr 2024 23:07:26 +0900 Subject: [PATCH 20/41] =?UTF-8?q?test(coin):=20=EC=BD=94=EC=9D=B8=20?= =?UTF-8?q?=ED=8C=90=EB=A7=A4=ED=95=A0=20=EB=95=8C=20=EC=BD=94=EC=9D=B8?= =?UTF-8?q?=EC=9D=B4=20=EC=B6=A9=EB=B6=84=ED=95=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EC=9D=84=20=EA=B2=BD=EC=9A=B0=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinServiceTest.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index 0b18e658..a325ea40 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -202,10 +202,8 @@ class 코인_구매하기 { @Nested class 코인_판매하기 { @RepeatedTest(REPEAT_COUNT) - void 잔고가_충분하지_않을_경우() { + void 코인이_충분하지_않을_경우() { // given - Price price = priceRepository.getRecentPrice(); - User user = FixtureGenerator.getDefaultUserBuilder().sample(); userRepository.save(user); @@ -215,10 +213,10 @@ class 코인_판매하기 { while (coinCount * coinPrice <= 0) { coinCount = FixtureGenerator.getDefaultLongArbitrary() - .greaterOrEqual(0L) + .between(0L, Long.MAX_VALUE) .sample(); coinPrice = FixtureGenerator.getDefaultLongArbitrary() - .greaterOrEqual(1000000L) + .between(0L, 1000000L) .sample(); } @@ -228,20 +226,25 @@ class 코인_판매하기 { CoinAccount coinAccount = new CoinAccount( user.getId(), FixtureGenerator.getDefaultLongArbitrary() - .between(0L, coinData.getCoinCount() * coinData.getCoinPrice() - 200000L) + .greaterOrEqual(coinData.getCoinCount() * coinData.getCoinPrice()) .sample() ); coinAccountRepository.save(coinAccount); + commandCoinService.buyCoin(coinData, user); + + TradeWithoutTradeStatusAndCoinAccountId coinDataToSell = + new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount + 1); + // when BumawikiException exception = assertThrows( BumawikiException.class, - () -> commandCoinService.buyCoin(coinData, user) + () -> commandCoinService.sellCoin(coinDataToSell, user) ); // then - assertThat(exception.getErrorCode()).isEqualTo(ErrorCode.MONEY_NOT_ENOUGH); + assertThat(exception.getErrorCode()).isEqualTo(ErrorCode.COIN_NOT_ENOUGH); } @RepeatedTest(REPEAT_COUNT) From 65082e946d1de6874aebdbf688fd90a99a6cda33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Sun, 28 Apr 2024 23:37:57 +0900 Subject: [PATCH 21/41] =?UTF-8?q?test(coin):=20=EC=BD=94=EC=9D=B8=20?= =?UTF-8?q?=ED=8C=90=EB=A7=A4=ED=95=A0=20=EB=95=8C=20=EA=B5=AC=EB=A7=A4=5F?= =?UTF-8?q?=EA=B0=80=EA=B2=A9=EC=9D=B4=5F=EC=8B=9C=EC=84=B8=EB=B3=B4?= =?UTF-8?q?=EB=8B=A4=5F=EB=82=AE=EA=B1=B0=EB=82=98=5F=EA=B0=99=EC=9D=84=5F?= =?UTF-8?q?=EB=95=8C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinServiceTest.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index a325ea40..eac8dd02 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -248,7 +248,7 @@ class 코인_판매하기 { } @RepeatedTest(REPEAT_COUNT) - void 구매_가격이_시세보다_높거나_같을_때() { + void 구매_가격이_시세보다_낮거나_같을_때() { // given Price price = priceRepository.getRecentPrice(); @@ -264,7 +264,7 @@ class 코인_판매하기 { .greaterOrEqual(0L) .sample(); coinPrice = FixtureGenerator.getDefaultLongArbitrary() - .greaterOrEqual(price.getPrice()) + .between(0L, price.getPrice()) .sample(); } @@ -280,19 +280,27 @@ class 코인_판매하기 { coinAccountRepository.save(coinAccount); - Long moneyBeforeBuyCoin = coinAccount.getMoney(); + commandCoinService.buyCoin(coinData, user); + + TradeWithoutTradeStatusAndCoinAccountId coinDataToSell = + new TradeWithoutTradeStatusAndCoinAccountId( + coinPrice, + FixtureGenerator.getDefaultLongArbitrary() + .between(0L, coinAccount.getCoin()) + .sample() + ); // when - commandCoinService.buyCoin(coinData, user); + commandCoinService.sellCoin(coinDataToSell, user); // then assertAll( - () -> assertThat(tradeRepository.findAll().size()).isEqualTo(1), + () -> assertThat(tradeRepository.findAll().size()).isEqualTo(2), () -> assertThat( - moneyBeforeBuyCoin >= coinData.getCoinPrice() * coinData.getCoinCount() - ).isEqualTo(true), + coinAccount.getCoin() < coinDataToSell.getCoinCount() + ).isEqualTo(false), () -> assertThat( - coinData.getCoinPrice() >= price.getPrice() + coinData.getCoinPrice() <= price.getPrice() ).isEqualTo(true) ); } From 09068698d41cc837fd8660ca6f4f9022905760df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Sun, 28 Apr 2024 23:47:30 +0900 Subject: [PATCH 22/41] =?UTF-8?q?test(coin):=20=EC=BD=94=EC=9D=B8=20?= =?UTF-8?q?=ED=8C=90=EB=A7=A4=ED=95=A0=20=EB=95=8C=20=EA=B5=AC=EB=A7=A4=5F?= =?UTF-8?q?=EA=B0=80=EA=B2=A9=EC=9D=B4=5F=EC=8B=9C=EC=84=B8=EB=B3=B4?= =?UTF-8?q?=EB=8B=A4=5F=EB=86=92=EC=9D=84=5F=EB=95=8C=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinServiceTest.java | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index eac8dd02..c52e2257 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -5,14 +5,17 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.RepeatedTest; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import com.project.bumawiki.domain.coin.domain.CoinAccount; import com.project.bumawiki.domain.coin.domain.Price; +import com.project.bumawiki.domain.coin.domain.Trade; import com.project.bumawiki.domain.coin.domain.TradeWithoutTradeStatusAndCoinAccountId; import com.project.bumawiki.domain.coin.domain.repository.CoinAccountRepository; import com.project.bumawiki.domain.coin.domain.repository.PriceRepository; import com.project.bumawiki.domain.coin.domain.repository.TradeRepository; +import com.project.bumawiki.domain.coin.domain.type.TradeStatus; import com.project.bumawiki.domain.user.domain.User; import com.project.bumawiki.domain.user.domain.repository.UserRepository; import com.project.bumawiki.global.error.exception.BumawikiException; @@ -306,7 +309,7 @@ class 코인_판매하기 { } @RepeatedTest(REPEAT_COUNT) - void 구매_가격이_시세보다_낮을_때() { + void 구매_가격이_시세보다_높을_때() { // given Price price = priceRepository.getRecentPrice(); @@ -322,7 +325,7 @@ class 코인_판매하기 { .greaterOrEqual(0L) .sample(); coinPrice = FixtureGenerator.getDefaultLongArbitrary() - .between(0L, price.getPrice() - 1L) + .greaterOrEqual(price.getPrice() + 200000L) .sample(); } @@ -338,19 +341,25 @@ class 코인_판매하기 { coinAccountRepository.save(coinAccount); - Long moneyBeforeBuyCoin = coinAccount.getMoney(); + commandCoinService.buyCoin(coinData, user); + + TradeWithoutTradeStatusAndCoinAccountId coinDataToSell = + new TradeWithoutTradeStatusAndCoinAccountId( + coinPrice, + FixtureGenerator.getDefaultLongArbitrary() + .between(0L, coinAccount.getCoin()) + .sample() + ); // when - commandCoinService.buyCoin(coinData, user); + Trade trade = commandCoinService.sellCoin(coinDataToSell, user); // then assertAll( - () -> assertThat(tradeRepository.findAll().size()).isEqualTo(1), - () -> assertThat( - moneyBeforeBuyCoin >= coinData.getCoinPrice() * coinData.getCoinCount() - ).isEqualTo(true), + () -> assertThat(tradeRepository.findAll().size()).isEqualTo(2), + () -> assertThat(trade.getTradeStatus()).isEqualTo(TradeStatus.SELLING), () -> assertThat( - coinData.getCoinPrice() < price.getPrice() + coinData.getCoinPrice() > price.getPrice() ).isEqualTo(true) ); } From 39d05c471b7f2c7070c4b2cb695e482a4526387c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Mon, 29 Apr 2024 00:03:19 +0900 Subject: [PATCH 23/41] =?UTF-8?q?refactor(coin):=20TradeStatus=EB=A5=BC=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/coin/service/CommandCoinServiceTest.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index c52e2257..84b76acd 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -137,7 +137,7 @@ class 코인_구매하기 { Long moneyBeforeBuyCoin = coinAccount.getMoney(); // when - commandCoinService.buyCoin(coinData, user); + Trade trade = commandCoinService.buyCoin(coinData, user); // then assertAll( @@ -145,6 +145,7 @@ class 코인_구매하기 { () -> assertThat( moneyBeforeBuyCoin >= coinData.getCoinPrice() * coinData.getCoinCount() ).isEqualTo(true), + () -> assertThat(trade.getTradeStatus()).isEqualTo(TradeStatus.BOUGHT), () -> assertThat( coinData.getCoinPrice() >= price.getPrice() ).isEqualTo(true) @@ -187,7 +188,7 @@ class 코인_구매하기 { Long moneyBeforeBuyCoin = coinAccount.getMoney(); // when - commandCoinService.buyCoin(coinData, user); + Trade trade = commandCoinService.buyCoin(coinData, user); // then assertAll( @@ -195,6 +196,7 @@ class 코인_구매하기 { () -> assertThat( moneyBeforeBuyCoin >= coinData.getCoinPrice() * coinData.getCoinCount() ).isEqualTo(true), + () -> assertThat(trade.getTradeStatus()).isEqualTo(TradeStatus.BUYING), () -> assertThat( coinData.getCoinPrice() < price.getPrice() ).isEqualTo(true) @@ -267,7 +269,7 @@ class 코인_판매하기 { .greaterOrEqual(0L) .sample(); coinPrice = FixtureGenerator.getDefaultLongArbitrary() - .between(0L, price.getPrice()) + .between(0L, 800000L) .sample(); } @@ -294,7 +296,7 @@ class 코인_판매하기 { ); // when - commandCoinService.sellCoin(coinDataToSell, user); + Trade trade = commandCoinService.sellCoin(coinDataToSell, user); // then assertAll( @@ -302,6 +304,7 @@ class 코인_판매하기 { () -> assertThat( coinAccount.getCoin() < coinDataToSell.getCoinCount() ).isEqualTo(false), + () -> assertThat(trade.getTradeStatus()).isEqualTo(TradeStatus.SOLD), () -> assertThat( coinData.getCoinPrice() <= price.getPrice() ).isEqualTo(true) From 4e2c776261f810aaee0678da56f3e9ad7c8c1fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Mon, 29 Apr 2024 08:30:55 +0900 Subject: [PATCH 24/41] =?UTF-8?q?test(coin):=20=EA=B1=B0=EB=9E=98=20?= =?UTF-8?q?=EC=B7=A8=EC=86=8C=ED=95=A0=20=EB=95=8C=20=EB=8B=A4=EB=A5=B8=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=EA=B0=80=20=EC=9A=94=EC=B2=AD=ED=96=88?= =?UTF-8?q?=EC=9D=84=20=EB=95=8C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinServiceTest.java | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index 84b76acd..734530d0 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -367,4 +367,98 @@ class 코인_판매하기 { ); } } + + @Nested + class 거래_취소하기 { + @RepeatedTest(REPEAT_COUNT) + void 이미_완료된_거래일_때() { + // given + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + Long coinCount = 0L; + Long coinPrice = 0L; + + while (coinCount * coinPrice <= 0) { + coinCount = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(0L) + .sample(); + coinPrice = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(1000000L) + .sample(); + } + + TradeWithoutTradeStatusAndCoinAccountId coinData = + new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + + CoinAccount coinAccount = new CoinAccount( + user.getId(), + FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(coinData.getCoinCount() * coinData.getCoinPrice()) + .sample() + ); + + coinAccountRepository.save(coinAccount); + + Trade trade = commandCoinService.buyCoin(coinData, user); + + // when + BumawikiException exception = assertThrows( + BumawikiException.class, + () -> commandCoinService.cancelTrade(trade.getId(), user) + ); + + // then + assertThat(exception.getErrorCode()).isEqualTo(ErrorCode.TRADE_ALREADY_FINISHED); + } + + @RepeatedTest(REPEAT_COUNT) + void 다른_유저가_요청했을_때() { + // given + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + User otherUser = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(otherUser); + + Long coinCount = 0L; + Long coinPrice = 0L; + + while (coinCount * coinPrice <= 0) { + coinCount = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(0L) + .sample(); + coinPrice = FixtureGenerator.getDefaultLongArbitrary() + .between(0L, 1000000L - 1L) + .sample(); + } + + TradeWithoutTradeStatusAndCoinAccountId coinData = + new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + + CoinAccount coinAccount = new CoinAccount( + user.getId(), + FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(coinData.getCoinCount() * coinData.getCoinPrice()) + .sample() + ); + + coinAccountRepository.save(coinAccount); + + // when + Trade trade = commandCoinService.buyCoin(coinData, user); + + // when + BumawikiException exception = assertThrows( + BumawikiException.class, + () -> commandCoinService.cancelTrade(trade.getId(), otherUser) + ); + + // then + assertThat(exception.getErrorCode()).isEqualTo(ErrorCode.CANCEL_OTHERS_TRADE); + } + } } From 7da61f868e3e519dff7c4e2507c7afc121760391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Mon, 29 Apr 2024 09:57:43 +0900 Subject: [PATCH 25/41] =?UTF-8?q?test(coin):=20=EA=B1=B0=EB=9E=98=20?= =?UTF-8?q?=EC=B7=A8=EC=86=8C=ED=95=A0=20=EB=95=8C=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinServiceTest.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index 734530d0..5384f423 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -370,6 +370,46 @@ class 코인_판매하기 { @Nested class 거래_취소하기 { + @RepeatedTest(REPEAT_COUNT) + void 거래_취소할_때() { + // given + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + Long coinCount = 0L; + Long coinPrice = 0L; + + while (coinCount * coinPrice <= 0) { + coinCount = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(0L) + .sample(); + coinPrice = FixtureGenerator.getDefaultLongArbitrary() + .between(0L, 800000L) + .sample(); + } + + TradeWithoutTradeStatusAndCoinAccountId coinData = + new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + + CoinAccount coinAccount = new CoinAccount( + user.getId(), + FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(coinData.getCoinCount() * coinData.getCoinPrice()) + .sample() + ); + + coinAccountRepository.save(coinAccount); + + Trade trade = commandCoinService.buyCoin(coinData, user); + + // when + commandCoinService.cancelTrade(trade.getId(), user); + + // then + assertThat(trade.getTradeStatus()).isEqualTo(TradeStatus.CANCELLED); + } + @RepeatedTest(REPEAT_COUNT) void 이미_완료된_거래일_때() { // given From 3a49a21454bc1b1cf146197439fddf0fe0afecbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Mon, 29 Apr 2024 10:11:51 +0900 Subject: [PATCH 26/41] =?UTF-8?q?test(coin):=20=EC=9D=BC=EC=9D=BC=20?= =?UTF-8?q?=EB=B3=B4=EC=83=81=20=EB=B0=9B=EA=B8=B0=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinServiceTest.java | 61 ++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index 5384f423..6dcdc623 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -5,7 +5,6 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import com.project.bumawiki.domain.coin.domain.CoinAccount; @@ -56,6 +55,7 @@ class CommandCoinServiceTest extends ServiceTest { assertThat(coinAccountRepository.findByUserId(user.getId()).get().getUserId()).isEqualTo(user.getId()); } ); + // 이미존재하는경우 ㄱㄱ } @Nested @@ -501,4 +501,63 @@ class 거래_취소하기 { assertThat(exception.getErrorCode()).isEqualTo(ErrorCode.CANCEL_OTHERS_TRADE); } } + + @Nested + class 일일_보상_받기 { + @RepeatedTest(REPEAT_COUNT) + void 일일_보상_받을_때() { + // given + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + CoinAccount coinAccount = new CoinAccount( + user.getId(), + CommandCoinService.FIRST_MONEY + ); + + coinAccountRepository.save(coinAccount); + + // when + commandCoinService.dailyCheck(user); + + CoinAccount updatedCoinAccount = coinAccountRepository.getByUserId(user.getId()); + + // then + assertAll( + () -> assertThat( + updatedCoinAccount.wasRewardedToday() + ).isTrue(), + () -> assertThat( + updatedCoinAccount.getMoney() - CommandCoinService.FIRST_MONEY + ).isBetween(50000L, 200000L) + ); + } + + @RepeatedTest(REPEAT_COUNT) + void 이미_보상을_받았을_때() { + // given + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + CoinAccount coinAccount = new CoinAccount( + user.getId(), + CommandCoinService.FIRST_MONEY + ); + + coinAccountRepository.save(coinAccount); + + commandCoinService.dailyCheck(user); + + // when + BumawikiException exception = assertThrows( + BumawikiException.class, + () -> commandCoinService.dailyCheck(user) + ); + + // then + assertThat(exception.getErrorCode()).isEqualTo(ErrorCode.ALREADY_AWARDED); + } + } } From 431b7fa690d9de89d8aed414e2bfb7ac91d84877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Mon, 29 Apr 2024 10:16:02 +0900 Subject: [PATCH 27/41] =?UTF-8?q?test(coin):=20=EC=9D=B4=EB=AF=B8=20?= =?UTF-8?q?=EC=BD=94=EC=9D=B8=20=EA=B3=84=EC=A0=95=EC=9D=B4=20=EC=A1=B4?= =?UTF-8?q?=EC=9E=AC=ED=95=A0=20=EB=95=8C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinServiceTest.java | 51 +++++++++++++------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index 6dcdc623..26d012cd 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -38,24 +38,45 @@ class CommandCoinServiceTest extends ServiceTest { @Autowired private PriceRepository priceRepository; - @RepeatedTest(REPEAT_COUNT) - void 코인_계정_생성하기() { - // given - User user = FixtureGenerator.getDefaultUserBuilder().sample(); + @Nested + class 코인_계정_생성하기 { + @RepeatedTest(REPEAT_COUNT) + void 코인_계정_생성할_때() { + // given + User user = FixtureGenerator.getDefaultUserBuilder().sample(); - userRepository.save(user); + userRepository.save(user); - // when - commandCoinService.createCoinAccount(user); + // when + commandCoinService.createCoinAccount(user); - // then - assertAll( - () -> { - assertThat(coinAccountRepository.findByUserId(user.getId()).isPresent()).isEqualTo(true); - assertThat(coinAccountRepository.findByUserId(user.getId()).get().getUserId()).isEqualTo(user.getId()); - } - ); - // 이미존재하는경우 ㄱㄱ + // then + assertAll( + () -> { + assertThat(coinAccountRepository.findByUserId(user.getId()).isPresent()).isEqualTo(true); + assertThat(coinAccountRepository.findByUserId(user.getId()).get().getUserId()).isEqualTo(user.getId()); + } + ); + } + + @RepeatedTest(REPEAT_COUNT) + void 이미_계정이_존재할_때() { + // given + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + commandCoinService.createCoinAccount(user); + + // when + BumawikiException exception = assertThrows( + BumawikiException.class, + () -> commandCoinService.createCoinAccount(user) + ); + + // then + assertThat(exception.getErrorCode()).isEqualTo(ErrorCode.ALREADY_CREATED); + } } @Nested From fe0d23fac0cfa452a7f4e0b50a3604118243d154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Mon, 29 Apr 2024 11:04:49 +0900 Subject: [PATCH 28/41] =?UTF-8?q?fix(coin):=20CommandCoinServiceTest=20?= =?UTF-8?q?=EC=97=A3=EC=A7=80=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinServiceTest.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index 26d012cd..c3c3d987 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -93,22 +93,20 @@ class 코인_구매하기 { while (coinCount * coinPrice <= 0) { coinCount = FixtureGenerator.getDefaultLongArbitrary() - .greaterOrEqual(0L) + .greaterOrEqual(1L) .sample(); coinPrice = FixtureGenerator.getDefaultLongArbitrary() - .greaterOrEqual(1000000L) + .greaterOrEqual(1200000L) .sample(); } TradeWithoutTradeStatusAndCoinAccountId coinData = new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); - CoinAccount coinAccount = new CoinAccount( - user.getId(), - FixtureGenerator.getDefaultLongArbitrary() - .between(0L, coinData.getCoinCount() * coinData.getCoinPrice() - 200000L) - .sample() - ); + System.out.println(coinData.getCoinCount()); + System.out.println(coinData.getCoinPrice()); + + CoinAccount coinAccount = new CoinAccount(user.getId(), 0L); coinAccountRepository.save(coinAccount); @@ -139,7 +137,7 @@ class 코인_구매하기 { .greaterOrEqual(0L) .sample(); coinPrice = FixtureGenerator.getDefaultLongArbitrary() - .greaterOrEqual(price.getPrice()) + .greaterOrEqual(1200000L) .sample(); } @@ -190,7 +188,7 @@ class 코인_구매하기 { .greaterOrEqual(0L) .sample(); coinPrice = FixtureGenerator.getDefaultLongArbitrary() - .between(0L, price.getPrice() - 1L) + .between(0L, 800000L) .sample(); } @@ -446,7 +444,7 @@ class 거래_취소하기 { .greaterOrEqual(0L) .sample(); coinPrice = FixtureGenerator.getDefaultLongArbitrary() - .greaterOrEqual(1000000L) + .greaterOrEqual(1200000L) .sample(); } @@ -493,7 +491,7 @@ class 거래_취소하기 { .greaterOrEqual(0L) .sample(); coinPrice = FixtureGenerator.getDefaultLongArbitrary() - .between(0L, 1000000L - 1L) + .between(0L, 800000L) .sample(); } From e0de96cc47ba3e3fe084fd5a6bd76b840904ef3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Mon, 29 Apr 2024 19:46:33 +0900 Subject: [PATCH 29/41] =?UTF-8?q?test(coin):=20QueryCoinServiceTest=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/QueryCoinServiceTest.java | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java new file mode 100644 index 00000000..b33bfa4a --- /dev/null +++ b/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java @@ -0,0 +1,168 @@ +package com.project.bumawiki.domain.coin.service; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.RepeatedTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; + +import com.project.bumawiki.domain.coin.domain.CoinAccount; +import com.project.bumawiki.domain.coin.domain.Price; +import com.project.bumawiki.domain.coin.domain.Trade; +import com.project.bumawiki.domain.coin.domain.TradeWithoutTradeStatusAndCoinAccountId; +import com.project.bumawiki.domain.coin.domain.repository.CoinAccountRepository; +import com.project.bumawiki.domain.coin.domain.repository.TradeRepository; +import com.project.bumawiki.domain.coin.domain.type.TradeStatus; +import com.project.bumawiki.domain.coin.presentation.dto.RankingResponse; +import com.project.bumawiki.domain.user.domain.User; +import com.project.bumawiki.domain.user.domain.repository.UserRepository; +import com.project.bumawiki.global.error.exception.BumawikiException; +import com.project.bumawiki.global.error.exception.ErrorCode; +import com.project.bumawiki.global.service.FixtureGenerator; +import com.project.bumawiki.global.service.ServiceTest; + +class QueryCoinServiceTest extends ServiceTest { + @Autowired + private QueryCoinService queryCoinService; + + @Autowired + private UserRepository userRepository; + + @Autowired + private CoinAccountRepository coinAccountRepository; + + @Autowired + private TradeRepository tradeRepository; + + @Nested + class 코인_계정_찾기 { + @RepeatedTest(REPEAT_COUNT) + void 유저_정보로_코인_계정_찾기() { + // given + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + Long money = FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(0L) + .sample(); + + CoinAccount coinAccount = new CoinAccount(user.getId(), money); + + coinAccountRepository.save(coinAccount); + + // when + CoinAccount findCoinAccount = queryCoinService.findCoinAccountByUser(user); + + // then + assertThat(findCoinAccount.getUserId()).isEqualTo(user.getId()); + } + + @RepeatedTest(REPEAT_COUNT) + void 코인_저장이_안되어있을때() { + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + // when + BumawikiException exception = assertThrows( + BumawikiException.class, + () -> queryCoinService.findCoinAccountByUser(user) + ); + + // then + assertThat(exception.getErrorCode()).isEqualTo(ErrorCode.COIN_ACCOUNT_NOT_FOUND_EXCEPTION); + } + } + + @RepeatedTest(REPEAT_COUNT) + void 코인_계정으로_거래_내역_조회하기() { + // given + User user = FixtureGenerator.getDefaultUserBuilder().sample(); + + userRepository.save(user); + + CoinAccount coinAccount = new CoinAccount( + user.getId(), + 10000000L + ); + + coinAccountRepository.save(coinAccount); + + TradeWithoutTradeStatusAndCoinAccountId coinData = + new TradeWithoutTradeStatusAndCoinAccountId(1000000L, 3L); + + Trade trade = coinData.toTrade(coinAccount); + + coinAccount.buyCoin(trade.getCoinPrice(), trade.getCoinCount()); + trade.updateTradeStatus(TradeStatus.BOUGHT); + + tradeRepository.save(trade); + + // when + List trades = queryCoinService.getTrades(coinAccount.getId()); + + // then + assertAll( + () -> assertThat(trades.size()).isEqualTo(1), + () -> assertThat(trades.get(0).getTradeStatus()).isEqualTo(TradeStatus.BOUGHT), + () -> assertThat(trades.get(0).getCoinAccountId()).isEqualTo(coinAccount.getId()) + ); + } + + @RepeatedTest(REPEAT_COUNT) + void 기간_별로_코인_가격_조회하기() { + // given + String[] periods = {"full", "halfMonth", "week", "day", "halfDay", "threeHours"}; + long index = FixtureGenerator.getDefaultLongArbitrary().between(0, 5).sample(); + + // when + List prices = queryCoinService.getPriceByPeriod(periods[Long.valueOf(index).intValue()]); + + // then + assertAll( + () -> assertThat(prices.get(0)).isNotNull(), + () -> assertThat(prices.size()).isEqualTo(2) + ); + } + + @RepeatedTest(REPEAT_COUNT) + void 랭킹_조회하기() { + // given + List users = FixtureGenerator.getDefaultUserBuilder() + .sampleList(10); + + userRepository.saveAll(users); + + users.forEach(user -> { + CoinAccount coinAccount = new CoinAccount( + user.getId(), + FixtureGenerator.getDefaultLongArbitrary() + .greaterOrEqual(0L) + .sample() + ); + + coinAccountRepository.save(coinAccount); + }); + + // when + List rankingResponses = + queryCoinService.getRanking(PageRequest.of(0, 10)); + + // then + assertThat(rankingResponses.size()).isEqualTo(10); + } + + @RepeatedTest(REPEAT_COUNT) + void 현재_코인_시세_조회하기() { + // when + Price price = queryCoinService.getRecentPrice(); + + // then + assertThat(price.getPrice()).isNotNull(); + } +} From ce2dc62aff113ed4397b07f35ef1802aeacf9942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Tue, 30 Apr 2024 19:43:20 +0900 Subject: [PATCH 30/41] =?UTF-8?q?refactor(coin):=20periods=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/coin/service/QueryCoinServiceTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java index b33bfa4a..4d2f9683 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java @@ -10,6 +10,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; +import net.jqwik.api.Arbitraries; +import net.jqwik.api.Arbitrary; + import com.project.bumawiki.domain.coin.domain.CoinAccount; import com.project.bumawiki.domain.coin.domain.Price; import com.project.bumawiki.domain.coin.domain.Trade; @@ -117,11 +120,10 @@ class 코인_계정_찾기 { @RepeatedTest(REPEAT_COUNT) void 기간_별로_코인_가격_조회하기() { // given - String[] periods = {"full", "halfMonth", "week", "day", "halfDay", "threeHours"}; - long index = FixtureGenerator.getDefaultLongArbitrary().between(0, 5).sample(); + Arbitrary periods = Arbitraries.of("full", "halfMonth", "week", "day", "halfDay", "threeHours"); // when - List prices = queryCoinService.getPriceByPeriod(periods[Long.valueOf(index).intValue()]); + List prices = queryCoinService.getPriceByPeriod(periods.sample()); // then assertAll( From 4d61f5c8088a0982e01df37c5f19df820cf579af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Tue, 30 Apr 2024 19:45:47 +0900 Subject: [PATCH 31/41] =?UTF-8?q?refactor(coin):=20=EC=95=88=20=EC=93=B0?= =?UTF-8?q?=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bumawiki/global/service/FixtureGenerator.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java b/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java index d8b394bd..d4f22a7d 100644 --- a/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java +++ b/src/test/java/com/project/bumawiki/global/service/FixtureGenerator.java @@ -8,7 +8,6 @@ import net.jqwik.api.arbitraries.LongArbitrary; import net.jqwik.api.arbitraries.StringArbitrary; -import com.project.bumawiki.domain.coin.domain.TradeWithoutTradeStatusAndCoinAccountId; import com.project.bumawiki.domain.docs.domain.Docs; import com.project.bumawiki.domain.docs.domain.VersionDocs; import com.project.bumawiki.domain.thumbsup.domain.ThumbsUp; @@ -62,13 +61,4 @@ public static StringArbitrary getDefaultStringBuilder() { public static LongArbitrary getDefaultLongArbitrary() { return Arbitraries.longs(); } - - public static ArbitraryBuilder getRandomTradeWithoutTradeStatusAndCoinAccountId() { - return fixtureGenerator.giveMeBuilder(TradeWithoutTradeStatusAndCoinAccountId.class) - .setPostCondition( - javaGetter(TradeWithoutTradeStatusAndCoinAccountId::getCoinCount), - Long.class, - it -> it > 0 - ); - } } From 07993b1865f89bc45be1f5f0035f27162f20fb95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Tue, 30 Apr 2024 20:02:08 +0900 Subject: [PATCH 32/41] =?UTF-8?q?refactor(coin):=20tradeUpdater=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/coin/implementation/TradeUpdater.java | 13 +++++++++++++ .../domain/coin/service/CommandCoinService.java | 10 ++++++---- .../domain/coin/service/PriceScheduler.java | 6 ++++-- 3 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/project/bumawiki/domain/coin/implementation/TradeUpdater.java diff --git a/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeUpdater.java b/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeUpdater.java new file mode 100644 index 00000000..3998d180 --- /dev/null +++ b/src/main/java/com/project/bumawiki/domain/coin/implementation/TradeUpdater.java @@ -0,0 +1,13 @@ +package com.project.bumawiki.domain.coin.implementation; + +import com.project.bumawiki.domain.coin.domain.Trade; +import com.project.bumawiki.domain.coin.domain.type.TradeStatus; +import com.project.bumawiki.global.annotation.Implementation; + +@Implementation +public class TradeUpdater { + + public void updateTradeStatus(Trade trade, TradeStatus tradeStatus) { + trade.updateTradeStatus(tradeStatus); + } +} diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java index 90ccb7db..377b7b54 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java @@ -18,6 +18,7 @@ import com.project.bumawiki.domain.coin.implementation.PriceReader; import com.project.bumawiki.domain.coin.implementation.TradeCreator; import com.project.bumawiki.domain.coin.implementation.TradeReader; +import com.project.bumawiki.domain.coin.implementation.TradeUpdater; import com.project.bumawiki.domain.coin.implementation.TradeValidator; import com.project.bumawiki.domain.user.domain.User; @@ -34,6 +35,7 @@ public class CommandCoinService { private final PriceReader priceReader; private final TradeReader tradeReader; private final TradeCreator tradeCreator; + private final TradeUpdater tradeUpdater; private final TradeValidator tradeValidator; public CoinAccount createCoinAccount(User user) { @@ -63,12 +65,12 @@ public Trade buyCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User user } private void buyLater(Trade trade) { - trade.updateTradeStatus(TradeStatus.BUYING); + tradeUpdater.updateTradeStatus(trade, TradeStatus.BUYING); } private void buyNow(Trade trade, CoinAccount coinAccount) { coinAccount.buyCoin(trade.getCoinPrice(), trade.getCoinCount()); - trade.updateTradeStatus(TradeStatus.BOUGHT); + tradeUpdater.updateTradeStatus(trade, TradeStatus.BOUGHT); } public Trade sellCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User user) { @@ -87,12 +89,12 @@ public Trade sellCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User use } private void sellLater(Trade trade) { - trade.updateTradeStatus(TradeStatus.SELLING); + tradeUpdater.updateTradeStatus(trade, TradeStatus.SELLING); } private void sellNow(Trade trade, CoinAccount coinAccount) { coinAccount.sellCoin(trade.getCoinPrice(), trade.getCoinCount()); - trade.updateTradeStatus(TradeStatus.SOLD); + tradeUpdater.updateTradeStatus(trade, TradeStatus.SOLD); } public void cancelTrade(Long tradeId, User user) { diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java b/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java index ea2e833a..e6c16fc8 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java @@ -18,6 +18,7 @@ import com.project.bumawiki.domain.coin.implementation.PriceReader; import com.project.bumawiki.domain.coin.implementation.TradeCreator; import com.project.bumawiki.domain.coin.implementation.TradeReader; +import com.project.bumawiki.domain.coin.implementation.TradeUpdater; import lombok.RequiredArgsConstructor; @@ -29,6 +30,7 @@ public class PriceScheduler { private final PriceCreator priceCreator; private final TradeReader tradeReader; private final TradeCreator tradeCreator; + private final TradeUpdater tradeUpdater; private final CoinAccountReader coinAccountReader; private final CoinAccountCreator coinAccountCreator; @@ -79,7 +81,7 @@ private void processSellingTrade(Price newPrice) { CoinAccount tradingAccount = coinAccountReader.getById(sellingTrade.getCoinAccountId()); tradingAccount.sellCoin(sellingTrade.getCoinPrice(), sellingTrade.getCoinCount()); - sellingTrade.updateTradeStatus(TradeStatus.SOLD); + tradeUpdater.updateTradeStatus(sellingTrade, TradeStatus.SOLD); tradeCreator.create(sellingTrade); } } @@ -93,7 +95,7 @@ private void processBuyingTrade(Price newPrice) { CoinAccount tradingAccount = coinAccountReader.getById(buyingTrade.getCoinAccountId()); tradingAccount.buyCoin(buyingTrade.getCoinPrice(), buyingTrade.getCoinCount()); - buyingTrade.updateTradeStatus(TradeStatus.BOUGHT); + tradeUpdater.updateTradeStatus(buyingTrade, TradeStatus.BOUGHT); tradeCreator.create(buyingTrade); } } From afa13f15bacc5578e90c85580df0b8ff725331a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Tue, 30 Apr 2024 20:22:09 +0900 Subject: [PATCH 33/41] =?UTF-8?q?refactor(coin):=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/coin/implementation/CoinAccountReader.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountReader.java b/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountReader.java index d8d2ab00..80fcbe1b 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountReader.java +++ b/src/main/java/com/project/bumawiki/domain/coin/implementation/CoinAccountReader.java @@ -7,8 +7,6 @@ import com.project.bumawiki.domain.coin.domain.CoinAccount; import com.project.bumawiki.domain.coin.domain.repository.CoinAccountRepository; import com.project.bumawiki.global.annotation.Implementation; -import com.project.bumawiki.global.error.exception.BumawikiException; -import com.project.bumawiki.global.error.exception.ErrorCode; import lombok.RequiredArgsConstructor; @@ -23,8 +21,7 @@ public boolean existsByUserId(Long userId) { } public CoinAccount getById(Long id) { - return coinAccountRepository.findById(id) - .orElseThrow(() -> new BumawikiException(ErrorCode.COIN_ACCOUNT_NOT_FOUND_EXCEPTION)); + return coinAccountRepository.getById(id); } public CoinAccount getByUserId(Long userId) { From 2001bae96f28d799bc4607caac1c014ab911c72a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Tue, 30 Apr 2024 21:31:18 +0900 Subject: [PATCH 34/41] =?UTF-8?q?refactor(coin):=20=EC=9E=90=EC=9E=98?= =?UTF-8?q?=ED=95=9C=20=EB=B6=80=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/coin/domain/repository/PriceRepository.java | 3 --- .../bumawiki/domain/coin/service/CommandCoinService.java | 2 +- .../bumawiki/domain/coin/service/CommandCoinServiceTest.java | 5 +++-- .../bumawiki/domain/coin/service/QueryCoinServiceTest.java | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/project/bumawiki/domain/coin/domain/repository/PriceRepository.java b/src/main/java/com/project/bumawiki/domain/coin/domain/repository/PriceRepository.java index ae97a886..3fd00425 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/domain/repository/PriceRepository.java +++ b/src/main/java/com/project/bumawiki/domain/coin/domain/repository/PriceRepository.java @@ -22,9 +22,6 @@ default Price getRecentPrice() { .orElse(save( new Price(1000000L) )); - // .orElseThrow( - // PriceNotFoundException::new - // ); } @Query("select p from Price p where p.startedTime >= :twoWeeksAgo order by p.startedTime asc") diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java index 377b7b54..e15cf06b 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java @@ -114,7 +114,7 @@ public Long dailyCheck(User user) { long max = 200000; SecureRandom random = getRandomInstance(); - long randomNumber = (random.nextLong(max - min + 1) + min); + long randomNumber = random.nextLong(max - min + 1) + min; randomNumber -= randomNumber % 10000; CoinAccount account = coinAccountReader.getByUserId(user.getId()); diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index c3c3d987..0a91eb93 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -53,8 +53,9 @@ class 코인_계정_생성하기 { // then assertAll( () -> { - assertThat(coinAccountRepository.findByUserId(user.getId()).isPresent()).isEqualTo(true); - assertThat(coinAccountRepository.findByUserId(user.getId()).get().getUserId()).isEqualTo(user.getId()); + assertTrue(coinAccountRepository.findByUserId(user.getId()).isPresent()); + assertThat(coinAccountRepository.findByUserId(user.getId()).get().getUserId()) + .isEqualTo(user.getId()); } ); } diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java index 4d2f9683..d650270a 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java @@ -66,7 +66,7 @@ class 코인_계정_찾기 { } @RepeatedTest(REPEAT_COUNT) - void 코인_저장이_안되어있을때() { + void 코인_계정이_존재하지_않을_때() { User user = FixtureGenerator.getDefaultUserBuilder().sample(); userRepository.save(user); From 859a1c8b657d2bcafe0d04842c13812bef1147f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Tue, 30 Apr 2024 21:49:41 +0900 Subject: [PATCH 35/41] fix(coin): orElse -> orElseGet --- .../domain/coin/domain/repository/PriceRepository.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/project/bumawiki/domain/coin/domain/repository/PriceRepository.java b/src/main/java/com/project/bumawiki/domain/coin/domain/repository/PriceRepository.java index 3fd00425..bd8c775f 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/domain/repository/PriceRepository.java +++ b/src/main/java/com/project/bumawiki/domain/coin/domain/repository/PriceRepository.java @@ -19,9 +19,9 @@ public interface PriceRepository extends JpaRepository { default Price getRecentPrice() { return findTopOrderByStartedTime() - .orElse(save( - new Price(1000000L) - )); + .orElseGet(() -> + save(new Price(1000000L)) + ); } @Query("select p from Price p where p.startedTime >= :twoWeeksAgo order by p.startedTime asc") From 254e078746651121660284774f4b94a38c691f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Tue, 30 Apr 2024 21:50:57 +0900 Subject: [PATCH 36/41] =?UTF-8?q?refactor(coin):=20PriceScheduler=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EC=83=81?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/coin/service/PriceScheduler.java | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java b/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java index e6c16fc8..4aa062ba 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java @@ -4,6 +4,7 @@ import java.security.SecureRandom; import java.util.List; +import java.util.function.Predicate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -76,29 +77,32 @@ private void restartCoin() { private void processSellingTrade(Price newPrice) { List sellingTrades = tradeReader.findAllByTradeStatus(TradeStatus.SELLING); - for (Trade sellingTrade : sellingTrades) { - if (sellingTrade.getCoinPrice() <= newPrice.getPrice()) { - CoinAccount tradingAccount = coinAccountReader.getById(sellingTrade.getCoinAccountId()); - - tradingAccount.sellCoin(sellingTrade.getCoinPrice(), sellingTrade.getCoinCount()); - tradeUpdater.updateTradeStatus(sellingTrade, TradeStatus.SOLD); - tradeCreator.create(sellingTrade); - } - } + processTrade( + sellingTrades, + TradeStatus.SOLD, + (Trade trade) -> trade.getCoinPrice() <= newPrice.getPrice() + ); } private void processBuyingTrade(Price newPrice) { List buyingTrades = tradeReader.findAllByTradeStatus(TradeStatus.BUYING); - for (Trade buyingTrade : buyingTrades) { - if (buyingTrade.getCoinPrice() >= newPrice.getPrice()) { - CoinAccount tradingAccount = coinAccountReader.getById(buyingTrade.getCoinAccountId()); + processTrade( + buyingTrades, + TradeStatus.BOUGHT, + (Trade trade) -> trade.getCoinPrice() >= newPrice.getPrice() + ); + } + + private void processTrade(List trades, TradeStatus tradeStatus, Predicate p) { + for (Trade trade : trades) { + if (p.test(trade)) { + CoinAccount tradingAccount = coinAccountReader.getById(trade.getCoinAccountId()); - tradingAccount.buyCoin(buyingTrade.getCoinPrice(), buyingTrade.getCoinCount()); - tradeUpdater.updateTradeStatus(buyingTrade, TradeStatus.BOUGHT); - tradeCreator.create(buyingTrade); + tradingAccount.buyCoin(trade.getCoinPrice(), trade.getCoinCount()); + tradeUpdater.updateTradeStatus(trade, tradeStatus); + tradeCreator.create(trade); } } } - } From f9acb32c1035cbff91a34749ab16f64b384540b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Tue, 30 Apr 2024 21:58:05 +0900 Subject: [PATCH 37/41] =?UTF-8?q?refactor(coin):=20NoArgsConstructor=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java b/src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java index eae511f7..92af1f17 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java +++ b/src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java @@ -6,10 +6,8 @@ import jakarta.validation.constraints.Positive; import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.NoArgsConstructor; @Getter -@NoArgsConstructor @AllArgsConstructor public class TradeWithoutTradeStatusAndCoinAccountId { @NotNull From e6aa6a0b4e248efaa2b1675b5bc1e2c3c56502b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Thu, 2 May 2024 15:19:58 +0900 Subject: [PATCH 38/41] =?UTF-8?q?refactor(coin):=20=EB=9E=AD=ED=82=B9=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/coin/service/QueryCoinServiceTest.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java index d650270a..97a7f672 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java @@ -155,8 +155,21 @@ class 코인_계정_찾기 { List rankingResponses = queryCoinService.getRanking(PageRequest.of(0, 10)); + List toComparedRankingResponse = + coinAccountRepository.getRanking(PageRequest.of(0, 10), 1000000L) + .stream() + .map(ranking -> new RankingResponse( + ranking, + 1000000L, + userRepository.findById(ranking.getUserId()).get() + )) + .toList(); + // then - assertThat(rankingResponses.size()).isEqualTo(10); + assertAll( + () -> assertThat(rankingResponses.size()).isEqualTo(10), + () -> assertTrue(toComparedRankingResponse.containsAll(rankingResponses)) + ); } @RepeatedTest(REPEAT_COUNT) From ebe6f9427de6cc178c4f52be1c7ce008fc5efed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Thu, 2 May 2024 15:28:26 +0900 Subject: [PATCH 39/41] =?UTF-8?q?refactor(coin):=20randomPrice=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bumawiki/domain/coin/service/PriceScheduler.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java b/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java index 4aa062ba..a5d7bc5b 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/PriceScheduler.java @@ -20,6 +20,8 @@ import com.project.bumawiki.domain.coin.implementation.TradeCreator; import com.project.bumawiki.domain.coin.implementation.TradeReader; import com.project.bumawiki.domain.coin.implementation.TradeUpdater; +import com.project.bumawiki.global.error.exception.BumawikiException; +import com.project.bumawiki.global.error.exception.ErrorCode; import lombok.RequiredArgsConstructor; @@ -42,7 +44,10 @@ void changePrice() { long min = Math.max(recentPrice.getPrice() - CHANGE_MONEY_RANGE, 0L); SecureRandom random = getRandomInstance(); - long randomPrice = random.nextLong(max - min + 1L) + min; + long randomPrice = random + .longs(min, max) + .findFirst() + .orElseThrow(() -> new BumawikiException(ErrorCode.INTERNAL_SERVER_ERROR)); Price newPrice; if (randomPrice == 0) { restartCoin(); From 2344cb75619799161603d143609b56c9fb2b7554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Thu, 2 May 2024 15:48:37 +0900 Subject: [PATCH 40/41] refactor(coin): TradeWithoutTradeStatusAndCoinAccountId -> TradeVo --- ...atusAndCoinAccountId.java => TradeVo.java} | 2 +- .../coin/presentation/dto/TradeRequest.java | 6 +-- .../coin/service/CommandCoinService.java | 6 +-- .../coin/service/CommandCoinServiceTest.java | 50 +++++++++---------- .../coin/service/QueryCoinServiceTest.java | 6 +-- 5 files changed, 35 insertions(+), 35 deletions(-) rename src/main/java/com/project/bumawiki/domain/coin/domain/{TradeWithoutTradeStatusAndCoinAccountId.java => TradeVo.java} (91%) diff --git a/src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java b/src/main/java/com/project/bumawiki/domain/coin/domain/TradeVo.java similarity index 91% rename from src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java rename to src/main/java/com/project/bumawiki/domain/coin/domain/TradeVo.java index 92af1f17..e5e1f999 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/domain/TradeWithoutTradeStatusAndCoinAccountId.java +++ b/src/main/java/com/project/bumawiki/domain/coin/domain/TradeVo.java @@ -9,7 +9,7 @@ @Getter @AllArgsConstructor -public class TradeWithoutTradeStatusAndCoinAccountId { +public class TradeVo { @NotNull @Positive private Long coinPrice; diff --git a/src/main/java/com/project/bumawiki/domain/coin/presentation/dto/TradeRequest.java b/src/main/java/com/project/bumawiki/domain/coin/presentation/dto/TradeRequest.java index 8987eda4..d87feebb 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/presentation/dto/TradeRequest.java +++ b/src/main/java/com/project/bumawiki/domain/coin/presentation/dto/TradeRequest.java @@ -1,6 +1,6 @@ package com.project.bumawiki.domain.coin.presentation.dto; -import com.project.bumawiki.domain.coin.domain.TradeWithoutTradeStatusAndCoinAccountId; +import com.project.bumawiki.domain.coin.domain.TradeVo; import jakarta.validation.constraints.Positive; @@ -8,8 +8,8 @@ public record TradeRequest( @Positive Long coinPrice, @Positive Long coinCount ) { - public TradeWithoutTradeStatusAndCoinAccountId toEntity() { - return new TradeWithoutTradeStatusAndCoinAccountId( + public TradeVo toEntity() { + return new TradeVo( coinPrice, coinCount ); diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java index e15cf06b..4563d5e3 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java @@ -10,7 +10,7 @@ import com.project.bumawiki.domain.coin.domain.CoinAccount; import com.project.bumawiki.domain.coin.domain.Price; import com.project.bumawiki.domain.coin.domain.Trade; -import com.project.bumawiki.domain.coin.domain.TradeWithoutTradeStatusAndCoinAccountId; +import com.project.bumawiki.domain.coin.domain.TradeVo; import com.project.bumawiki.domain.coin.domain.type.TradeStatus; import com.project.bumawiki.domain.coin.implementation.CoinAccountCreator; import com.project.bumawiki.domain.coin.implementation.CoinAccountReader; @@ -49,7 +49,7 @@ public CoinAccount createCoinAccount(User user) { return coinAccountCreator.create(coinAccount); } - public Trade buyCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User user) { + public Trade buyCoin(TradeVo coinData, User user) { CoinAccount coinAccount = coinAccountReader.getByUserId(user.getId()); Price nowPrice = priceReader.getRecentPrice(); @@ -73,7 +73,7 @@ private void buyNow(Trade trade, CoinAccount coinAccount) { tradeUpdater.updateTradeStatus(trade, TradeStatus.BOUGHT); } - public Trade sellCoin(TradeWithoutTradeStatusAndCoinAccountId coinData, User user) { + public Trade sellCoin(TradeVo coinData, User user) { CoinAccount coinAccount = coinAccountReader.getByUserId(user.getId()); Price nowPrice = priceReader.getRecentPrice(); diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java index 0a91eb93..609edf21 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/CommandCoinServiceTest.java @@ -10,7 +10,7 @@ import com.project.bumawiki.domain.coin.domain.CoinAccount; import com.project.bumawiki.domain.coin.domain.Price; import com.project.bumawiki.domain.coin.domain.Trade; -import com.project.bumawiki.domain.coin.domain.TradeWithoutTradeStatusAndCoinAccountId; +import com.project.bumawiki.domain.coin.domain.TradeVo; import com.project.bumawiki.domain.coin.domain.repository.CoinAccountRepository; import com.project.bumawiki.domain.coin.domain.repository.PriceRepository; import com.project.bumawiki.domain.coin.domain.repository.TradeRepository; @@ -101,8 +101,8 @@ class 코인_구매하기 { .sample(); } - TradeWithoutTradeStatusAndCoinAccountId coinData = - new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + TradeVo coinData = + new TradeVo(coinPrice, coinCount); System.out.println(coinData.getCoinCount()); System.out.println(coinData.getCoinPrice()); @@ -142,8 +142,8 @@ class 코인_구매하기 { .sample(); } - TradeWithoutTradeStatusAndCoinAccountId coinData = - new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + TradeVo coinData = + new TradeVo(coinPrice, coinCount); CoinAccount coinAccount = new CoinAccount( user.getId(), @@ -193,8 +193,8 @@ class 코인_구매하기 { .sample(); } - TradeWithoutTradeStatusAndCoinAccountId coinData = - new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + TradeVo coinData = + new TradeVo(coinPrice, coinCount); CoinAccount coinAccount = new CoinAccount( user.getId(), @@ -245,8 +245,8 @@ class 코인_판매하기 { .sample(); } - TradeWithoutTradeStatusAndCoinAccountId coinData = - new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + TradeVo coinData = + new TradeVo(coinPrice, coinCount); CoinAccount coinAccount = new CoinAccount( user.getId(), @@ -259,8 +259,8 @@ class 코인_판매하기 { commandCoinService.buyCoin(coinData, user); - TradeWithoutTradeStatusAndCoinAccountId coinDataToSell = - new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount + 1); + TradeVo coinDataToSell = + new TradeVo(coinPrice, coinCount + 1); // when BumawikiException exception = assertThrows( @@ -293,8 +293,8 @@ class 코인_판매하기 { .sample(); } - TradeWithoutTradeStatusAndCoinAccountId coinData = - new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + TradeVo coinData = + new TradeVo(coinPrice, coinCount); CoinAccount coinAccount = new CoinAccount( user.getId(), @@ -307,8 +307,8 @@ class 코인_판매하기 { commandCoinService.buyCoin(coinData, user); - TradeWithoutTradeStatusAndCoinAccountId coinDataToSell = - new TradeWithoutTradeStatusAndCoinAccountId( + TradeVo coinDataToSell = + new TradeVo( coinPrice, FixtureGenerator.getDefaultLongArbitrary() .between(0L, coinAccount.getCoin()) @@ -352,8 +352,8 @@ class 코인_판매하기 { .sample(); } - TradeWithoutTradeStatusAndCoinAccountId coinData = - new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + TradeVo coinData = + new TradeVo(coinPrice, coinCount); CoinAccount coinAccount = new CoinAccount( user.getId(), @@ -366,8 +366,8 @@ class 코인_판매하기 { commandCoinService.buyCoin(coinData, user); - TradeWithoutTradeStatusAndCoinAccountId coinDataToSell = - new TradeWithoutTradeStatusAndCoinAccountId( + TradeVo coinDataToSell = + new TradeVo( coinPrice, FixtureGenerator.getDefaultLongArbitrary() .between(0L, coinAccount.getCoin()) @@ -409,8 +409,8 @@ class 거래_취소하기 { .sample(); } - TradeWithoutTradeStatusAndCoinAccountId coinData = - new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + TradeVo coinData = + new TradeVo(coinPrice, coinCount); CoinAccount coinAccount = new CoinAccount( user.getId(), @@ -449,8 +449,8 @@ class 거래_취소하기 { .sample(); } - TradeWithoutTradeStatusAndCoinAccountId coinData = - new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + TradeVo coinData = + new TradeVo(coinPrice, coinCount); CoinAccount coinAccount = new CoinAccount( user.getId(), @@ -496,8 +496,8 @@ class 거래_취소하기 { .sample(); } - TradeWithoutTradeStatusAndCoinAccountId coinData = - new TradeWithoutTradeStatusAndCoinAccountId(coinPrice, coinCount); + TradeVo coinData = + new TradeVo(coinPrice, coinCount); CoinAccount coinAccount = new CoinAccount( user.getId(), diff --git a/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java b/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java index 97a7f672..6230b58b 100644 --- a/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java +++ b/src/test/java/com/project/bumawiki/domain/coin/service/QueryCoinServiceTest.java @@ -16,7 +16,7 @@ import com.project.bumawiki.domain.coin.domain.CoinAccount; import com.project.bumawiki.domain.coin.domain.Price; import com.project.bumawiki.domain.coin.domain.Trade; -import com.project.bumawiki.domain.coin.domain.TradeWithoutTradeStatusAndCoinAccountId; +import com.project.bumawiki.domain.coin.domain.TradeVo; import com.project.bumawiki.domain.coin.domain.repository.CoinAccountRepository; import com.project.bumawiki.domain.coin.domain.repository.TradeRepository; import com.project.bumawiki.domain.coin.domain.type.TradeStatus; @@ -96,8 +96,8 @@ class 코인_계정_찾기 { coinAccountRepository.save(coinAccount); - TradeWithoutTradeStatusAndCoinAccountId coinData = - new TradeWithoutTradeStatusAndCoinAccountId(1000000L, 3L); + TradeVo coinData = + new TradeVo(1000000L, 3L); Trade trade = coinData.toTrade(coinAccount); From 01f544278d694854286056deecbba7289e8be2d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=ED=98=84=EC=9A=B0?= Date: Thu, 2 May 2024 15:59:52 +0900 Subject: [PATCH 41/41] =?UTF-8?q?refactor(coin):=20randomNumber=20?= =?UTF-8?q?=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8A=94=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=EC=9D=84=20=EB=A9=94=EC=84=9C=EB=93=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coin/service/CommandCoinService.java | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java b/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java index 4563d5e3..c8c4d4bd 100644 --- a/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java +++ b/src/main/java/com/project/bumawiki/domain/coin/service/CommandCoinService.java @@ -21,6 +21,8 @@ import com.project.bumawiki.domain.coin.implementation.TradeUpdater; import com.project.bumawiki.domain.coin.implementation.TradeValidator; import com.project.bumawiki.domain.user.domain.User; +import com.project.bumawiki.global.error.exception.BumawikiException; +import com.project.bumawiki.global.error.exception.ErrorCode; import lombok.RequiredArgsConstructor; @@ -110,12 +112,7 @@ public void cancelTrade(Long tradeId, User user) { } public Long dailyCheck(User user) { - long min = 50000; - long max = 200000; - - SecureRandom random = getRandomInstance(); - long randomNumber = random.nextLong(max - min + 1) + min; - randomNumber -= randomNumber % 10000; + long randomNumber = getRandomNumber(); CoinAccount account = coinAccountReader.getByUserId(user.getId()); @@ -126,4 +123,19 @@ public Long dailyCheck(User user) { return randomNumber; } + + private long getRandomNumber() { + long min = 50000; + long max = 200000; + + SecureRandom random = getRandomInstance(); + + long randomNumber = random + .longs(min, max) + .findFirst() + .orElseThrow(() -> new BumawikiException(ErrorCode.INTERNAL_SERVER_ERROR)); + randomNumber -= randomNumber % 10000; + + return randomNumber; + } }