From 12ecdfe0ab0f11089ab24a4c884e69d07c15c462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A2=85=EB=AF=B8=28=EB=AF=B8=EC=95=84=29?= <101439796+jongmee@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:17:25 +0900 Subject: [PATCH] =?UTF-8?q?[BE-FEAT]=20=ED=8F=AC=EC=BC=93=EB=AA=AC?= =?UTF-8?q?=EC=9D=98=20=EA=B8=B0=EC=88=A0=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=B6=88=EB=9F=AC=EC=98=A4=EB=8A=94=20API=20(#237)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: WeatherRepository 컴포넌트 애너테이션 변경 * feat: 기술 데이터 세팅 * refactor: 기술 id 저장 데이터 변경 * feat: 포켓몬의 기술 데이터 세팅 * feat: 포켓몬의 기술 리스트 불러오는 api * chore: 기술 데이터 추가 * feat: 기술 리스트에서 타입, 카테고리 로고 함께 반환 * fix: 빈 문자열 저장하는 오류 * refactor: 포켓몬 타입 enum 생성 * test: 모든 도감 번호에 대해서 기술 리스트 조회 테스트 * refactor: 포켓몬 타입 레포지토리 생성 * refactor: 기술 카테고리 enum 생성 * style: 개행 추가 * style: enum 개행 추가 * chore: 데이터 추가 히스토리 맞추기 * fix: 중복되는 bean 이름 변경 --- .../external/s3/service/S3Service.java | 10 +- .../helper/battle/BattleController.java | 6 + .../pokerogue/helper/battle/BattleMove.java | 20 +++ .../helper/battle/BattleMoveRepository.java | 27 ++++ .../battle/BattlePokemonTypeRepository.java | 27 ++++ .../helper/battle/BattleService.java | 44 +++++++ .../helper/battle/DataInitializer.java | 121 ++++++++++++++++-- .../pokerogue/helper/battle/MoveCategory.java | 34 +++++ .../pokerogue/helper/battle/MoveResponse.java | 24 ++++ .../helper/battle/PokemonMovesByEgg.java | 6 + .../battle/PokemonMovesByEggRepository.java | 27 ++++ .../helper/battle/PokemonMovesByMachine.java | 6 + .../PokemonMovesByMachineRepository.java | 27 ++++ .../helper/battle/PokemonMovesBySelf.java | 6 + .../battle/PokemonMovesBySelfRepository.java | 27 ++++ .../pokerogue/helper/battle/PokemonType.java | 4 + .../helper/battle/WeatherRepository.java | 4 +- .../helper/global/exception/ErrorMessage.java | 10 +- .../repository/PokemonTypeRepository.java | 2 + backend/pokerogue/src/main/resources | 2 +- .../helper/battle/BattleServiceTest.java | 32 +++++ .../helper/battle/DataInitializerTest.java | 30 ++++- 22 files changed, 476 insertions(+), 20 deletions(-) create mode 100644 backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleMove.java create mode 100644 backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleMoveRepository.java create mode 100644 backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattlePokemonTypeRepository.java create mode 100644 backend/pokerogue/src/main/java/com/pokerogue/helper/battle/MoveCategory.java create mode 100644 backend/pokerogue/src/main/java/com/pokerogue/helper/battle/MoveResponse.java create mode 100644 backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByEgg.java create mode 100644 backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByEggRepository.java create mode 100644 backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByMachine.java create mode 100644 backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByMachineRepository.java create mode 100644 backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesBySelf.java create mode 100644 backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesBySelfRepository.java create mode 100644 backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonType.java create mode 100644 backend/pokerogue/src/test/java/com/pokerogue/helper/battle/BattleServiceTest.java diff --git a/backend/pokerogue/src/main/java/com/pokerogue/external/s3/service/S3Service.java b/backend/pokerogue/src/main/java/com/pokerogue/external/s3/service/S3Service.java index 474b8a83e..42aa7521a 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/external/s3/service/S3Service.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/external/s3/service/S3Service.java @@ -14,7 +14,10 @@ public class S3Service { private static final String POKEMON_IMAGE_FOLDER = "image/"; private static final String TYPE_IMAGE_FOLDER = "type/"; + private static final String POKEROGUE_TYPE_IMAGE_FOLDER = "pokerogue/type/"; + private static final String POKEROGUE_MOVE_CATEGORY_IMAGE_FOLDER = "pokerogue/move-category/"; private static final String SVG_EXTENSION = ".svg"; + private static final String PNG_EXTENSION = ".png"; private final S3ImageClient s3ImageClient; @@ -35,6 +38,11 @@ private String makeRandomFileName() { } private String makeTypeFileName(String typeName) { - return TYPE_IMAGE_FOLDER + typeName + SVG_EXTENSION; + return TYPE_IMAGE_FOLDER + typeName + SVG_EXTENSION; + } + + public String getPokerogueTypeImageFromS3(String typeName) { + String key = POKEROGUE_TYPE_IMAGE_FOLDER + typeName + "-1" + PNG_EXTENSION; + return s3ImageClient.getFileUrl(key); } } diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleController.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleController.java index 2f0f7a411..2f513985a 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleController.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleController.java @@ -5,6 +5,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @Slf4j @@ -18,4 +19,9 @@ public class BattleController { public ApiResponse> weatherList() { return new ApiResponse<>("날씨 리스트 불러오기에 성공했습니다.", battleService.findWeathers()); } + + @GetMapping("/api/v1/moves") + public ApiResponse> moveByPokemonList(@RequestParam("pokedex-number") Integer pokedexNumber) { + return new ApiResponse<>("포켓몬의 기술 리스트 불러오기에 성공했습니다.", battleService.findMovesByPokemon(pokedexNumber)); + } } diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleMove.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleMove.java new file mode 100644 index 000000000..3c80dc4ed --- /dev/null +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleMove.java @@ -0,0 +1,20 @@ +package com.pokerogue.helper.battle; + +public record BattleMove( + String id, + String name, + String nameAppend, + String effect, + String type, + String defaultTypeId, + String category, + String moveTarget, + Integer power, + Integer accuracy, + Integer pp, + Integer chance, + Integer priority, + Integer generation, + String flags +) { +} diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleMoveRepository.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleMoveRepository.java new file mode 100644 index 000000000..6fb0fe999 --- /dev/null +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleMoveRepository.java @@ -0,0 +1,27 @@ +package com.pokerogue.helper.battle; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.springframework.stereotype.Repository; + +@Repository +public class BattleMoveRepository { + + private final Map moves = new HashMap<>(); + + public void save(BattleMove battleMove) { + moves.put(battleMove.id(), battleMove); + } + + public List findAll() { + return moves.values() + .stream() + .toList(); + } + + public Optional findById(String id) { + return Optional.ofNullable(moves.get(id)); + } +} diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattlePokemonTypeRepository.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattlePokemonTypeRepository.java new file mode 100644 index 000000000..ae9768638 --- /dev/null +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattlePokemonTypeRepository.java @@ -0,0 +1,27 @@ +package com.pokerogue.helper.battle; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.springframework.stereotype.Repository; + +@Repository +public class BattlePokemonTypeRepository { + + private final Map pokemonTypes = new HashMap<>(); + + public void save(PokemonType pokemonType) { + pokemonTypes.put(pokemonType.name(), pokemonType); + } + + public List findAll() { + return pokemonTypes.values() + .stream() + .toList(); + } + + public Optional findByName(String name) { + return Optional.ofNullable(pokemonTypes.get(name)); + } +} diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleService.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleService.java index 6cb0725ef..1679d7735 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleService.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/BattleService.java @@ -1,5 +1,8 @@ package com.pokerogue.helper.battle; +import com.pokerogue.helper.global.exception.ErrorMessage; +import com.pokerogue.helper.global.exception.GlobalCustomException; +import java.util.ArrayList; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -9,10 +12,51 @@ public class BattleService { private final WeatherRepository weatherRepository; + private final BattleMoveRepository battleMoveRepository; + private final PokemonMovesByEggRepository pokemonMovesByEggRepository; + private final PokemonMovesBySelfRepository pokemonMovesBySelfRepository; + private final PokemonMovesByMachineRepository pokemonMovesByMachineRepository; + private final BattlePokemonTypeRepository battlePokemonTypeRepository; public List findWeathers() { return weatherRepository.findAll().stream() .map(WeatherResponse::from) .toList(); } + + public List findMovesByPokemon(Integer pokedexNumber) { + List allMoveIds = new ArrayList<>(); + PokemonMovesBySelf pokemonMovesBySelf = pokemonMovesBySelfRepository.findByPokedexNumber(pokedexNumber) + .orElseThrow(() -> new GlobalCustomException(ErrorMessage.MOVE_BY_SELF_NOT_FOUND)); + PokemonMovesByMachine pokemonMovesByMachine = pokemonMovesByMachineRepository.findByPokedexNumber(pokedexNumber) + .orElseThrow(() -> new GlobalCustomException(ErrorMessage.MOVE_BY_MACHINE_NOT_FOUND)); + PokemonMovesByEgg pokemonMovesByEgg = pokemonMovesByEggRepository.findByPokedexNumber(pokedexNumber) + .orElseThrow(() -> new GlobalCustomException(ErrorMessage.MOVE_BY_EGG_NOT_FOUND)); + + allMoveIds.addAll(pokemonMovesBySelf.moveIds()); + allMoveIds.addAll(pokemonMovesByMachine.moveIds()); + allMoveIds.addAll(pokemonMovesByEgg.moveIds()); + List battleMoves = allMoveIds.stream() + .map(this::findMoveById) + .toList(); + + return battleMoves.stream() + .map(this::toMoveResponseWithLogo) + .toList(); + } + + private BattleMove findMoveById(String id) { + return battleMoveRepository.findById(id) + .orElseThrow(() -> new GlobalCustomException(ErrorMessage.MOVE_NOT_FOUND)); + } + + private MoveResponse toMoveResponseWithLogo(BattleMove battleMove) { + PokemonType pokemonType = battlePokemonTypeRepository.findByName(battleMove.type()) + .orElseThrow(() -> new GlobalCustomException(ErrorMessage.POKEMON_TYPE_NOT_FOUND)); + String typeLogo = pokemonType.image(); + MoveCategory moveCategory = MoveCategory.findByName(battleMove.category().toLowerCase()); + String categoryLogo = moveCategory.getName(); + + return MoveResponse.of(battleMove, typeLogo, categoryLogo); + } } diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/DataInitializer.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/DataInitializer.java index 3f7928235..23071685c 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/DataInitializer.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/DataInitializer.java @@ -1,12 +1,13 @@ package com.pokerogue.helper.battle; +import com.pokerogue.external.s3.service.S3Service; import java.io.BufferedReader; -import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Arrays; import java.util.List; +import java.util.function.Consumer; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.ApplicationArguments; @@ -18,45 +19,143 @@ @RequiredArgsConstructor public class DataInitializer implements ApplicationRunner { - private static final int FIRST_LINE = 3; + private static final int FIRST_LINE_NUMBER = 3; private static final String FIELD_DELIMITER = "/"; private static final String LIST_DELIMITER = ","; private final WeatherRepository weatherRepository; + private final BattleMoveRepository battleMoveRepository; + private final PokemonMovesByMachineRepository pokemonMovesByMachineRepository; + private final PokemonMovesBySelfRepository pokemonMovesBySelfRepository; + private final PokemonMovesByEggRepository pokemonMovesByEggRepository; + private final BattlePokemonTypeRepository battlePokemonTypeRepository; + private final S3Service s3Service; @Override public void run(ApplicationArguments args) { - try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("weather.txt"); + saveData("weather.txt", fields -> { + Weather weather = createWeather(fields); + weatherRepository.save(weather); + }); + saveData("battle-move.txt", fields -> { + BattleMove battleMove = createMove(fields); + battleMoveRepository.save(battleMove); + }); + saveData("tms.txt", fields -> { + PokemonMovesByMachine pokemonMovesByMachine = createPokemonMovesByMachine(fields); + pokemonMovesByMachineRepository.save(pokemonMovesByMachine); + }); + saveData("battle-pokemon.txt", fields -> { + PokemonMovesBySelf pokemonMovesBySelf = createPokemonMovesBySelf(fields); + pokemonMovesBySelfRepository.save(pokemonMovesBySelf); + PokemonMovesByEgg pokemonMovesByEgg = createPokemonMovesByEgg(fields); + pokemonMovesByEggRepository.save(pokemonMovesByEgg); + }); + saveData("type.txt", fields -> { + PokemonType pokemonType = createPokemonType(fields); + battlePokemonTypeRepository.save(pokemonType); + }); + } + + private void saveData(String path, Consumer> createAndSaveOperation) { + try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(path); BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { int lineCount = 0; String line; while ((line = br.readLine()) != null) { lineCount++; - if (lineCount < FIRST_LINE) { + if (lineCount < FIRST_LINE_NUMBER) { continue; } - Weather weather = createWeather(line); - weatherRepository.save(weather); + List fields = splitFields(line); + createAndSaveOperation.accept(fields); } } catch (IOException e) { - log.error("error message : {}", e.getStackTrace()[0]); + log.error("error message : {}", e.getMessage(), e); } } - private Weather createWeather(String data) { - List fields = Arrays.stream(data.split(FIELD_DELIMITER)) + private List splitFields(String line) { + return Arrays.stream(line.split(FIELD_DELIMITER)) .map(String::trim) .toList(); + } + + private Weather createWeather(List fields) { String id = fields.get(0); String name = fields.get(1); String description = fields.get(2); List effects = Arrays.stream(fields.get(3).split(LIST_DELIMITER)) .map(String::trim) .toList(); + return new Weather(id, name, description, effects); } - private String createId(String data) { - return data.replace(' ', '-'); + private BattleMove createMove(List fields) { + return new BattleMove( + fields.get(1), /* 우선은 한글 이름을 id로 설정, 추후 숫자로 변경 */ + fields.get(1), + fields.get(2), + fields.get(3), + fields.get(4), + fields.get(5), + fields.get(6), + fields.get(7), + convertToInteger(fields.get(8)), + convertToInteger(fields.get(9)), + convertToInteger(fields.get(10)), + convertToInteger(fields.get(11)), + convertToInteger(fields.get(12)), + convertToInteger(fields.get(13)), + fields.get(14) + ); + } + + private PokemonMovesByMachine createPokemonMovesByMachine(List fields) { + Integer pokedexNumber = convertToInteger(fields.get(0)); + List moveIds = Arrays.stream(fields.get(2).split(LIST_DELIMITER)) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .toList(); + + return new PokemonMovesByMachine(pokedexNumber, moveIds); + } + + private PokemonMovesBySelf createPokemonMovesBySelf(List fields) { + Integer pokedexNumber = convertToInteger(fields.get(0)); + List moveIds = Arrays.stream(fields.get(19).split(LIST_DELIMITER)) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .toList(); + + return new PokemonMovesBySelf(pokedexNumber, moveIds); + } + + private PokemonMovesByEgg createPokemonMovesByEgg(List fields) { + Integer pokedexNumber = convertToInteger(fields.get(0)); + List moveIds = Arrays.stream(fields.get(18).split(LIST_DELIMITER)) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .toList(); + + return new PokemonMovesByEgg(pokedexNumber, moveIds); + } + + private PokemonType createPokemonType(List fields) { + String name = fields.get(0); + String engName = fields.get(1); + String image = s3Service.getPokerogueTypeImageFromS3(engName); + + return new PokemonType(name, engName, image); + } + + + private Integer convertToInteger(String data) { + try { + return Integer.valueOf(data); + } catch (NumberFormatException e) { + return null; + } } } diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/MoveCategory.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/MoveCategory.java new file mode 100644 index 000000000..cc880f16f --- /dev/null +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/MoveCategory.java @@ -0,0 +1,34 @@ +package com.pokerogue.helper.battle; + +import com.pokerogue.helper.global.exception.ErrorMessage; +import com.pokerogue.helper.global.exception.GlobalCustomException; +import java.util.Arrays; +import lombok.Getter; + +@Getter +public enum MoveCategory { + + STATUS("status", "https://dl70s9ccojnge.cloudfront.net/pokerogue-helper/pokerogue/move-category/status.png"), + SPECIAL("special", "https://dl70s9ccojnge.cloudfront.net/pokerogue-helper/pokerogue/move-category/special.png"), + PHYSICAL("physical", "https://dl70s9ccojnge.cloudfront.net/pokerogue-helper/pokerogue/move-category/physical.png"), + ; + + private final String name; + private final String image; + + MoveCategory(String name, String image) { + this.name = name; + this.image = image; + } + + public static MoveCategory findByName(String name) { + return Arrays.stream(values()) + .filter(category -> category.hasSameName(name)) + .findAny() + .orElseThrow(() -> new GlobalCustomException(ErrorMessage.MOVE_CATEGORY_NOT_FOUND)); + } + + private boolean hasSameName(String name) { + return this.name.equals(name); + } +} diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/MoveResponse.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/MoveResponse.java new file mode 100644 index 000000000..161965384 --- /dev/null +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/MoveResponse.java @@ -0,0 +1,24 @@ +package com.pokerogue.helper.battle; + +public record MoveResponse( + String id, + String name, + String typeLogo, + String categoryLogo, + Integer power, + Integer accuracy, + String effect +) { + + public static MoveResponse of(BattleMove battleMove, String typeLogo, String categoryLogo) { + return new MoveResponse( + battleMove.id(), + battleMove.name(), + typeLogo, + categoryLogo, + battleMove.power(), + battleMove.accuracy(), + battleMove.effect() + ); + } +} diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByEgg.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByEgg.java new file mode 100644 index 000000000..f62d2aaa7 --- /dev/null +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByEgg.java @@ -0,0 +1,6 @@ +package com.pokerogue.helper.battle; + +import java.util.List; + +public record PokemonMovesByEgg(Integer pokedexNumber, List moveIds) { +} diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByEggRepository.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByEggRepository.java new file mode 100644 index 000000000..1a1aacd5e --- /dev/null +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByEggRepository.java @@ -0,0 +1,27 @@ +package com.pokerogue.helper.battle; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.springframework.stereotype.Repository; + +@Repository +public class PokemonMovesByEggRepository { + + private final Map pokemonsMovesByEgg = new HashMap<>(); + + public void save(PokemonMovesByEgg pokemonMovesByEgg) { + pokemonsMovesByEgg.put(pokemonMovesByEgg.pokedexNumber(), pokemonMovesByEgg); + } + + public List findAll() { + return pokemonsMovesByEgg.values() + .stream() + .toList(); + } + + public Optional findByPokedexNumber(Integer pokedexNumber) { + return Optional.ofNullable(pokemonsMovesByEgg.get(pokedexNumber)); + } +} diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByMachine.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByMachine.java new file mode 100644 index 000000000..550219984 --- /dev/null +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByMachine.java @@ -0,0 +1,6 @@ +package com.pokerogue.helper.battle; + +import java.util.List; + +public record PokemonMovesByMachine(Integer pokedexNumber, List moveIds) { +} diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByMachineRepository.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByMachineRepository.java new file mode 100644 index 000000000..ae6cfdfd0 --- /dev/null +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesByMachineRepository.java @@ -0,0 +1,27 @@ +package com.pokerogue.helper.battle; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.springframework.stereotype.Repository; + +@Repository +public class PokemonMovesByMachineRepository { + + private final Map pokemonsMovesByMachine = new HashMap<>(); + + public void save(PokemonMovesByMachine pokemonMovesByMachine) { + pokemonsMovesByMachine.put(pokemonMovesByMachine.pokedexNumber(), pokemonMovesByMachine); + } + + public List findAll() { + return pokemonsMovesByMachine.values() + .stream() + .toList(); + } + + public Optional findByPokedexNumber(Integer pokedexNumber) { + return Optional.ofNullable(pokemonsMovesByMachine.get(pokedexNumber)); + } +} diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesBySelf.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesBySelf.java new file mode 100644 index 000000000..3def5dcaf --- /dev/null +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesBySelf.java @@ -0,0 +1,6 @@ +package com.pokerogue.helper.battle; + +import java.util.List; + +public record PokemonMovesBySelf(Integer pokedexNumber, List moveIds) { +} diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesBySelfRepository.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesBySelfRepository.java new file mode 100644 index 000000000..ff06be3a1 --- /dev/null +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonMovesBySelfRepository.java @@ -0,0 +1,27 @@ +package com.pokerogue.helper.battle; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.springframework.stereotype.Repository; + +@Repository +public class PokemonMovesBySelfRepository { + + private final Map pokemonsMovesBySelf = new HashMap<>(); + + public void save(PokemonMovesBySelf pokemonMovesBySelf) { + pokemonsMovesBySelf.put(pokemonMovesBySelf.pokedexNumber(), pokemonMovesBySelf); + } + + public List findAll() { + return pokemonsMovesBySelf.values() + .stream() + .toList(); + } + + public Optional findByPokedexNumber(Integer pokedexNumber) { + return Optional.ofNullable(pokemonsMovesBySelf.get(pokedexNumber)); + } +} diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonType.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonType.java new file mode 100644 index 000000000..0b5905041 --- /dev/null +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/PokemonType.java @@ -0,0 +1,4 @@ +package com.pokerogue.helper.battle; + +public record PokemonType(String name, String engName, String image) { +} diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/WeatherRepository.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/WeatherRepository.java index a99251496..02ff5b514 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/WeatherRepository.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/battle/WeatherRepository.java @@ -3,9 +3,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Repository; -@Component +@Repository public class WeatherRepository { private final Map weathers = new HashMap<>(); diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/global/exception/ErrorMessage.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/global/exception/ErrorMessage.java index ddf2f746b..9a73cef6f 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/global/exception/ErrorMessage.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/global/exception/ErrorMessage.java @@ -15,9 +15,15 @@ public enum ErrorMessage { TIER_NOT_FOUND(HttpStatus.NOT_FOUND, "해당하는 티어를 찾지 못했습니다."), TRAINER_NOT_FOUND(HttpStatus.NOT_FOUND, "해당하는 트레이너를 찾지 못했습니다."), BIOME_NOT_FOUND(HttpStatus.NOT_FOUND, "해당하는 바이옴을 찾지 못했습니다."), - FILE_ACCESS_FAILED(HttpStatus.BAD_REQUEST, "파일 정보 접근에 실패했습니다."), + MOVE_BY_MACHINE_NOT_FOUND(HttpStatus.NOT_FOUND, "도감 번호에 해당하는 머신으로 배울 수 있는 기술을 찾지 못했습니다."), + MOVE_BY_EGG_NOT_FOUND(HttpStatus.NOT_FOUND, "도감 번호에 해당하는 알 기술을 찾지 못했습니다."), + MOVE_BY_SELF_NOT_FOUND(HttpStatus.NOT_FOUND, "도감 번호에 해당하는 자력 기술을 찾지 못했습니다."), + MOVE_NOT_FOUND(HttpStatus.NOT_FOUND, "id에 해당하는 기술을 찾지 못했습니다."), + MOVE_CATEGORY_NOT_FOUND(HttpStatus.NOT_FOUND, "기술 카테고리를 찾지 못했습니다."), - FILE_EXTENSION_NOT_APPLY(HttpStatus.BAD_REQUEST, "지원하지 않는 파일 형식입니다."); + FILE_ACCESS_FAILED(HttpStatus.BAD_REQUEST, "파일 정보 접근에 실패했습니다."), + FILE_EXTENSION_NOT_APPLY(HttpStatus.BAD_REQUEST, "지원하지 않는 파일 형식입니다."), + ; private final HttpStatus httpStatus; private final String message; diff --git a/backend/pokerogue/src/main/java/com/pokerogue/helper/type/repository/PokemonTypeRepository.java b/backend/pokerogue/src/main/java/com/pokerogue/helper/type/repository/PokemonTypeRepository.java index 177fee08a..d92db5916 100644 --- a/backend/pokerogue/src/main/java/com/pokerogue/helper/type/repository/PokemonTypeRepository.java +++ b/backend/pokerogue/src/main/java/com/pokerogue/helper/type/repository/PokemonTypeRepository.java @@ -1,7 +1,9 @@ package com.pokerogue.helper.type.repository; import com.pokerogue.helper.type.domain.PokemonType; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface PokemonTypeRepository extends JpaRepository { + Optional findByKoName(String koName); } diff --git a/backend/pokerogue/src/main/resources b/backend/pokerogue/src/main/resources index f813631b9..fccc26bdc 160000 --- a/backend/pokerogue/src/main/resources +++ b/backend/pokerogue/src/main/resources @@ -1 +1 @@ -Subproject commit f813631b9d97795ef56cb25020733208a8175fce +Subproject commit fccc26bdc50a03988130cb523e555d6119a60dfb diff --git a/backend/pokerogue/src/test/java/com/pokerogue/helper/battle/BattleServiceTest.java b/backend/pokerogue/src/test/java/com/pokerogue/helper/battle/BattleServiceTest.java new file mode 100644 index 000000000..8f58e3c42 --- /dev/null +++ b/backend/pokerogue/src/test/java/com/pokerogue/helper/battle/BattleServiceTest.java @@ -0,0 +1,32 @@ +package com.pokerogue.helper.battle; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.pokerogue.environment.service.ServiceTest; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +class BattleServiceTest extends ServiceTest { + + @Autowired + private BattleService battleService; + + @Autowired + private PokemonMovesByMachineRepository pokemonMovesByMachineRepository; + + @Test + @DisplayName("포켓몬의 기술(자력 기술, 머신 기술, 알 기술) 리스트를 조회한다.") + void findMovesByPokemon() { + List pokedexNumbers = pokemonMovesByMachineRepository.findAll() + .stream() + .map(PokemonMovesByMachine::pokedexNumber) + .toList(); + + pokedexNumbers.forEach(pokedexNumber -> { + List moveResponses = battleService.findMovesByPokemon(pokedexNumber); + assertThat(moveResponses).isNotEmpty(); + }); + } +} diff --git a/backend/pokerogue/src/test/java/com/pokerogue/helper/battle/DataInitializerTest.java b/backend/pokerogue/src/test/java/com/pokerogue/helper/battle/DataInitializerTest.java index f2a2e79a3..bf1926012 100644 --- a/backend/pokerogue/src/test/java/com/pokerogue/helper/battle/DataInitializerTest.java +++ b/backend/pokerogue/src/test/java/com/pokerogue/helper/battle/DataInitializerTest.java @@ -1,7 +1,10 @@ package com.pokerogue.helper.battle; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import com.pokerogue.environment.client.FakeS3ImageClient; +import com.pokerogue.external.s3.service.S3Service; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.DefaultApplicationArguments; @@ -9,12 +12,33 @@ class DataInitializerTest { @Test - @DisplayName("날씨 데이터를 세팅한다.") + @DisplayName("날씨, 기술 데이터를 세팅한다.") void setWeathersData() { WeatherRepository weatherRepository = new WeatherRepository(); - DataInitializer dataInitializer = new DataInitializer(weatherRepository); + BattleMoveRepository battleMoveRepository = new BattleMoveRepository(); + PokemonMovesByMachineRepository pokemonMovesByMachineRepository = new PokemonMovesByMachineRepository(); + PokemonMovesBySelfRepository pokemonMovesBySelfRepository = new PokemonMovesBySelfRepository(); + PokemonMovesByEggRepository pokemonMovesByEggRepository = new PokemonMovesByEggRepository(); + BattlePokemonTypeRepository battlePokemonTypeRepository = new BattlePokemonTypeRepository(); + S3Service s3Service = new S3Service(new FakeS3ImageClient()); + DataInitializer dataInitializer = new DataInitializer( + weatherRepository, + battleMoveRepository, + pokemonMovesByMachineRepository, + pokemonMovesBySelfRepository, + pokemonMovesByEggRepository, + battlePokemonTypeRepository, + s3Service + ); dataInitializer.run(new DefaultApplicationArguments()); - assertThat(weatherRepository.findAll()).hasSize(10); + assertAll(() -> { + assertThat(weatherRepository.findAll()).hasSize(10); + assertThat(battleMoveRepository.findAll()).hasSize(902); + assertThat(pokemonMovesByMachineRepository.findAll()).hasSize(1082); + assertThat(pokemonMovesBySelfRepository.findAll()).hasSize(1082); + assertThat(pokemonMovesByEggRepository.findAll()).hasSize(1082); + assertThat(battlePokemonTypeRepository.findAll()).hasSize(20); + }); } }