diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/controller/AbilityController.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/controller/AbilityController.java index bab16c4a8..3bccc02ff 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/controller/AbilityController.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/controller/AbilityController.java @@ -25,7 +25,12 @@ public ApiResponse> abilityList() { @GetMapping("/api/v1/ability2/{id}") public ApiResponse abilityDetails(@PathVariable("id") String id) { - log.info("---- URI : {}, Param : {}", "/api/v1/ability/{id}", id); + log.info( + "---- URI : {}, Param : {}, ThreadName : {}", + "/api/v1/ability/{id}", + id, + Thread.currentThread().getName() + ); return new ApiResponse<>("특성 정보 불러오기에 성공했습니다.", abilityService.findAbilityDetails(id)); } diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/data/Ability.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/data/Ability.java index 10539eaf2..5c829c78b 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/data/Ability.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/data/Ability.java @@ -1,14 +1,16 @@ package com.pokerogue.helper.ability.data; -import com.pokerogue.helper.pokemon.data.InMemoryPokemon; import java.util.List; +import lombok.AccessLevel; import lombok.Getter; +import lombok.NoArgsConstructor; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Field; @Getter @Document(collection = "ability") +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Ability { @Id @@ -30,7 +32,7 @@ public class Ability { private int generation; @Field("pokemonIds") - private List pokemonIds; + private List pokemonIds; @Field("isBypassFaint") private Boolean isBypassFaint; @@ -38,13 +40,7 @@ public class Ability { @Field("isIgnorable") private Boolean isIgnorable; - // Todo: 지우기 - private List inMemoryPokemons; - - public Ability(String id, String name, String description, List inMemoryPokemons) { - this.id = id; - this.name = name; - this.description = description; - this.inMemoryPokemons = inMemoryPokemons; + public boolean isPresent() { + return !id.equals("none"); } } diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/data/AbilityInfo.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/data/AbilityInfo.java deleted file mode 100644 index 9041aa682..000000000 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/data/AbilityInfo.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.pokerogue.helper.ability.data; - -import java.util.List; -import lombok.Getter; - -@Getter -public class AbilityInfo { - - private final String id; - private final String name; - private final String description; - private final List pokemons; - private final List pokedexNumbers; - - public AbilityInfo(String abilityInfo) { - String[] abilityInfos = abilityInfo.split(" / "); - this.id = abilityInfos[0]; - this.name = abilityInfos[1]; - this.description = abilityInfos[2]; - this.pokemons = List.of(abilityInfos[4].split(" , ")); - this.pokedexNumbers = List.of(abilityInfos[5].split(" , ")); - } -} diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityDetailResponse.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityDetailResponse.java index 2e7f88771..7b2924a16 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityDetailResponse.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityDetailResponse.java @@ -10,6 +10,6 @@ public record AbilityDetailResponse( ) { public static AbilityDetailResponse of(Ability ability, List pokemons) { - return new AbilityDetailResponse(ability.getName(), ability.getDescription(), pokemons); + return new AbilityDetailResponse(ability.getKoName(), ability.getDescription(), pokemons); } } diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityPokemonResponse.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityPokemonResponse.java index 81e85c435..798a7532c 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityPokemonResponse.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityPokemonResponse.java @@ -1,5 +1,6 @@ package com.pokerogue.helper.ability.dto; +import com.pokerogue.helper.pokemon.data.Pokemon; import java.util.List; public record AbilityPokemonResponse( @@ -9,4 +10,17 @@ public record AbilityPokemonResponse( String image, List pokemonTypeResponses ) { + public static AbilityPokemonResponse of( + Pokemon pokemon, + String image, + List pokemonTypeResponses + ) { + return new AbilityPokemonResponse( + pokemon.getId(), + (long) pokemon.getPokedexNumber(), + pokemon.getKoName(), + image, + pokemonTypeResponses + ); + } } diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityResponse.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityResponse.java index 97e2ca9c5..a12c422a3 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityResponse.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityResponse.java @@ -5,6 +5,6 @@ public record AbilityResponse(String id, String koName, String description) { public static AbilityResponse from(Ability ability) { - return new AbilityResponse(ability.getId(), ability.getName(), ability.getDescription()); + return new AbilityResponse(ability.getId(), ability.getKoName(), ability.getDescription()); } } diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityTypeResponse.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityTypeResponse.java index cb9c8657e..0a2220ec0 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityTypeResponse.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/dto/AbilityTypeResponse.java @@ -1,4 +1,10 @@ package com.pokerogue.helper.ability.dto; +import com.pokerogue.helper.type.data.Type; + public record AbilityTypeResponse(String typeLogo, String typeName) { + + public static AbilityTypeResponse from(Type type) { + return new AbilityTypeResponse(type.getImage(), type.getKoName()); + } } diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/repository/InMemoryAbilityRepository.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/repository/InMemoryAbilityRepository.java deleted file mode 100644 index 8916eb9ab..000000000 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/repository/InMemoryAbilityRepository.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.pokerogue.helper.ability.repository; - -import com.pokerogue.helper.ability.data.Ability; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Repository; - -@Repository -@RequiredArgsConstructor -public class InMemoryAbilityRepository { - - private final Map abilities; - - public InMemoryAbilityRepository() { - this.abilities = new HashMap<>(); - } - - public void save(Ability ability) { - abilities.put(ability.getId(), ability); - } - - public List findAll() { - return abilities.values().stream() - .toList(); - } - - public Optional findById(String id) { - return Optional.ofNullable(abilities.get(id)); - } -} diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/service/AbilityService.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/service/AbilityService.java index 5f97f9886..fc586e13f 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/service/AbilityService.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/ability/service/AbilityService.java @@ -6,11 +6,12 @@ import com.pokerogue.helper.ability.dto.AbilityPokemonResponse; import com.pokerogue.helper.ability.dto.AbilityResponse; import com.pokerogue.helper.ability.dto.AbilityTypeResponse; -import com.pokerogue.helper.ability.repository.InMemoryAbilityRepository; -import com.pokerogue.helper.type.data.Type; +import com.pokerogue.helper.ability.repository.AbilityRepository; import com.pokerogue.helper.global.exception.ErrorMessage; import com.pokerogue.helper.global.exception.GlobalCustomException; -import java.util.ArrayList; +import com.pokerogue.helper.pokemon.data.Pokemon; +import com.pokerogue.helper.pokemon.repository.PokemonRepository; +import com.pokerogue.helper.type.data.Type; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -20,43 +21,45 @@ public class AbilityService { private final S3Service s3Service; - private final InMemoryAbilityRepository inMemoryAbilityRepository; + private final AbilityRepository abilityRepository; + private final PokemonRepository pokemonRepository; public List findAbilities() { - return inMemoryAbilityRepository.findAll().stream() + return abilityRepository.findAll().stream() + .filter(Ability::isPresent) .map(AbilityResponse::from) .toList(); } public AbilityDetailResponse findAbilityDetails(String id) { - Ability ability = inMemoryAbilityRepository.findById(id) + Ability ability = abilityRepository.findById(id) .orElseThrow(() -> new GlobalCustomException(ErrorMessage.POKEMON_ABILITY_NOT_FOUND)); - List abilityPokemonResponses = ability.getInMemoryPokemons().stream() - .map(abilityPokemon -> new AbilityPokemonResponse( - abilityPokemon.id(), - Long.parseLong(abilityPokemon.speciesId()), - abilityPokemon.koName(), - s3Service.getPokemonImageFromS3(abilityPokemon.id()), - getAbilityTypeResponses(abilityPokemon.firstType(), abilityPokemon.secondType()) + List abilityPokemonIds = ability.getPokemonIds(); + List pokemons = pokemonRepository.findAllById(abilityPokemonIds); + validateExistAllPokemonId(abilityPokemonIds, pokemons); + List abilityPokemonResponses = pokemons.stream() + .map(pokemon -> AbilityPokemonResponse.of( + pokemon, + s3Service.getPokemonImageFromS3(pokemon.getImageId()), + getAbilityTypeResponses(pokemon.getTypes()) )) .toList(); return AbilityDetailResponse.of(ability, abilityPokemonResponses); } - private List getAbilityTypeResponses(String firstType, String secondType) { - List abilityTypeResponses = new ArrayList<>(); - if (!firstType.equals("Type.undefined") && !firstType.isEmpty()) { - abilityTypeResponses.add(new AbilityTypeResponse(Type.findByEngName(firstType) - .orElseThrow(() -> new GlobalCustomException(ErrorMessage.POKEMON_TYPE_NOT_FOUND)).getImage(), - firstType)); - } - if (!secondType.equals("Type.undefined") && !secondType.isEmpty()) { - abilityTypeResponses.add(new AbilityTypeResponse(Type.findByEngName(secondType) - .orElseThrow(() -> new GlobalCustomException(ErrorMessage.POKEMON_TYPE_NOT_FOUND)).getImage(), - secondType)); + private static void validateExistAllPokemonId( + List abilityPokemonIds, + List abilityPokemonResponses + ) { + if (abilityPokemonIds.size() != abilityPokemonResponses.size()) { + throw new GlobalCustomException(ErrorMessage.POKEMON_NOT_FOUND); } + } - return abilityTypeResponses; + private List getAbilityTypeResponses(List types) { + return types.stream() + .map(AbilityTypeResponse::from) + .toList(); } } diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/biome/config/BiomeDatabaseInitializer.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/biome/config/BiomeDatabaseInitializer.java deleted file mode 100644 index e69de29bb..000000000 diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/pokemon/config/PokemonDatabaseInitializer.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/pokemon/config/PokemonDatabaseInitializer.java index a4432a330..ad42b9b4a 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/pokemon/config/PokemonDatabaseInitializer.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/pokemon/config/PokemonDatabaseInitializer.java @@ -1,8 +1,5 @@ package com.pokerogue.helper.pokemon.config; -import com.pokerogue.helper.ability.data.Ability; -import com.pokerogue.helper.ability.data.AbilityInfo; -import com.pokerogue.helper.ability.repository.InMemoryAbilityRepository; import com.pokerogue.helper.global.exception.ErrorMessage; import com.pokerogue.helper.global.exception.GlobalCustomException; import com.pokerogue.helper.pokemon.data.Evolution; @@ -46,7 +43,6 @@ public class PokemonDatabaseInitializer implements ApplicationRunner { private final InMemoryPokemonRepository inMemoryPokemonRepository; private final EvolutionRepository evolutionRepository; - private final InMemoryAbilityRepository inMemoryAbilityRepository; private final List pokemonKeys = List.of( "id", "speciesId", @@ -95,7 +91,6 @@ public class PokemonDatabaseInitializer implements ApplicationRunner { public void run(ApplicationArguments args) { save("data/pokemon/pokemon.txt", this::savePokemon); save("data/pokemon/evolution-for-pokemon-response.txt", this::saveEvolution); - saveAbility(); } private void save(String file, Consumer consumer) { @@ -344,43 +339,4 @@ private List parseToken(String line) { return values; } - - private void saveAbility() { - List abilityInfos = new ArrayList<>(); - - try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("data/ability/ability.txt"); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) { - while (true) { - String abilityInfo = bufferedReader.readLine(); - if (abilityInfo == null) { - break; - } - abilityInfos.add(new AbilityInfo(abilityInfo)); - } - } catch (IOException e) { - log.error("error message : {}", e.getStackTrace()[0]); - } - - abilityInfos.stream() - .map(abilityInfo -> new Ability( - abilityInfo.getId(), - abilityInfo.getName(), - abilityInfo.getDescription(), - getAbilityPokemon(abilityInfo.getPokemons())) - ).forEach(inMemoryAbilityRepository::save); - } - - private List getAbilityPokemon(List pokemons) { - List abilityInMemoryPokemons = new ArrayList<>(); - for (int i = 0; i < pokemons.size(); i++) { - String pokemonId = pokemons.get(i); - - InMemoryPokemon inMemoryPokemon = inMemoryPokemonRepository.findById(pokemonId) - .orElseThrow(() -> new GlobalCustomException(ErrorMessage.POKEMON_NOT_FOUND)); - - abilityInMemoryPokemons.add(inMemoryPokemon); - } - - return abilityInMemoryPokemons; - } } diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/pokemon/service/PokemonService.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/pokemon/service/PokemonService.java index 172e14a47..10d8f143f 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/pokemon/service/PokemonService.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/pokemon/service/PokemonService.java @@ -3,7 +3,7 @@ import com.pokerogue.external.s3.service.S3Service; import com.pokerogue.helper.ability.data.Ability; -import com.pokerogue.helper.ability.repository.InMemoryAbilityRepository; +import com.pokerogue.helper.ability.repository.AbilityRepository; import com.pokerogue.helper.biome.data.Biome; import com.pokerogue.helper.biome.repository.BiomeRepository; import com.pokerogue.helper.global.exception.ErrorMessage; @@ -45,7 +45,7 @@ public class PokemonService { private final MoveRepository moveRepository; private final EvolutionRepository evolutionRepository; private final BiomeRepository biomeRepository; - private final InMemoryAbilityRepository inMemoryAbilityRepository; + private final AbilityRepository abilityRepository; private List findAllCache = List.of(); private Map findByIdCache = new HashMap<>(); @@ -186,16 +186,16 @@ private List createStages(EvolutionChain evolutionChain) { private List createAbilityResponse(InMemoryPokemon inMemoryPokemon) { List ret = new ArrayList<>(); - Ability passive = inMemoryAbilityRepository.findById(inMemoryPokemon.abilityPassive()) + Ability passive = abilityRepository.findById(inMemoryPokemon.abilityPassive()) .orElseThrow(() -> new GlobalCustomException(ErrorMessage.POKEMON_ABILITY_NOT_FOUND)); ret.add(new PokemonAbilityResponse( inMemoryPokemon.abilityPassive(), passive.getName(), passive.getDescription(), true, false )); - Ability ability1 = inMemoryAbilityRepository.findById(inMemoryPokemon.ability1()) + Ability ability1 = abilityRepository.findById(inMemoryPokemon.ability1()) .orElseThrow(() -> new GlobalCustomException(ErrorMessage.POKEMON_ABILITY_NOT_FOUND)); - Ability ability2 = inMemoryAbilityRepository.findById(inMemoryPokemon.ability2()) + Ability ability2 = abilityRepository.findById(inMemoryPokemon.ability2()) .orElseThrow(() -> new GlobalCustomException(ErrorMessage.POKEMON_ABILITY_NOT_FOUND)); List defaultAbilities = Stream.of(ability1, ability2) .distinct() @@ -208,14 +208,14 @@ private List createAbilityResponse(InMemoryPokemon inMem ret.addAll(defaultAbilities); if (!inMemoryPokemon.abilityHidden().isEmpty()) { - Ability hidden = inMemoryAbilityRepository.findById(inMemoryPokemon.abilityHidden()) + Ability hidden = abilityRepository.findById(inMemoryPokemon.abilityHidden()) .orElseThrow(() -> new GlobalCustomException(ErrorMessage.POKEMON_ABILITY_NOT_FOUND)); ret.add(new PokemonAbilityResponse(inMemoryPokemon.abilityHidden(), hidden.getName(), hidden.getDescription(), false, true)); for (int i = 1; i < ret.size() - 1; i++) { - if (inMemoryAbilityRepository.findById(ret.get(i).id()) + if (abilityRepository.findById(ret.get(i).id()) .orElseThrow(() -> new GlobalCustomException(ErrorMessage.POKEMON_ABILITY_NOT_FOUND)) == hidden ) { ret.remove(i); diff --git a/backend/pokerogue/src/test/java/com/pokerogue/helper/ability/service/AbilityServiceTest.java b/backend/pokerogue/src/test/java/com/pokerogue/helper/ability/service/AbilityServiceTest.java new file mode 100644 index 000000000..6cc13cf87 --- /dev/null +++ b/backend/pokerogue/src/test/java/com/pokerogue/helper/ability/service/AbilityServiceTest.java @@ -0,0 +1,35 @@ +package com.pokerogue.helper.ability.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import com.pokerogue.environment.service.ServiceTest; +import com.pokerogue.helper.ability.dto.AbilityDetailResponse; +import com.pokerogue.helper.ability.dto.AbilityResponse; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +class AbilityServiceTest extends ServiceTest { + + @Autowired + private AbilityService abilityService; + + @Test + void findAbilities() { + List abilityResponses = abilityService.findAbilities(); + + assertThat(abilityResponses).hasSize(310); + } + + @Test + void findAbilityDetails() { + AbilityDetailResponse abilityDetails = abilityService.findAbilityDetails("stench"); + + assertAll( + () -> assertThat(abilityDetails.koName()).isEqualTo("악취"), + () -> assertThat(abilityDetails.description()).isEqualTo("악취를 풍겨서 공격했을 때 상대가 풀죽을 때가 있다."), + () -> assertThat(abilityDetails.pokemons()).hasSize(9) + ); + } +} diff --git a/backend/pokerogue/src/test/java/com/pokerogue/helper/pokemon/data/InMemoryPokemonDatabaseInitializerTest.java b/backend/pokerogue/src/test/java/com/pokerogue/helper/pokemon/data/InMemoryPokemonDatabaseInitializerTest.java index d634db1ce..e9365f9ae 100644 --- a/backend/pokerogue/src/test/java/com/pokerogue/helper/pokemon/data/InMemoryPokemonDatabaseInitializerTest.java +++ b/backend/pokerogue/src/test/java/com/pokerogue/helper/pokemon/data/InMemoryPokemonDatabaseInitializerTest.java @@ -1,6 +1,5 @@ package com.pokerogue.helper.pokemon.data; -import com.pokerogue.helper.ability.repository.InMemoryAbilityRepository; import com.pokerogue.helper.pokemon.config.PokemonDatabaseInitializer; import com.pokerogue.helper.pokemon.repository.EvolutionRepository; import com.pokerogue.helper.pokemon.repository.InMemoryPokemonRepository; @@ -19,8 +18,7 @@ void savePokemonCount() { InMemoryPokemonRepository inMemoryPokemonRepository = new InMemoryPokemonRepository(); PokemonDatabaseInitializer pokemonDatabaseInitializer = new PokemonDatabaseInitializer( inMemoryPokemonRepository, - new EvolutionRepository(), - new InMemoryAbilityRepository() + new EvolutionRepository() ); pokemonDatabaseInitializer.run(new DefaultApplicationArguments()); @@ -36,8 +34,7 @@ void savePokemonNames(String name) { InMemoryPokemonRepository inMemoryPokemonRepository = new InMemoryPokemonRepository(); PokemonDatabaseInitializer pokemonDatabaseInitializer = new PokemonDatabaseInitializer( inMemoryPokemonRepository, - new EvolutionRepository(), - new InMemoryAbilityRepository() + new EvolutionRepository() ); pokemonDatabaseInitializer.run(new DefaultApplicationArguments());