From 293a07d1af159c7199ce99ff8357afdc18061a25 Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Wed, 23 Apr 2025 21:34:37 +0900 Subject: [PATCH 01/12] :recycle: refactor : reformat code --- .../org/runimo/runimo/hatch/controller/HatchController.java | 2 +- .../org/runimo/runimo/hatch/service/strategy/EqualRandom.java | 4 ++-- .../runimo/runimo/hatch/service/usecase/HatchUsecaseImpl.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/runimo/runimo/hatch/controller/HatchController.java b/src/main/java/org/runimo/runimo/hatch/controller/HatchController.java index 573c45e4..e7e53c7e 100644 --- a/src/main/java/org/runimo/runimo/hatch/controller/HatchController.java +++ b/src/main/java/org/runimo/runimo/hatch/controller/HatchController.java @@ -6,8 +6,8 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.runimo.runimo.common.response.SuccessResponse; -import org.runimo.runimo.hatch.service.dto.HatchEggResponse; import org.runimo.runimo.hatch.exception.HatchHttpResponseCode; +import org.runimo.runimo.hatch.service.dto.HatchEggResponse; import org.runimo.runimo.hatch.service.usecase.HatchUsecase; import org.runimo.runimo.user.controller.UserId; import org.springframework.http.HttpStatus; diff --git a/src/main/java/org/runimo/runimo/hatch/service/strategy/EqualRandom.java b/src/main/java/org/runimo/runimo/hatch/service/strategy/EqualRandom.java index 8cfc3a51..e4514905 100644 --- a/src/main/java/org/runimo/runimo/hatch/service/strategy/EqualRandom.java +++ b/src/main/java/org/runimo/runimo/hatch/service/strategy/EqualRandom.java @@ -4,9 +4,9 @@ public class EqualRandom implements HatchRandomStrategy { - private final SecureRandom secureRandom = new SecureRandom(); // TODO : 빈으로 관리? + private final SecureRandom secureRandom = new SecureRandom(); - private int size; + private final int size; public EqualRandom(int size) { this.size = size; diff --git a/src/main/java/org/runimo/runimo/hatch/service/usecase/HatchUsecaseImpl.java b/src/main/java/org/runimo/runimo/hatch/service/usecase/HatchUsecaseImpl.java index 24e4bccb..44d97c79 100644 --- a/src/main/java/org/runimo/runimo/hatch/service/usecase/HatchUsecaseImpl.java +++ b/src/main/java/org/runimo/runimo/hatch/service/usecase/HatchUsecaseImpl.java @@ -1,10 +1,10 @@ package org.runimo.runimo.hatch.service.usecase; import lombok.RequiredArgsConstructor; -import org.runimo.runimo.hatch.service.dto.HatchEggResponse; import org.runimo.runimo.hatch.exception.HatchException; import org.runimo.runimo.hatch.exception.HatchHttpResponseCode; import org.runimo.runimo.hatch.service.HatchClient; +import org.runimo.runimo.hatch.service.dto.HatchEggResponse; import org.runimo.runimo.item.domain.Egg; import org.runimo.runimo.item.service.ItemFinder; import org.runimo.runimo.runimo.domain.Runimo; From 32654aa406468f0ab33c5abad055aa49ea5a0f98 Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Wed, 23 Apr 2025 21:40:51 +0900 Subject: [PATCH 02/12] :sparkles: feat : create `EggType` entity --- .../runimo/runimo/item/domain/EggType.java | 57 +++++++++++++------ 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/runimo/runimo/item/domain/EggType.java b/src/main/java/org/runimo/runimo/item/domain/EggType.java index 84d3ca5e..a9428240 100644 --- a/src/main/java/org/runimo/runimo/item/domain/EggType.java +++ b/src/main/java/org/runimo/runimo/item/domain/EggType.java @@ -1,30 +1,55 @@ package org.runimo.runimo.item.domain; -import java.util.Arrays; -import java.util.List; +import static org.runimo.runimo.common.GlobalConsts.EMPTYFIELD; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; +import org.runimo.runimo.common.BaseEntity; +@Table(name = "egg_type") +@Entity @Getter -public enum EggType { - MADANG("A100", "마당", 0L), - FOREST("A101", "숲", 30000L), -// GRASSLAND("A102", "초원", 50000L), - ; +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class EggType extends BaseEntity { - private final String code; - private final String name; - private final Long requiredDistanceInMeters; + public static final EggType EMPTY = new EggType(EMPTYFIELD, EMPTYFIELD, 0L, 0); + @Column(name = "name", nullable = false) + private String name; + @Column(name = "code", nullable = false) + private String code; + @Column(name = "required_distance_in_meters", nullable = false) + private Long requiredDistanceInMeters; + @Column(name = "level", nullable = false) + private Integer level; - EggType(String code, String name, Long requiredDistanceInMeters) { - this.code = code; + @Builder + private EggType(String name, String code, Long requiredDistanceInMeters, Integer eggLevel) { this.name = name; + this.code = code; + if (requiredDistanceInMeters < 0) { + throw new IllegalArgumentException("알의 요구 거리(미터)는 0보다 작을 수 없습니다."); + } this.requiredDistanceInMeters = requiredDistanceInMeters; + if (eggLevel < 0) { + throw new IllegalArgumentException("알의 레벨은 0보다 작을 수 없습니다."); + } + this.level = eggLevel; } - public static List getUnLockedEggTypes(final Long distance) { - return Arrays.stream(EggType.values()) - .filter(type -> type.requiredDistanceInMeters < distance) - .toList(); + public static EggType of(String name, String code, Long requiredDistanceInMeters, + Integer eggLevel) { + return EggType.builder() + .name(name) + .code(code) + .requiredDistanceInMeters(requiredDistanceInMeters) + .eggLevel(eggLevel) + .build(); } + } From 23f9f7169e8beb94bc3d88e58637e909a923444d Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Wed, 23 Apr 2025 21:41:29 +0900 Subject: [PATCH 03/12] :sparkles: feat : update `EggType` field from enum to entity; relate `@OneToOne` --- .../java/org/runimo/runimo/item/domain/Egg.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/runimo/runimo/item/domain/Egg.java b/src/main/java/org/runimo/runimo/item/domain/Egg.java index aca403a6..1ed2972c 100644 --- a/src/main/java/org/runimo/runimo/item/domain/Egg.java +++ b/src/main/java/org/runimo/runimo/item/domain/Egg.java @@ -5,8 +5,9 @@ import jakarta.persistence.Column; import jakarta.persistence.DiscriminatorValue; import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -18,10 +19,10 @@ @DiscriminatorValue("EGG") public class Egg extends Item { - public static final Egg EMPTY = new Egg(EMPTYFIELD, EMPTYFIELD, EMPTYFIELD, EMPTYFIELD, null, - 0L); - @Column(name = "egg_type") - @Enumerated(EnumType.STRING) + public static final Egg EMPTY = new Egg(EMPTYFIELD, EMPTYFIELD, EMPTYFIELD, EMPTYFIELD, + EggType.EMPTY, 0L); + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "egg_type_id", referencedColumnName = "id") private EggType eggType; @Column(name = "hatch_require_amount") private Long hatchRequireAmount; @@ -33,4 +34,8 @@ public Egg(String itemCode, String name, String description, String imgUrl, EggT this.eggType = eggType; this.hatchRequireAmount = hatchRequireAmount; } + + public boolean isEmpty() { + return this == EMPTY; + } } \ No newline at end of file From 88e5e508247bfdc5647ca4e9db9ae167801cd2ab Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Wed, 23 Apr 2025 21:46:02 +0900 Subject: [PATCH 04/12] :sparkles: feat : replace enum to `EggType` entity --- .../runimo/hatch/service/HatchClient.java | 25 ++---- .../runimo/hatch/service/HatchContext.java | 11 ++- .../item/repository/EggTypeRepository.java | 16 ++++ .../item/repository/ItemRepository.java | 4 +- .../runimo/rewards/service/RewardService.java | 3 +- .../rewards/service/dto/RewardResponse.java | 4 +- .../rewards/service/eggs/EggGrantService.java | 4 +- .../runimo/domain/RunimoDefinition.java | 9 +- .../RunimoDefinitionRepository.java | 15 +++- .../service/dto/RunimoTypeSimpleModel.java | 84 +++++-------------- .../service/dto/response/RunimoTypeGroup.java | 3 +- .../service/dto/response/RunimoTypeInfo.java | 8 ++ .../service/usecase/RunimoUsecaseImpl.java | 32 +++++-- 13 files changed, 111 insertions(+), 107 deletions(-) create mode 100644 src/main/java/org/runimo/runimo/item/repository/EggTypeRepository.java diff --git a/src/main/java/org/runimo/runimo/hatch/service/HatchClient.java b/src/main/java/org/runimo/runimo/hatch/service/HatchClient.java index 870bec35..98636870 100644 --- a/src/main/java/org/runimo/runimo/hatch/service/HatchClient.java +++ b/src/main/java/org/runimo/runimo/hatch/service/HatchClient.java @@ -1,6 +1,5 @@ package org.runimo.runimo.hatch.service; -import java.util.ArrayList; import java.util.List; import lombok.RequiredArgsConstructor; import org.runimo.runimo.hatch.exception.HatchException; @@ -8,8 +7,8 @@ import org.runimo.runimo.hatch.service.strategy.EqualRandom; import org.runimo.runimo.hatch.service.strategy.HatchRandomStrategy; import org.runimo.runimo.item.domain.EggType; +import org.runimo.runimo.item.repository.EggTypeRepository; import org.runimo.runimo.runimo.domain.RunimoDefinition; -import org.runimo.runimo.runimo.domain.runimo_type.RunimoType; import org.runimo.runimo.runimo.repository.RunimoDefinitionRepository; import org.springframework.stereotype.Service; @@ -18,12 +17,13 @@ public class HatchClient { private final RunimoDefinitionRepository runimoDefinitionRepository; + private final EggTypeRepository eggTypeRepository; public RunimoDefinition getRandomRunimoDefinition(EggType eggType) { HatchContext hatchContext = new HatchContext(); // 나올 수 있는 전체 러니모 풀 생성 - List runimoTypePool = generateRunimoTypePool(eggType); + List runimoTypePool = generateRunimoPoolCoveringLowerLevel(eggType); // 부화 확률 전략 생성 HatchRandomStrategy hatchRandomStrategy = new EqualRandom(runimoTypePool.size()); @@ -33,24 +33,15 @@ public RunimoDefinition getRandomRunimoDefinition(EggType eggType) { hatchContext.setHatchContext(runimoTypePool); // 부화 - RunimoType chosenRunimoType = hatchContext.execute(); + Long chosenRunimoId = hatchContext.execute(); - RunimoDefinition runimoDefinition = runimoDefinitionRepository.findByCode( - chosenRunimoType.getCode()) + return runimoDefinitionRepository.findById(chosenRunimoId) .orElseThrow(() -> HatchException.of( HatchHttpResponseCode.HATCH_RUNIMO_NOT_FOUND_INTERNAL_ERROR)); - - return runimoDefinition; } - private List generateRunimoTypePool(EggType eggType) { - int eggEndIdx = eggType.ordinal(); - EggRunimo[] eggRunimos = EggRunimo.values(); - - List runimoTypes = new ArrayList<>(); - for (int i = 0; i <= eggEndIdx; i++) { - runimoTypes.addAll(List.of(eggRunimos[i].getRunimoTypes())); - } - return runimoTypes; + private List generateRunimoPoolCoveringLowerLevel(EggType eggType) { + List eggTypes = eggTypeRepository.findEggTypeByLevelLessThan(eggType.getLevel()); + return runimoDefinitionRepository.findIdInEggTypes(eggTypes); } } diff --git a/src/main/java/org/runimo/runimo/hatch/service/HatchContext.java b/src/main/java/org/runimo/runimo/hatch/service/HatchContext.java index 68638635..3a1ba203 100644 --- a/src/main/java/org/runimo/runimo/hatch/service/HatchContext.java +++ b/src/main/java/org/runimo/runimo/hatch/service/HatchContext.java @@ -2,20 +2,19 @@ import java.util.List; import org.runimo.runimo.hatch.service.strategy.HatchRandomStrategy; -import org.runimo.runimo.runimo.domain.runimo_type.RunimoType; public class HatchContext { - private List runimoTypePool; + private List runimoPool; private HatchRandomStrategy hatchRandomStrategy; - public RunimoType execute() { + public Long execute() { int chosenIdx = hatchRandomStrategy.generateNumber(); - return runimoTypePool.get(chosenIdx); + return runimoPool.get(chosenIdx); } - public void setHatchContext(List runimoTypePool) { - this.runimoTypePool = runimoTypePool; + public void setHatchContext(List runimoIdPool) { + this.runimoPool = runimoIdPool; } public void setHatchStrategy(HatchRandomStrategy hatchRandomStrategy) { diff --git a/src/main/java/org/runimo/runimo/item/repository/EggTypeRepository.java b/src/main/java/org/runimo/runimo/item/repository/EggTypeRepository.java new file mode 100644 index 00000000..00f44cf1 --- /dev/null +++ b/src/main/java/org/runimo/runimo/item/repository/EggTypeRepository.java @@ -0,0 +1,16 @@ +package org.runimo.runimo.item.repository; + +import java.util.List; +import org.runimo.runimo.item.domain.EggType; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +public interface EggTypeRepository extends JpaRepository { + + @Query("select et from EggType et order by et.id") + List findAllOrderById(); + + List findEggTypeByRequiredDistanceInMetersLessThanEqual(Long totalDistanceInMeters); + + List findEggTypeByLevelLessThan(Integer level); +} \ No newline at end of file diff --git a/src/main/java/org/runimo/runimo/item/repository/ItemRepository.java b/src/main/java/org/runimo/runimo/item/repository/ItemRepository.java index 40666ef2..534a5fc2 100644 --- a/src/main/java/org/runimo/runimo/item/repository/ItemRepository.java +++ b/src/main/java/org/runimo/runimo/item/repository/ItemRepository.java @@ -15,6 +15,6 @@ public interface ItemRepository extends JpaRepository { @Query("select i.id from Item i") List findAllItemIds(); - @Query("select e from Egg e where e.eggType = :eggtype") - Optional findByEggType(EggType eggtype); + @Query("select e from Egg e where e.eggType = :eggType") + Optional findByEggType(EggType eggType); } diff --git a/src/main/java/org/runimo/runimo/rewards/service/RewardService.java b/src/main/java/org/runimo/runimo/rewards/service/RewardService.java index 5a99eb53..1f529f9b 100644 --- a/src/main/java/org/runimo/runimo/rewards/service/RewardService.java +++ b/src/main/java/org/runimo/runimo/rewards/service/RewardService.java @@ -35,7 +35,8 @@ public RewardResponse claimReward(RewardClaimCommand command) { Egg grantedEgg = rewardEgg(command); Long grantedLoveAmount = loveGrantService.grantLoveToUserWithDistance(runningRecord); runningRecord.reward(command.userId()); - return new RewardResponse(grantedEgg.getItemCode(), grantedEgg.getEggType(), + return new RewardResponse(!grantedEgg.isEmpty(), grantedEgg.getItemCode(), + grantedEgg.getEggType().getName(), grantedLoveAmount); } diff --git a/src/main/java/org/runimo/runimo/rewards/service/dto/RewardResponse.java b/src/main/java/org/runimo/runimo/rewards/service/dto/RewardResponse.java index 2fbe9fcd..a007954b 100644 --- a/src/main/java/org/runimo/runimo/rewards/service/dto/RewardResponse.java +++ b/src/main/java/org/runimo/runimo/rewards/service/dto/RewardResponse.java @@ -1,10 +1,10 @@ package org.runimo.runimo.rewards.service.dto; -import org.runimo.runimo.item.domain.EggType; public record RewardResponse( + Boolean isRewarded, String eggCode, - EggType eggType, + String eggType, Long lovePointAmount ) { diff --git a/src/main/java/org/runimo/runimo/rewards/service/eggs/EggGrantService.java b/src/main/java/org/runimo/runimo/rewards/service/eggs/EggGrantService.java index e9704046..fb70d3ab 100644 --- a/src/main/java/org/runimo/runimo/rewards/service/eggs/EggGrantService.java +++ b/src/main/java/org/runimo/runimo/rewards/service/eggs/EggGrantService.java @@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor; import org.runimo.runimo.item.domain.Egg; import org.runimo.runimo.item.domain.EggType; +import org.runimo.runimo.item.repository.EggTypeRepository; import org.runimo.runimo.item.service.EggFactory; import org.runimo.runimo.user.domain.User; import org.runimo.runimo.user.service.UserItemProcessor; @@ -19,6 +20,7 @@ public class EggGrantService { private static final Long DEFAULT_REWARD_EGG_AMOUNT = 1L; private final EggFactory eggFactory; private final UserItemProcessor userItemProcessor; + private final EggTypeRepository eggTypeRepository; @Transactional public void grantGreetingEggToUser(User user) { @@ -31,7 +33,7 @@ public void grantGreetingEggToUser(User user) { @Transactional public Egg grantRandomEggToUser(User user) { - List unLockedEggTypes = EggType.getUnLockedEggTypes( + List unLockedEggTypes = eggTypeRepository.findEggTypeByRequiredDistanceInMetersLessThanEqual( user.getTotalDistanceInMeters()); Egg grantedEgg = eggFactory.createEggRandomly(unLockedEggTypes); userItemProcessor.updateItemQuantity(user.getId(), grantedEgg.getId(), diff --git a/src/main/java/org/runimo/runimo/runimo/domain/RunimoDefinition.java b/src/main/java/org/runimo/runimo/runimo/domain/RunimoDefinition.java index 0c67b63d..8d5408b1 100644 --- a/src/main/java/org/runimo/runimo/runimo/domain/RunimoDefinition.java +++ b/src/main/java/org/runimo/runimo/runimo/domain/RunimoDefinition.java @@ -2,8 +2,8 @@ import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; import jakarta.persistence.Table; import lombok.AccessLevel; import lombok.Builder; @@ -30,8 +30,9 @@ public class RunimoDefinition extends BaseEntity { @Column(name = "img_url") private String imgUrl; - @Enumerated(EnumType.STRING) - @Column(name = "egg_type", nullable = false) + + @OneToOne + @JoinColumn(name = "egg_type_id", nullable = false) private EggType type; @Builder diff --git a/src/main/java/org/runimo/runimo/runimo/repository/RunimoDefinitionRepository.java b/src/main/java/org/runimo/runimo/runimo/repository/RunimoDefinitionRepository.java index d8bb5590..40792c44 100644 --- a/src/main/java/org/runimo/runimo/runimo/repository/RunimoDefinitionRepository.java +++ b/src/main/java/org/runimo/runimo/runimo/repository/RunimoDefinitionRepository.java @@ -2,6 +2,7 @@ import java.util.List; import java.util.Optional; +import org.runimo.runimo.item.domain.EggType; import org.runimo.runimo.runimo.domain.RunimoDefinition; import org.runimo.runimo.runimo.service.dto.RunimoTypeSimpleModel; import org.springframework.data.jpa.repository.JpaRepository; @@ -12,8 +13,16 @@ public interface RunimoDefinitionRepository extends JpaRepository findByCode(String runimoCode); @Query(""" - select new org.runimo.runimo.runimo.service.dto.RunimoTypeSimpleModel(rd.name, rd.imgUrl, rd.code, rd.type, rd.description) - from RunimoDefinition rd + select rd.id from RunimoDefinition rd + where rd.type in :eggTypes """) - List findAllToSimpleModel(); + List findIdInEggTypes(List eggTypes); + + @Query(""" + select new org.runimo.runimo.runimo.service.dto.RunimoTypeSimpleModel( + rd.type.id, rd.code, rd.name, rd.imgUrl, rd.description + ) from RunimoDefinition rd + where rd.type in :eggTypes + """) + List findRunimoSimpleTypeModelByType(List eggTypes); } diff --git a/src/main/java/org/runimo/runimo/runimo/service/dto/RunimoTypeSimpleModel.java b/src/main/java/org/runimo/runimo/runimo/service/dto/RunimoTypeSimpleModel.java index 63540e8c..c0a3f87b 100644 --- a/src/main/java/org/runimo/runimo/runimo/service/dto/RunimoTypeSimpleModel.java +++ b/src/main/java/org/runimo/runimo/runimo/service/dto/RunimoTypeSimpleModel.java @@ -1,72 +1,26 @@ package org.runimo.runimo.runimo.service.dto; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.runimo.runimo.item.domain.EggType; -import org.runimo.runimo.runimo.service.dto.response.RunimoTypeGroup; -import org.runimo.runimo.runimo.service.dto.response.RunimoTypeInfo; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; -public record RunimoTypeSimpleModel( - String name, - String imgUrl, - String code, - String eggType, - String description -) { - - public RunimoTypeSimpleModel(String name, String imgUrl, String code, EggType eggType, - String description) { - this(name, imgUrl, code, eggType.getName(), description); - } - - public static List toDtoList(List modelList) { - Map> runimoDtoMap = toRunimoTypeMap( - modelList); - - List runimoTypeGroups = toRunimoTypeGroups( - runimoDtoMap); - - return runimoTypeGroups; - } - - private RunimoTypeInfo toDto() { - return new RunimoTypeInfo(name, imgUrl, code, description); - } +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class RunimoTypeSimpleModel{ + private Long eggTypeId; + private String code; + private String name; + private String imgUrl; + private String description; - /** - * EggType enum 클래스 순서 기준으로 EggType 별 러니모 그룹목록 생성 - */ - private static List toRunimoTypeGroups( - Map> runimoDtoMap) { - - List runimoTypeGroups = new ArrayList<>(); - for (EggType eggType : EggType.values()) { - String key = eggType.getName(); - runimoTypeGroups.add(new RunimoTypeGroup(key, runimoDtoMap.get(key))); - } - - return runimoTypeGroups; - } - - /** - * EggType 별 러니모 분류 map 생성 - */ - private static Map> toRunimoTypeMap( - List modelList) { - - Map> runimoTypeDtos = new HashMap<>(); - for (RunimoTypeSimpleModel model : modelList) { - String key = model.eggType(); - if (!runimoTypeDtos.containsKey(key)) { - runimoTypeDtos.put(key, new ArrayList<>()); - } - runimoTypeDtos.get(key).add(model.toDto()); - } - - return runimoTypeDtos; + public RunimoTypeSimpleModel(Long eggTypeId, String code, String name, String imgUrl, + String description) { + this.eggTypeId = eggTypeId; + this.code = code; + this.name = name; + this.imgUrl = imgUrl; + this.description = description; } - } + diff --git a/src/main/java/org/runimo/runimo/runimo/service/dto/response/RunimoTypeGroup.java b/src/main/java/org/runimo/runimo/runimo/service/dto/response/RunimoTypeGroup.java index f4e409ce..01cb0e52 100644 --- a/src/main/java/org/runimo/runimo/runimo/service/dto/response/RunimoTypeGroup.java +++ b/src/main/java/org/runimo/runimo/runimo/service/dto/response/RunimoTypeGroup.java @@ -7,7 +7,8 @@ public record RunimoTypeGroup( @Schema(description = "러니모가 태어난 알 속성", example = "마당") String eggType, - + @Schema(description = "러니모를 해금하기 위한 누적 거리", example = "10000") + Long eggRequiredDistanceInMeters, @Schema(description = "해당 알에서 태어나는 러니모 목록") List runimoTypes ) { diff --git a/src/main/java/org/runimo/runimo/runimo/service/dto/response/RunimoTypeInfo.java b/src/main/java/org/runimo/runimo/runimo/service/dto/response/RunimoTypeInfo.java index ee19c2b0..8c0a31fd 100644 --- a/src/main/java/org/runimo/runimo/runimo/service/dto/response/RunimoTypeInfo.java +++ b/src/main/java/org/runimo/runimo/runimo/service/dto/response/RunimoTypeInfo.java @@ -1,6 +1,8 @@ package org.runimo.runimo.runimo.service.dto.response; import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import org.runimo.runimo.runimo.service.dto.RunimoTypeSimpleModel; public record RunimoTypeInfo( @Schema(description = "러니모 이름", example = "토끼") @@ -16,4 +18,10 @@ public record RunimoTypeInfo( String description ) { + public static List from (final List modelList) { + return modelList.stream().map(i -> + new RunimoTypeInfo(i.getName(), i.getImgUrl(), i.getCode(), i.getDescription()) + ).toList(); + } + } diff --git a/src/main/java/org/runimo/runimo/runimo/service/usecase/RunimoUsecaseImpl.java b/src/main/java/org/runimo/runimo/runimo/service/usecase/RunimoUsecaseImpl.java index b6e80cf1..bef662f9 100644 --- a/src/main/java/org/runimo/runimo/runimo/service/usecase/RunimoUsecaseImpl.java +++ b/src/main/java/org/runimo/runimo/runimo/service/usecase/RunimoUsecaseImpl.java @@ -1,13 +1,14 @@ package org.runimo.runimo.runimo.service.usecase; import java.util.List; +import java.util.Map; import java.util.NoSuchElementException; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.runimo.runimo.hatch.exception.HatchException; import org.runimo.runimo.hatch.exception.HatchHttpResponseCode; -import org.runimo.runimo.runimo.service.dto.response.GetMyRunimoListResponse; -import org.runimo.runimo.runimo.service.dto.response.GetRunimoTypeListResponse; -import org.runimo.runimo.runimo.service.dto.response.SetMainRunimoResponse; +import org.runimo.runimo.item.domain.EggType; +import org.runimo.runimo.item.repository.EggTypeRepository; import org.runimo.runimo.runimo.domain.Runimo; import org.runimo.runimo.runimo.exception.RunimoException; import org.runimo.runimo.runimo.exception.RunimoHttpResponseCode; @@ -15,6 +16,11 @@ import org.runimo.runimo.runimo.repository.RunimoRepository; import org.runimo.runimo.runimo.service.dto.RunimoSimpleModel; import org.runimo.runimo.runimo.service.dto.RunimoTypeSimpleModel; +import org.runimo.runimo.runimo.service.dto.response.GetMyRunimoListResponse; +import org.runimo.runimo.runimo.service.dto.response.GetRunimoTypeListResponse; +import org.runimo.runimo.runimo.service.dto.response.RunimoTypeGroup; +import org.runimo.runimo.runimo.service.dto.response.RunimoTypeInfo; +import org.runimo.runimo.runimo.service.dto.response.SetMainRunimoResponse; import org.runimo.runimo.user.domain.User; import org.runimo.runimo.user.service.UserFinder; import org.springframework.stereotype.Service; @@ -28,6 +34,7 @@ public class RunimoUsecaseImpl implements RunimoUsecase { private final RunimoRepository runimoRepository; private final UserFinder userFinder; private final RunimoDefinitionRepository runimoDefinitionRepository; + private final EggTypeRepository eggTypeRepository; public GetMyRunimoListResponse getMyRunimoList(Long userId) { List models = runimoRepository.findAllByUserId(userId); @@ -55,8 +62,23 @@ public SetMainRunimoResponse setMainRunimo(Long userId, Long runimoId) { @Override public GetRunimoTypeListResponse getRunimoTypeList() { - List models = runimoDefinitionRepository.findAllToSimpleModel(); - return new GetRunimoTypeListResponse(RunimoTypeSimpleModel.toDtoList(models)); + List eggTypes = eggTypeRepository.findAllOrderById(); + + Map> runimoTypeInfos = eggTypes.stream() + .collect(Collectors.toMap( + EggType::getId, + type -> runimoDefinitionRepository.findRunimoSimpleTypeModelByType(List.of(type)) + )); + + List runimoTypeGroups = eggTypes.stream() + .map(type -> new RunimoTypeGroup( + type.getName(), + type.getRequiredDistanceInMeters(), + RunimoTypeInfo.from(runimoTypeInfos.get(type.getId())) + )) + .toList(); + + return new GetRunimoTypeListResponse(runimoTypeGroups); } } From 4a004e9c6dcb7042224bf1c49fed804289e37de4 Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Wed, 23 Apr 2025 21:46:34 +0900 Subject: [PATCH 05/12] :recycle: refactor : use egg-code instead of type --- .../runimo/user/repository/UserItemRepository.java | 11 +++++------ .../runimo/runimo/user/service/UserItemFinder.java | 10 ++-------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/runimo/runimo/user/repository/UserItemRepository.java b/src/main/java/org/runimo/runimo/user/repository/UserItemRepository.java index d910b545..1b31282a 100644 --- a/src/main/java/org/runimo/runimo/user/repository/UserItemRepository.java +++ b/src/main/java/org/runimo/runimo/user/repository/UserItemRepository.java @@ -4,7 +4,6 @@ import jakarta.persistence.QueryHint; import java.util.List; import java.util.Optional; -import org.runimo.runimo.item.domain.EggType; import org.runimo.runimo.user.domain.UserItem; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Lock; @@ -23,14 +22,14 @@ public interface UserItemRepository extends JpaRepository { @Query("select ui from UserItem ui where ui.userId = :userId and ui.itemId = :itemId") Optional findByUserIdAndItemIdForUpdate(Long userId, Long itemId); - @Query("select ui " + - "from UserItem ui " + - "join Egg e on ui.itemId = e.id " + - "where ui.userId = :userId and e.eggType = :eggType") - Optional findByUserIdAndEggType(Long userId, EggType eggType); @Query("select ui from UserItem ui " + "join Egg e on ui.itemId = e.id " + "where ui.userId = :userId") List findAllEggsByUserId(Long userId); + + @Query("select ui from UserItem ui " + + "join Egg e on ui.itemId = e.id " + + "where ui.userId = :userId and e.itemCode = :eggCode") + Optional findByUserIdAndEggCode(Long userId, String eggCode); } diff --git a/src/main/java/org/runimo/runimo/user/service/UserItemFinder.java b/src/main/java/org/runimo/runimo/user/service/UserItemFinder.java index f4489c59..df56000d 100644 --- a/src/main/java/org/runimo/runimo/user/service/UserItemFinder.java +++ b/src/main/java/org/runimo/runimo/user/service/UserItemFinder.java @@ -3,7 +3,6 @@ import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; -import org.runimo.runimo.item.domain.EggType; import org.runimo.runimo.user.domain.UserItem; import org.runimo.runimo.user.repository.UserItemRepository; import org.springframework.stereotype.Component; @@ -21,13 +20,8 @@ public List findEggsByUserId(Long userId) { } @Transactional(readOnly = true) - public Optional findEggByUserIdAndEggType(Long userId, EggType eggType) { - return userItemRepository.findByUserIdAndEggType(userId, eggType); - } - - @Transactional(readOnly = true) - public Optional findByUserIdAndItemId(Long userId, Long itemId) { - return userItemRepository.findByUserIdAndItemId(userId, itemId); + public Optional findEggByUserIdAndEggCode(Long userId, String eggCode) { + return userItemRepository.findByUserIdAndEggCode(userId, eggCode); } @Transactional From e829e1aca1136db87c05651fdcba3f25df3db2e0 Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Wed, 23 Apr 2025 21:47:00 +0900 Subject: [PATCH 06/12] :recycle: refactor : use `GREETING_EGG_ID` for creating Greeting Egg --- src/main/java/org/runimo/runimo/item/service/EggFactory.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/runimo/runimo/item/service/EggFactory.java b/src/main/java/org/runimo/runimo/item/service/EggFactory.java index 298cf9d1..489b4cfc 100644 --- a/src/main/java/org/runimo/runimo/item/service/EggFactory.java +++ b/src/main/java/org/runimo/runimo/item/service/EggFactory.java @@ -13,11 +13,12 @@ @RequiredArgsConstructor public class EggFactory { + private static final Long GREETING_EGG_ID = 1L; private final ItemFinder itemFinder; private final EggTypeRandomGenerator eggTypeRandomGenerator; public Egg createGreetingEgg() { - return itemFinder.findEggByEggType(EggType.MADANG) + return (Egg) itemFinder.findById(GREETING_EGG_ID) .orElseThrow(RuntimeException::new); } From 8bf87a849402d3254512694c0f0ae400ec4a6d48 Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Wed, 23 Apr 2025 22:08:01 +0900 Subject: [PATCH 07/12] :hammer: chore : update ddl, dml scripts --- src/main/resources/sql/schema.sql | 75 ++++++++++++------- src/test/resources/sql/egg_data.sql | 16 ++-- .../sql/get_my_runimo_list_test_data.sql | 8 -- src/test/resources/sql/hatch_test_data.sql | 25 ------- .../sql/incubating_egg_test_data.sql | 4 +- src/test/resources/sql/main_view_data.sql | 38 +++++----- src/test/resources/sql/schema.sql | 75 ++++++++++++------- .../sql/set_main_runimo_test_data.sql | 8 -- .../resources/sql/user_item_test_data.sql | 11 --- .../resources/sql/user_mypage_test_data.sql | 8 -- 10 files changed, 131 insertions(+), 137 deletions(-) diff --git a/src/main/resources/sql/schema.sql b/src/main/resources/sql/schema.sql index f5565007..ed638e7b 100644 --- a/src/main/resources/sql/schema.sql +++ b/src/main/resources/sql/schema.sql @@ -1,5 +1,6 @@ SET FOREIGN_KEY_CHECKS = 0; +DROP TABLE IF EXISTS egg_type; DROP TABLE IF EXISTS signup_token; DROP TABLE IF EXISTS apple_user_token; DROP TABLE IF EXISTS user_token; @@ -68,22 +69,22 @@ CREATE TABLE `oauth_account` CREATE TABLE `apple_user_token` ( - `id` BIGINT PRIMARY KEY AUTO_INCREMENT, - `user_id` BIGINT NOT NULL, + `id` BIGINT PRIMARY KEY AUTO_INCREMENT, + `user_id` BIGINT NOT NULL, `refresh_token` VARCHAR(255) NOT NULL, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `deleted_at` TIMESTAMP NULL, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `deleted_at` TIMESTAMP NULL, FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ); CREATE TABLE `signup_token` ( - `token` VARCHAR(255) PRIMARY KEY NOT NULL UNIQUE , - `provider_id` VARCHAR(255) NOT NULL, + `token` VARCHAR(255) PRIMARY KEY NOT NULL UNIQUE, + `provider_id` VARCHAR(255) NOT NULL, `refresh_token` VARCHAR(255), - `provider` VARCHAR(255), - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP + `provider` VARCHAR(255), + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); @@ -115,13 +116,26 @@ CREATE TABLE `item` `item_type` VARCHAR(255) NOT NULL, `img_url` VARCHAR(255), `dtype` VARCHAR(255), - `egg_type` VARCHAR(255), + `egg_type_id` BIGINT, `hatch_require_amount` BIGINT, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `deleted_at` TIMESTAMP NULL ); +CREATE TABLE `egg_type` +( + `id` INTEGER PRIMARY KEY AUTO_INCREMENT, + `name` VARCHAR(64) NOT NULL, + `code` VARCHAR(64) NOT NULL, + `required_distance_in_meters` BIGINT, + `level` INTEGER, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `deleted_at` TIMESTAMP NULL + +); + CREATE TABLE `item_activity` ( `id` INTEGER PRIMARY KEY AUTO_INCREMENT, @@ -165,10 +179,10 @@ CREATE TABLE `runimo_definition` `code` VARCHAR(255), `description` VARCHAR(255), `img_url` varchar(255), - `egg_type` varchar(255) NOT NULL, + `egg_type_id` BIGINT NOT NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `deleted_at` TIMESTAMP NULL + `deleted_at` TIMESTAMP NULL ); CREATE TABLE `runimo` @@ -190,17 +204,26 @@ ALTER TABLE `oauth_account` ADD FOREIGN KEY (`user_id`) REFERENCES `users` (`id`); -- insert static data -INSERT INTO runimo_definition (id, name, code, description, img_url, egg_type, created_at, updated_at) -VALUES (1, '강아지', 'R-101', '마당-강아지예여', 'http://dummy1', 'MADANG', NOW(), NOW()), - (2, '고양이', 'R-102', '마당-고양이예여', 'http://dummy2', 'MADANG', NOW(), NOW()), - (3, '토끼', 'R-103', '마당-토끼예여', 'http://dummy2', 'MADANG', NOW(), NOW()), - (4, '오리', 'R-104', '마당-오리예여', 'http://dummy2', 'MADANG', NOW(), NOW()), - (5, '늑대 강아지', 'R-105', '늑대 강아지예여', 'http://dummy2', 'FOREST', NOW(), NOW()), - (6, '숲 고양이', 'R-106', '숲 고양이예여', 'http://dummy2', 'FOREST', NOW(), NOW()), - (7, '나뭇잎 토끼', 'R-107', '나뭇잎 토끼예여', 'http://dummy2', 'FOREST', NOW(), NOW()), - (8, '숲 오리', 'R-108', '숲 오리예여', 'http://dummy2', 'FOREST', NOW(), NOW()); - -INSERT INTO item (id, name, item_code, description, item_type, img_url, dtype, egg_type, hatch_require_amount, created_at, updated_at) -VALUES (1, '마당', 'A100', '기본 알', 'USABLE', 'https://example.com/images/egg1.png', 'EGG', 'MADANG', 0L, NOW(), NOW()), - (2, '숲', 'A101', '두번째 단계 알', 'USABLE', 'https://example.com/images/egg2.png', 'EGG', 'FOREST', 30000L, NOW(), NOW()), - (3, '초원', 'A102', '세번째 단계 알', 'USABLE', 'https://example.com/images/egg3.png', 'EGG', 'GRASSLAND', 50000L, NOW(), NOW()); + +INSERT INTO egg_type (id, name, code, required_distance_in_meters, level, created_at, updated_at) +VALUES (1, '마당', 'A100', 0, 1, NOW(), NOW()), + (2, '숲', 'A101', 30000, 2, NOW(), NOW()); + + +INSERT INTO runimo_definition (id, name, code, description, img_url, egg_type_id, created_at, + updated_at) +VALUES (1, '강아지', 'R-101', '마당-강아지예여', 'http://dummy1', 1, NOW(), NOW()), + (2, '고양이', 'R-102', '마당-고양이예여', 'http://dummy1', 1, NOW(), NOW()), + (3, '토끼', 'R-103', '마당-토끼예여', 'http://dummy1', 1, NOW(), NOW()), + (4, '오리', 'R-104', '마당-오리예여', 'http://dummy1', 1, NOW(), NOW()), + (5, '늑대 강아지', 'R-105', '늑대 강아지예여', 'http://dummy2', 2, NOW(), NOW()), + (6, '숲 고양이', 'R-106', '숲 고양이예여', 'http://dummy2', 2, NOW(), NOW()), + (7, '나뭇잎 토끼', 'R-107', '나뭇잎 토끼예여', 'http://dummy2', 2, NOW(), NOW()), + (8, '숲 오리', 'R-108', '숲 오리예여', 'http://dummy2', 2, NOW(), NOW()); + +INSERT INTO item (id, name, item_code, description, item_type, img_url, dtype, egg_type_id, + hatch_require_amount, created_at, updated_at) +VALUES (1, '마당', 'A100', '기본 알', 'USABLE', 'https://example.com/images/egg1.png', 'EGG', 1, + 100, NOW(), NOW()), + (2, '숲', 'A101', '두번째 단계 알', 'USABLE', 'https://example.com/images/egg2.png', 'EGG', + 2, 30000, NOW(), NOW()); \ No newline at end of file diff --git a/src/test/resources/sql/egg_data.sql b/src/test/resources/sql/egg_data.sql index 4324ae35..809465f2 100644 --- a/src/test/resources/sql/egg_data.sql +++ b/src/test/resources/sql/egg_data.sql @@ -1,9 +1,13 @@ TRUNCATE TABLE item; +TRUNCATE TABLE egg_type; -INSERT INTO item (name, item_code, description, item_type, img_url, dtype, egg_type, hatch_require_amount, created_at, - updated_at) -VALUES ('마당알', 'A100', '마당알: 기본 알', 'USABLE', 'example.url', 'EGG', 'MADANG', 10, NOW(), NOW()); +INSERT INTO egg_type (id, name, code, required_distance_in_meters, level, created_at, updated_at) +VALUES (1, '마당', 'A100', 0L, 1, NOW(), NOW()), + (2, '숲', 'A101', 30000L, 2, NOW(), NOW()); -INSERT INTO item (name, item_code, description, item_type, img_url, dtype, egg_type, hatch_require_amount, created_at, - updated_at) -VALUES ('숲알', 'A101', '숲알: 기본 알', 'USABLE', 'example1.url', 'EGG', 'FOREST', 20, NOW(), NOW()); \ No newline at end of file +INSERT INTO item (id, name, item_code, description, item_type, img_url, dtype, egg_type_id, + hatch_require_amount, created_at, updated_at) +VALUES (1, '마당', 'A100', '기본 알', 'USABLE', 'https://example.com/images/egg1.png', 'EGG', 1, + 10, NOW(), NOW()), + (2, '숲', 'A101', '두번째 단계 알', 'USABLE', 'https://example.com/images/egg2.png', 'EGG', + 2, 30, NOW(), NOW()); diff --git a/src/test/resources/sql/get_my_runimo_list_test_data.sql b/src/test/resources/sql/get_my_runimo_list_test_data.sql index 03c1fad7..1219fb14 100644 --- a/src/test/resources/sql/get_my_runimo_list_test_data.sql +++ b/src/test/resources/sql/get_my_runimo_list_test_data.sql @@ -7,14 +7,6 @@ VALUES (1, 'test-user-uuid-1', 'Daniel', 'https://example.com/images/user1.png', (2, 'test-user-uuid-2', 'Moon', 'https://example.com/images/user2.png', 5000, 1800, null, NOW(), NOW()); SET FOREIGN_KEY_CHECKS = 1; --- 러니모 - 정적 데이터 --- TRUNCATE TABLE runimo_definition; --- INSERT INTO runimo_definition (id, name, code, description, img_url, egg_type, created_at, updated_at) --- VALUES (1, '토끼', 'R-101', '마당 토끼예여', 'http://dummy1', 'MADANG', NOW(), NOW()), --- (2, '강아지', 'R-102', '마당 강아지예여', 'http://dummy2', 'MADANG', NOW(), NOW()), --- (3, '오리', 'R-103', '마당 오리예여', 'http://dummy3', 'MADANG', NOW(), NOW()), --- (4, '늑대', 'R-104', '주인이 다른 마당 늑대예여', 'http://dummy4', 'MADANG', NOW(), NOW()); - -- 러니모 TRUNCATE TABLE runimo; INSERT INTO runimo (id, user_id, runimo_definition_id, total_run_count, total_distance_in_meters, created_at, updated_at) diff --git a/src/test/resources/sql/hatch_test_data.sql b/src/test/resources/sql/hatch_test_data.sql index b61ca63e..b0b12d8a 100644 --- a/src/test/resources/sql/hatch_test_data.sql +++ b/src/test/resources/sql/hatch_test_data.sql @@ -21,28 +21,3 @@ VALUES (1, 1, 1, 0L, 0L, 'INCUBATED', NOW(), NOW()), (9, 1, 2, 30000L, 30000L, 'INCUBATED', NOW(), NOW()), (10, 1, 2, 30000L, 30000L, 'INCUBATED', NOW(), NOW()); - - --- Item (Egg) - 정적데이터 --- TRUNCATE TABLE item; --- INSERT INTO item (id, name, item_code, description, item_type, img_url, dtype, egg_type, hatch_require_amount, created_at, updated_at) --- VALUES (1, '마당', 'A100', '기본 알', 'USABLE', 'https://example.com/images/egg1.png', 'EGG', 'MADANG', 0L, NOW(), NOW()), --- (2, '숲', 'A101', '두번째 단계 알', 'USABLE', 'https://example.com/images/egg2.png', 'EGG', 'FOREST', 30000L, NOW(), NOW()), --- (3, '초원', 'A102', '세번째 단계 알', 'USABLE', 'https://example.com/images/egg3.png', 'EGG', 'GRASSLAND', 50000L, NOW(), NOW()); - --- 러니모 - 정적 데이터 --- TRUNCATE TABLE runimo_definition; --- INSERT INTO runimo_definition (id, name, code, description, img_url, egg_type, created_at, updated_at) --- VALUES (1, '강아지', 'R-101', '마당-강아지예여', 'http://dummy1', 'MADANG', NOW(), NOW()), --- (2, '고양이', 'R-102', '마당-고양이예여', 'http://dummy2', 'MADANG', NOW(), NOW()), --- (3, '토끼', 'R-103', '마당-토끼예여', 'http://dummy2', 'MADANG', NOW(), NOW()), --- (4, '오리', 'R-104', '마당-오리예여', 'http://dummy2', 'MADANG', NOW(), NOW()), --- (5, '늑대 강아지', 'R-105', '늑대 강아지예여', 'http://dummy2', 'FOREST', NOW(), NOW()), --- (6, '숲 고양이', 'R-106', '숲 고양이예여', 'http://dummy2', 'FOREST', NOW(), NOW()), --- (7, '나뭇잎 토끼', 'R-107', '나뭇잎 토끼예여', 'http://dummy2', 'FOREST', NOW(), NOW()), --- (8, '숲 오리', 'R-108', '숲 오리예여', 'http://dummy2', 'FOREST', NOW(), NOW()); - --- 사용자-러니모 맵핑 --- TRUNCATE TABLE runimo; --- INSERT INTO runimo (id, user_id, runimo_definition_id, created_at, updated_at) --- VALUES (1, 1, 2, NOW(), NOW()); \ No newline at end of file diff --git a/src/test/resources/sql/incubating_egg_test_data.sql b/src/test/resources/sql/incubating_egg_test_data.sql index 5fb3fed2..2cd3766c 100644 --- a/src/test/resources/sql/incubating_egg_test_data.sql +++ b/src/test/resources/sql/incubating_egg_test_data.sql @@ -18,8 +18,8 @@ INSERT INTO user_item (id, user_id, item_id, quantity, created_at, updated_at) VALUES (1001, 1, 1, 2, NOW(), NOW()), (1002, 1, 2, 1, NOW(), NOW()); -INSERT INTO item (id, name, item_code, description, item_type, img_url, dtype, egg_type, hatch_require_amount, created_at, updated_at) -VALUES (1, '마당알', 'A100', '기본 알', 'USABLE', 'https://example.com/images/egg.png', 'EGG', 'MADANG', 100, NOW(), NOW()); +INSERT INTO item (id, name, item_code, description, item_type, img_url, dtype, egg_type_id, hatch_require_amount, created_at, updated_at) +VALUES (1, '마당알', 'A100', '기본 알', 'USABLE', 'https://example.com/images/egg.png', 'EGG', 1, 100, NOW(), NOW()); INSERT INTO incubating_egg (id, user_id, egg_id, current_love_point_amount, hatch_require_amount, egg_status, created_at, updated_at) VALUES (1, 1, 1, 50, 100, 'INCUBATING', NOW(), NOW()); diff --git a/src/test/resources/sql/main_view_data.sql b/src/test/resources/sql/main_view_data.sql index aac49c6d..964e5d96 100644 --- a/src/test/resources/sql/main_view_data.sql +++ b/src/test/resources/sql/main_view_data.sql @@ -4,28 +4,31 @@ TRUNCATE TABLE users; INSERT INTO users (id, public_id, nickname, img_url, total_distance_in_meters, total_time_in_seconds, created_at, updated_at, main_runimo_id) -VALUES (1, 'test-user-uuid-1', 'Daniel', 'https://example.com/images/user1.png', 3000, 3600, NOW(),NOW(),1), - (2, 'test-user-uuid-2', 'HEHH', 'https://example.com/images/user2.png', 3000, 3600, NOW(), NOW(), null); +VALUES (1, 'test-user-uuid-1', 'Daniel', 'https://example.com/images/user1.png', 3000, 3600, NOW(), + NOW(), 1), + (2, 'test-user-uuid-2', 'HEHH', 'https://example.com/images/user2.png', 3000, 3600, NOW(), + NOW(), null); SET FOREIGN_KEY_CHECKS = 1; TRUNCATE TABLE item; -INSERT INTO item (name, item_code, description, item_type, img_url, dtype, egg_type, +INSERT INTO item (name, item_code, description, item_type, img_url, dtype, egg_type_id, hatch_require_amount, created_at, updated_at) -VALUES ('마당알', 'A100', '마당알: 기본 알', 'USABLE', 'example.url', 'EGG', 'MADANG', 10, NOW(), NOW()); - -INSERT INTO item (name, item_code, description, item_type, img_url, dtype, egg_type, - hatch_require_amount, created_at, - updated_at) -VALUES ('숲알', 'A101', '숲알: 기본 알', 'USABLE', 'example1.url', 'EGG', 'FOREST', 20, NOW(), NOW()); +VALUES ('마당알', 'A100', '마당알: 기본 알', 'USABLE', 'example.url', 'EGG', 1, 10, NOW(), NOW()), + ('숲알', 'A101', '숲알: 기본 알', 'USABLE', 'example1.url', 'EGG', 2, 20, NOW(), NOW()); TRUNCATE TABLE runimo_definition; -INSERT INTO runimo_definition (id, name, code, description, img_url, egg_type, created_at, +INSERT INTO runimo_definition (id, name, code, description, img_url, egg_type_id, created_at, updated_at) -VALUES (1, '토끼', 'R-101', '마당 토끼예여', 'http://dummy1', 'MADANG', NOW(), NOW()), - (2, '강아지', 'R-102', '마당 강아지예여', 'http://dummy2', 'MADANG', NOW(), NOW()), - (3, '오리', 'R-103', '마당 오리예여', 'http://dummy3', 'MADANG', NOW(), NOW()), - (4, '늑대', 'R-104', '주인이 다른 마당 늑대예여', 'http://dummy4', 'MADANG', NOW(), NOW()); +VALUES (1, '토끼', 'R-101', '마당-토끼예여', 'http://dummy1', 1, NOW(), NOW()), + (2, '강아지', 'R-102', '마당-강아지예여', 'http://dummy1', 1, NOW(), NOW()), + (3, '오리', 'R-103', '마당-오리예여', 'http://dummy1', 1, NOW(), NOW()), + (4, '고양이', 'R-104', '마당-고양이예여', 'http://dummy1', 1, NOW(), NOW()), + (5, '늑대 강아지', 'R-105', '늑대 강아지예여', 'http://dummy2', 2, NOW(), NOW()), + (6, '숲 고양이', 'R-106', '숲 고양이예여', 'http://dummy2', 2, NOW(), NOW()), + (7, '나뭇잎 토끼', 'R-107', '나뭇잎 토끼예여', 'http://dummy2', 2, NOW(), NOW()), + (8, '숲 오리', 'R-108', '숲 오리예여', 'http://dummy2', 2, NOW(), NOW()); + TRUNCATE TABLE running_record; @@ -36,8 +39,9 @@ VALUES (1, 1, 'record-public-id-1', 'record-title-1', NOW(), NOW(), 1000, 100, f (2, 1, 'record-public-id-2', 'record-title-2', NOW(), NOW(), 2000, 200, false, NOW(), NOW()); TRUNCATE TABLE runimo; -INSERT INTO runimo (id, user_id, runimo_definition_id, total_run_count, total_distance_in_meters, created_at, updated_at, deleted_at) -VALUES ( 1, 1, 1, 2, 3456, NOW(), NOW(), null ); +INSERT INTO runimo (id, user_id, runimo_definition_id, total_run_count, total_distance_in_meters, + created_at, updated_at, deleted_at) +VALUES (1, 1, 1, 2, 3456, NOW(), NOW(), null); -- 보유 아이템 @@ -45,7 +49,7 @@ TRUNCATE TABLE user_item; INSERT INTO user_item (id, user_id, item_id, quantity, created_at, updated_at) VALUES (1001, 1, 1, 2, NOW(), NOW()), (1002, 1, 2, 1, NOW(), NOW()), - (1003, 2, 1, 3, NOW(), NOW()), + (1003, 2, 1, 3, NOW(), NOW()), (1004, 2, 2, 4, NOW(), NOW()); TRUNCATE TABLE user_love_point; diff --git a/src/test/resources/sql/schema.sql b/src/test/resources/sql/schema.sql index f5565007..916ff5e1 100644 --- a/src/test/resources/sql/schema.sql +++ b/src/test/resources/sql/schema.sql @@ -1,5 +1,6 @@ SET FOREIGN_KEY_CHECKS = 0; +DROP TABLE IF EXISTS egg_type; DROP TABLE IF EXISTS signup_token; DROP TABLE IF EXISTS apple_user_token; DROP TABLE IF EXISTS user_token; @@ -68,22 +69,22 @@ CREATE TABLE `oauth_account` CREATE TABLE `apple_user_token` ( - `id` BIGINT PRIMARY KEY AUTO_INCREMENT, - `user_id` BIGINT NOT NULL, + `id` BIGINT PRIMARY KEY AUTO_INCREMENT, + `user_id` BIGINT NOT NULL, `refresh_token` VARCHAR(255) NOT NULL, - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `deleted_at` TIMESTAMP NULL, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `deleted_at` TIMESTAMP NULL, FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ); CREATE TABLE `signup_token` ( - `token` VARCHAR(255) PRIMARY KEY NOT NULL UNIQUE , - `provider_id` VARCHAR(255) NOT NULL, + `token` VARCHAR(255) PRIMARY KEY NOT NULL UNIQUE, + `provider_id` VARCHAR(255) NOT NULL, `refresh_token` VARCHAR(255), - `provider` VARCHAR(255), - `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP + `provider` VARCHAR(255), + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); @@ -115,13 +116,26 @@ CREATE TABLE `item` `item_type` VARCHAR(255) NOT NULL, `img_url` VARCHAR(255), `dtype` VARCHAR(255), - `egg_type` VARCHAR(255), + `egg_type_id` BIGINT, `hatch_require_amount` BIGINT, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `deleted_at` TIMESTAMP NULL ); +CREATE TABLE `egg_type` +( + `id` INTEGER PRIMARY KEY AUTO_INCREMENT, + `name` VARCHAR(64) NOT NULL, + `code` VARCHAR(64) NOT NULL, + `required_distance_in_meters` BIGINT, + `level` INTEGER, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `deleted_at` TIMESTAMP NULL + +); + CREATE TABLE `item_activity` ( `id` INTEGER PRIMARY KEY AUTO_INCREMENT, @@ -165,10 +179,10 @@ CREATE TABLE `runimo_definition` `code` VARCHAR(255), `description` VARCHAR(255), `img_url` varchar(255), - `egg_type` varchar(255) NOT NULL, + `egg_type_id` BIGINT NOT NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `deleted_at` TIMESTAMP NULL + `deleted_at` TIMESTAMP NULL ); CREATE TABLE `runimo` @@ -190,17 +204,26 @@ ALTER TABLE `oauth_account` ADD FOREIGN KEY (`user_id`) REFERENCES `users` (`id`); -- insert static data -INSERT INTO runimo_definition (id, name, code, description, img_url, egg_type, created_at, updated_at) -VALUES (1, '강아지', 'R-101', '마당-강아지예여', 'http://dummy1', 'MADANG', NOW(), NOW()), - (2, '고양이', 'R-102', '마당-고양이예여', 'http://dummy2', 'MADANG', NOW(), NOW()), - (3, '토끼', 'R-103', '마당-토끼예여', 'http://dummy2', 'MADANG', NOW(), NOW()), - (4, '오리', 'R-104', '마당-오리예여', 'http://dummy2', 'MADANG', NOW(), NOW()), - (5, '늑대 강아지', 'R-105', '늑대 강아지예여', 'http://dummy2', 'FOREST', NOW(), NOW()), - (6, '숲 고양이', 'R-106', '숲 고양이예여', 'http://dummy2', 'FOREST', NOW(), NOW()), - (7, '나뭇잎 토끼', 'R-107', '나뭇잎 토끼예여', 'http://dummy2', 'FOREST', NOW(), NOW()), - (8, '숲 오리', 'R-108', '숲 오리예여', 'http://dummy2', 'FOREST', NOW(), NOW()); - -INSERT INTO item (id, name, item_code, description, item_type, img_url, dtype, egg_type, hatch_require_amount, created_at, updated_at) -VALUES (1, '마당', 'A100', '기본 알', 'USABLE', 'https://example.com/images/egg1.png', 'EGG', 'MADANG', 0L, NOW(), NOW()), - (2, '숲', 'A101', '두번째 단계 알', 'USABLE', 'https://example.com/images/egg2.png', 'EGG', 'FOREST', 30000L, NOW(), NOW()), - (3, '초원', 'A102', '세번째 단계 알', 'USABLE', 'https://example.com/images/egg3.png', 'EGG', 'GRASSLAND', 50000L, NOW(), NOW()); + +INSERT INTO egg_type (id, name, code, required_distance_in_meters, level, created_at, updated_at) +VALUES (1, '마당', 'A100', 0, 1, NOW(), NOW()), + (2, '숲', 'A101', 30000, 2, NOW(), NOW()); + + +INSERT INTO runimo_definition (id, name, code, description, img_url, egg_type_id, created_at, + updated_at) +VALUES (1, '강아지', 'R-101', '마당-강아지예여', 'http://dummy1', 1, NOW(), NOW()), + (2, '고양이', 'R-102', '마당-고양이예여', 'http://dummy2', 1, NOW(), NOW()), + (3, '토끼', 'R-103', '마당-토끼예여', 'http://dummy2', 1, NOW(), NOW()), + (4, '오리', 'R-104', '마당-오리예여', 'http://dummy2', 1, NOW(), NOW()), + (5, '늑대 강아지', 'R-105', '늑대 강아지예여', 'http://dummy2', 2, NOW(), NOW()), + (6, '숲 고양이', 'R-106', '숲 고양이예여', 'http://dummy2', 2, NOW(), NOW()), + (7, '나뭇잎 토끼', 'R-107', '나뭇잎 토끼예여', 'http://dummy2', 2, NOW(), NOW()), + (8, '숲 오리', 'R-108', '숲 오리예여', 'http://dummy2', 2, NOW(), NOW()); + +INSERT INTO item (id, name, item_code, description, item_type, img_url, dtype, egg_type_id, + hatch_require_amount, created_at, updated_at) +VALUES (1, '마당', 'A100', '기본 알', 'USABLE', 'https://example.com/images/egg1.png', 'EGG', 1, + 100, NOW(), NOW()), + (2, '숲', 'A101', '두번째 단계 알', 'USABLE', 'https://example.com/images/egg2.png', 'EGG', + 2, 30000, NOW(), NOW()); \ No newline at end of file diff --git a/src/test/resources/sql/set_main_runimo_test_data.sql b/src/test/resources/sql/set_main_runimo_test_data.sql index 03c1fad7..1219fb14 100644 --- a/src/test/resources/sql/set_main_runimo_test_data.sql +++ b/src/test/resources/sql/set_main_runimo_test_data.sql @@ -7,14 +7,6 @@ VALUES (1, 'test-user-uuid-1', 'Daniel', 'https://example.com/images/user1.png', (2, 'test-user-uuid-2', 'Moon', 'https://example.com/images/user2.png', 5000, 1800, null, NOW(), NOW()); SET FOREIGN_KEY_CHECKS = 1; --- 러니모 - 정적 데이터 --- TRUNCATE TABLE runimo_definition; --- INSERT INTO runimo_definition (id, name, code, description, img_url, egg_type, created_at, updated_at) --- VALUES (1, '토끼', 'R-101', '마당 토끼예여', 'http://dummy1', 'MADANG', NOW(), NOW()), --- (2, '강아지', 'R-102', '마당 강아지예여', 'http://dummy2', 'MADANG', NOW(), NOW()), --- (3, '오리', 'R-103', '마당 오리예여', 'http://dummy3', 'MADANG', NOW(), NOW()), --- (4, '늑대', 'R-104', '주인이 다른 마당 늑대예여', 'http://dummy4', 'MADANG', NOW(), NOW()); - -- 러니모 TRUNCATE TABLE runimo; INSERT INTO runimo (id, user_id, runimo_definition_id, total_run_count, total_distance_in_meters, created_at, updated_at) diff --git a/src/test/resources/sql/user_item_test_data.sql b/src/test/resources/sql/user_item_test_data.sql index 2d1fb522..7c8defc6 100644 --- a/src/test/resources/sql/user_item_test_data.sql +++ b/src/test/resources/sql/user_item_test_data.sql @@ -7,17 +7,6 @@ VALUES (1, 'test-user-uuid-1', 'Daniel', 'https://example.com/images/user1.png', (2, 'test-user-uuid-2', 'Moon', 'https://example.com/images/user2.png', 5000, 1800, null, NOW(), NOW()); SET FOREIGN_KEY_CHECKS = 1; - -TRUNCATE TABLE item; -INSERT INTO item (name, item_code, description, item_type, img_url, dtype, egg_type, hatch_require_amount, created_at, - updated_at) -VALUES ('마당알', 'A100', '마당알: 기본 알', 'USABLE', 'example.url', 'EGG', 'MADANG', 10, NOW(), NOW()); - -INSERT INTO item (name, item_code, description, item_type, img_url, dtype, egg_type, hatch_require_amount, created_at, - updated_at) -VALUES ('숲알', 'A101', '숲알: 기본 알', 'USABLE', 'example1.url', 'EGG', 'FOREST', 20, NOW(), NOW()); - - -- 보유 아이템 TRUNCATE TABLE user_item; INSERT INTO user_item (id, user_id, item_id, quantity, created_at, updated_at) diff --git a/src/test/resources/sql/user_mypage_test_data.sql b/src/test/resources/sql/user_mypage_test_data.sql index f0627531..384d62a5 100644 --- a/src/test/resources/sql/user_mypage_test_data.sql +++ b/src/test/resources/sql/user_mypage_test_data.sql @@ -12,14 +12,6 @@ TRUNCATE TABLE oauth_account; INSERT INTO oauth_account (id, created_at, deleted_at, updated_at, provider, provider_id, user_id) VALUES (1, NOW(), null, NOW(), 'KAKAO', 1234, 1); - -TRUNCATE TABLE item; -INSERT INTO item (name, item_code, description, item_type, img_url, dtype, egg_type, - hatch_require_amount, created_at, - updated_at) -VALUES ('마당알', 'A100', '마당알: 기본 알', 'USABLE', 'example.url', 'EGG', 'MADANG', 10, NOW(), NOW()); - - -- 보유 아이템 TRUNCATE TABLE user_item; INSERT INTO user_item (id, user_id, item_id, quantity, created_at, updated_at) From 22359a86efed627ae2b728ada4200a181fd759c4 Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Wed, 23 Apr 2025 22:09:02 +0900 Subject: [PATCH 08/12] :white_check_mark: test : update test code --- .../hatch/controller/HatchControllerTest.java | 2 +- ...t.java => EggEnumRandomGeneratorTest.java} | 22 ++++++++++++++----- .../org/runimo/runimo/rewards/RewardTest.java | 4 ++-- .../rewards/api/RewardAcceptanceTest.java | 5 +++-- .../rewards/service/RewardServiceTest.java | 22 ++++++++++++++----- .../controller/RunimoControllerTest.java | 5 ++++- 6 files changed, 44 insertions(+), 16 deletions(-) rename src/test/java/org/runimo/runimo/item/service/{EggTypeRandomGeneratorTest.java => EggEnumRandomGeneratorTest.java} (56%) diff --git a/src/test/java/org/runimo/runimo/hatch/controller/HatchControllerTest.java b/src/test/java/org/runimo/runimo/hatch/controller/HatchControllerTest.java index 83b2e1d2..cf9e2a96 100644 --- a/src/test/java/org/runimo/runimo/hatch/controller/HatchControllerTest.java +++ b/src/test/java/org/runimo/runimo/hatch/controller/HatchControllerTest.java @@ -66,7 +66,7 @@ void tearDown() { .then() .log().all() - .statusCode(HttpStatus.CREATED.value()) + .statusCode(HttpStatus.CREATED.value()) .body("code", equalTo("HSH2011")) .body("payload.name", notNullValue()) diff --git a/src/test/java/org/runimo/runimo/item/service/EggTypeRandomGeneratorTest.java b/src/test/java/org/runimo/runimo/item/service/EggEnumRandomGeneratorTest.java similarity index 56% rename from src/test/java/org/runimo/runimo/item/service/EggTypeRandomGeneratorTest.java rename to src/test/java/org/runimo/runimo/item/service/EggEnumRandomGeneratorTest.java index babd68b3..5dd15cc0 100644 --- a/src/test/java/org/runimo/runimo/item/service/EggTypeRandomGeneratorTest.java +++ b/src/test/java/org/runimo/runimo/item/service/EggEnumRandomGeneratorTest.java @@ -2,22 +2,34 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; +import java.util.List; import org.junit.jupiter.api.Test; import org.runimo.runimo.item.domain.EggType; -class EggTypeRandomGeneratorTest { +class EggEnumRandomGeneratorTest { private final EggTypeRandomGenerator eggTypeRandomGenerator = new EggTypeRandomGenerator(); @Test void generateRandomEggType() { - //given - Long totalRunningDistanceInMeters = 34444L; //when + List eggTypes = List.of( + EggType.of( + "마당", + "E100", + 0L, + 0 + ), + EggType.of( + "숲", + "E101", + 30000L, + 1 + ) + ); for (int i = 0; i < 10; i++) { - EggType selectedType = eggTypeRandomGenerator.generateRandomEggType( - EggType.getUnLockedEggTypes(totalRunningDistanceInMeters)); + EggType selectedType = eggTypeRandomGenerator.generateRandomEggType(eggTypes); assertNotNull(selectedType); } } diff --git a/src/test/java/org/runimo/runimo/rewards/RewardTest.java b/src/test/java/org/runimo/runimo/rewards/RewardTest.java index 57a7efd5..42d7fe03 100644 --- a/src/test/java/org/runimo/runimo/rewards/RewardTest.java +++ b/src/test/java/org/runimo/runimo/rewards/RewardTest.java @@ -101,9 +101,9 @@ void tearDown() { RewardResponse rewardResponse = rewardService.claimReward(rewardClaimCommand); UserItem savedItem = userItemFinder. - findEggByUserIdAndEggType( + findEggByUserIdAndEggCode( savedUser.getId(), - rewardResponse.eggType()) + rewardResponse.eggCode()) .get(); assertNotNull(rewardResponse.eggCode()); diff --git a/src/test/java/org/runimo/runimo/rewards/api/RewardAcceptanceTest.java b/src/test/java/org/runimo/runimo/rewards/api/RewardAcceptanceTest.java index e991ebf1..6639310d 100644 --- a/src/test/java/org/runimo/runimo/rewards/api/RewardAcceptanceTest.java +++ b/src/test/java/org/runimo/runimo/rewards/api/RewardAcceptanceTest.java @@ -4,7 +4,6 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -185,7 +184,8 @@ void tearDown() { .then() .log().all() .statusCode(HttpStatus.OK.value()) - .body("payload.egg_type", nullValue()) + .body("payload.is_rewarded", equalTo(false)) + .body("payload.egg_type", equalTo("EMPTY")) .body("payload.egg_code", equalTo("EMPTY")); } @@ -260,6 +260,7 @@ void tearDown() { .then() .log().all() .statusCode(HttpStatus.OK.value()) + .body("payload.is_rewarded", equalTo(false)) .body("payload.love_point_amount", notNullValue()) .body("payload.love_point_amount", equalTo(0)); } diff --git a/src/test/java/org/runimo/runimo/rewards/service/RewardServiceTest.java b/src/test/java/org/runimo/runimo/rewards/service/RewardServiceTest.java index 6aece609..bfd7467a 100644 --- a/src/test/java/org/runimo/runimo/rewards/service/RewardServiceTest.java +++ b/src/test/java/org/runimo/runimo/rewards/service/RewardServiceTest.java @@ -3,8 +3,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -74,11 +74,17 @@ void setUp() { when(recordFinder.findFirstRunOfCurrentWeek(any())).thenReturn( java.util.Optional.of(unRewardedRecord)); when(eggGrantService.grantRandomEggToUser(any())).thenReturn( - Egg.builder().eggType(EggType.MADANG).build()); + Egg.builder().eggType(EggType.of( + "MADANG", + "hi", + 0L, + 0 + )).build()); when(loveGrantService.grantLoveToUserWithDistance(any())).thenReturn(10L); RewardResponse res = rewardService.claimReward(command); assertNotNull(res); - assertEquals(EggType.MADANG, res.eggType()); + assertTrue(res.isRewarded()); + assertEquals("MADANG", res.eggType()); assertNotEquals(0, res.lovePointAmount()); } @@ -92,7 +98,12 @@ void setUp() { when(recordFinder.findFirstRunOfCurrentWeek(any())).thenReturn( java.util.Optional.of(alreadyRewardedRecord)); when(eggGrantService.grantRandomEggToUser(any())).thenReturn( - Egg.builder().eggType(EggType.MADANG).build()); + Egg.builder().eggType(EggType.of( + "MADANG", + "hi", + 0L, + 0 + )).build()); when(loveGrantService.grantLoveToUserWithDistance(any())).thenReturn(10L); assertThrows(IllegalStateException.class, () -> rewardService.claimReward(command)); @@ -110,7 +121,8 @@ void setUp() { RewardResponse res = rewardService.claimReward(command); verify(eggGrantService, never()).grantRandomEggToUser(any()); + assertEquals(false, res.isRewarded()); assertEquals(Egg.EMPTY.getItemCode(), res.eggCode()); - assertNull(res.eggType()); + assertEquals(Egg.EMPTY.getName(), res.eggType()); } } \ No newline at end of file diff --git a/src/test/java/org/runimo/runimo/runimo/controller/RunimoControllerTest.java b/src/test/java/org/runimo/runimo/runimo/controller/RunimoControllerTest.java index bc96c30b..ab9b3df9 100644 --- a/src/test/java/org/runimo/runimo/runimo/controller/RunimoControllerTest.java +++ b/src/test/java/org/runimo/runimo/runimo/controller/RunimoControllerTest.java @@ -89,15 +89,18 @@ void tearDown() { .then() .log().all() - .statusCode(HttpStatus.OK.value()) + .statusCode(HttpStatus.OK.value()) .body("code", equalTo("MSH2003")) .body("payload.runimo_groups", hasSize(2)) .body("payload.runimo_groups[0].egg_type", equalTo("마당")) .body("payload.runimo_groups[0].runimo_types", hasSize(4)) + .body("payload.runimo_groups[0].egg_required_distance_in_meters", equalTo(0)) .body("payload.runimo_groups[1].egg_type", equalTo("숲")) .body("payload.runimo_groups[1].runimo_types", hasSize(4)) + .body("payload.runimo_groups[1].egg_required_distance_in_meters", equalTo(30000)) + .body("payload.runimo_groups[0].runimo_types[0].name", equalTo("강아지")) .body("payload.runimo_groups[0].runimo_types[0].img_url", equalTo("http://dummy1")) From eddf4538fd099d3978e49daa8185b175ca9dc1b7 Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Wed, 23 Apr 2025 22:45:44 +0900 Subject: [PATCH 09/12] :recycle: refactor : change jpql to data jpa function --- .../org/runimo/runimo/item/repository/EggTypeRepository.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/runimo/runimo/item/repository/EggTypeRepository.java b/src/main/java/org/runimo/runimo/item/repository/EggTypeRepository.java index 00f44cf1..a8d7bfa4 100644 --- a/src/main/java/org/runimo/runimo/item/repository/EggTypeRepository.java +++ b/src/main/java/org/runimo/runimo/item/repository/EggTypeRepository.java @@ -3,12 +3,10 @@ import java.util.List; import org.runimo.runimo.item.domain.EggType; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; public interface EggTypeRepository extends JpaRepository { - @Query("select et from EggType et order by et.id") - List findAllOrderById(); + List findAllByOrderByIdAsc(); List findEggTypeByRequiredDistanceInMetersLessThanEqual(Long totalDistanceInMeters); From bf70c20cc8aaef7b8f97190054cc2f2a64c78db9 Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Wed, 23 Apr 2025 22:46:09 +0900 Subject: [PATCH 10/12] :recycle: refactor : refactor collecting runimoTypeInfo --- .../runimo/service/usecase/RunimoUsecaseImpl.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/runimo/runimo/runimo/service/usecase/RunimoUsecaseImpl.java b/src/main/java/org/runimo/runimo/runimo/service/usecase/RunimoUsecaseImpl.java index bef662f9..123db2d5 100644 --- a/src/main/java/org/runimo/runimo/runimo/service/usecase/RunimoUsecaseImpl.java +++ b/src/main/java/org/runimo/runimo/runimo/service/usecase/RunimoUsecaseImpl.java @@ -1,5 +1,6 @@ package org.runimo.runimo.runimo.service.usecase; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; @@ -62,19 +63,18 @@ public SetMainRunimoResponse setMainRunimo(Long userId, Long runimoId) { @Override public GetRunimoTypeListResponse getRunimoTypeList() { - List eggTypes = eggTypeRepository.findAllOrderById(); + List eggTypes = eggTypeRepository.findAllByOrderByIdAsc(); - Map> runimoTypeInfos = eggTypes.stream() - .collect(Collectors.toMap( - EggType::getId, - type -> runimoDefinitionRepository.findRunimoSimpleTypeModelByType(List.of(type)) - )); + Map> runimoTypeInfos = + runimoDefinitionRepository.findRunimoSimpleTypeModelByType(eggTypes).stream() + .collect(Collectors.groupingBy(RunimoTypeSimpleModel::getEggTypeId)); List runimoTypeGroups = eggTypes.stream() .map(type -> new RunimoTypeGroup( type.getName(), type.getRequiredDistanceInMeters(), - RunimoTypeInfo.from(runimoTypeInfos.get(type.getId())) + RunimoTypeInfo.from( + runimoTypeInfos.getOrDefault(type.getId(), Collections.emptyList())) )) .toList(); From e8e3b1082a629946e171aab9a42ba76fbd6c475d Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Wed, 23 Apr 2025 22:47:16 +0900 Subject: [PATCH 11/12] :recycle: refactor : rename parameter from `eggLevel` to `level` --- .../java/org/runimo/runimo/item/domain/EggType.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/runimo/runimo/item/domain/EggType.java b/src/main/java/org/runimo/runimo/item/domain/EggType.java index a9428240..98fb0c8c 100644 --- a/src/main/java/org/runimo/runimo/item/domain/EggType.java +++ b/src/main/java/org/runimo/runimo/item/domain/EggType.java @@ -29,26 +29,26 @@ public class EggType extends BaseEntity { private Integer level; @Builder - private EggType(String name, String code, Long requiredDistanceInMeters, Integer eggLevel) { + private EggType(String name, String code, Long requiredDistanceInMeters, Integer level) { this.name = name; this.code = code; if (requiredDistanceInMeters < 0) { throw new IllegalArgumentException("알의 요구 거리(미터)는 0보다 작을 수 없습니다."); } this.requiredDistanceInMeters = requiredDistanceInMeters; - if (eggLevel < 0) { + if (level < 0) { throw new IllegalArgumentException("알의 레벨은 0보다 작을 수 없습니다."); } - this.level = eggLevel; + this.level = level; } public static EggType of(String name, String code, Long requiredDistanceInMeters, - Integer eggLevel) { + Integer level) { return EggType.builder() .name(name) .code(code) .requiredDistanceInMeters(requiredDistanceInMeters) - .eggLevel(eggLevel) + .level(level) .build(); } From f66deb1707e004b99a3d9552db691fe01dfb617e Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Thu, 24 Apr 2025 21:48:03 +0900 Subject: [PATCH 12/12] :bug: fix : fix relation from `@OneToOne` to `@ManyToOne` --- src/main/java/org/runimo/runimo/item/domain/Egg.java | 4 ++-- .../org/runimo/runimo/runimo/domain/RunimoDefinition.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/runimo/runimo/item/domain/Egg.java b/src/main/java/org/runimo/runimo/item/domain/Egg.java index 1ed2972c..7f8dc1c5 100644 --- a/src/main/java/org/runimo/runimo/item/domain/Egg.java +++ b/src/main/java/org/runimo/runimo/item/domain/Egg.java @@ -7,7 +7,7 @@ import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; -import jakarta.persistence.OneToOne; +import jakarta.persistence.ManyToOne; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -21,7 +21,7 @@ public class Egg extends Item { public static final Egg EMPTY = new Egg(EMPTYFIELD, EMPTYFIELD, EMPTYFIELD, EMPTYFIELD, EggType.EMPTY, 0L); - @OneToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "egg_type_id", referencedColumnName = "id") private EggType eggType; @Column(name = "hatch_require_amount") diff --git a/src/main/java/org/runimo/runimo/runimo/domain/RunimoDefinition.java b/src/main/java/org/runimo/runimo/runimo/domain/RunimoDefinition.java index 8d5408b1..f684afd1 100644 --- a/src/main/java/org/runimo/runimo/runimo/domain/RunimoDefinition.java +++ b/src/main/java/org/runimo/runimo/runimo/domain/RunimoDefinition.java @@ -2,8 +2,9 @@ import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; -import jakarta.persistence.OneToOne; +import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import lombok.AccessLevel; import lombok.Builder; @@ -30,8 +31,7 @@ public class RunimoDefinition extends BaseEntity { @Column(name = "img_url") private String imgUrl; - - @OneToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "egg_type_id", nullable = false) private EggType type;