From 4a506a5009cf664e510093a4d55dac1a3a8a1924 Mon Sep 17 00:00:00 2001 From: zillionme <100172683+zillionme@users.noreply.github.com> Date: Wed, 8 Nov 2023 11:05:39 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=9D=BD=EC=9D=80=20=EC=AA=BD=EC=A7=80?= =?UTF-8?q?=20=EB=A1=9C=EA=B7=B8=20=EC=A4=91=EB=B3=B5=20=EC=AA=BD=EC=A7=80?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0=20(#541)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: 이미 읽은 쪽지는 로깅하지 않는 테스트 * feat: 이미 읽은 쪽지는 로깅하지 않는 기능 추가 * chore: letter 패키지 수정과 충돌 해결 및 커밋 --- .../exception/ControllerExceptionHandler.java | 8 +- .../letter/application/LetterService.java | 14 ++- .../letterlog/ReadLetterLogRepository.java | 4 + .../letter/application/LetterServiceTest.java | 103 +++++++++++++++++- 4 files changed, 122 insertions(+), 7 deletions(-) diff --git a/backend/src/main/java/com/now/naaga/common/exception/ControllerExceptionHandler.java b/backend/src/main/java/com/now/naaga/common/exception/ControllerExceptionHandler.java index 2964d570d..0ede463ff 100644 --- a/backend/src/main/java/com/now/naaga/common/exception/ControllerExceptionHandler.java +++ b/backend/src/main/java/com/now/naaga/common/exception/ControllerExceptionHandler.java @@ -39,17 +39,17 @@ public ResponseEntity handleTypeMismatchException(final Excep return ResponseEntity.status(commonExceptionType.httpStatus()).body(exceptionResponse); } - + @ExceptionHandler(MethodArgumentTypeMismatchException.class) public ResponseEntity handleArgumentTypeMismatchException(final Exception e) { final CommonExceptionType commonExceptionType = CommonExceptionType.INVALID_REQUEST_PARAMETERS; final ExceptionResponse exceptionResponse = new ExceptionResponse(commonExceptionType.errorCode(), commonExceptionType.errorMessage()); - + log.info("error = {}", exceptionResponse); - + return ResponseEntity.status(commonExceptionType.httpStatus()).body(exceptionResponse); } - + @ExceptionHandler(InternalException.class) public ResponseEntity handleInternalException(final InternalException e) { final BaseExceptionType internalExceptionType = e.exceptionType(); diff --git a/backend/src/main/java/com/now/naaga/letter/application/LetterService.java b/backend/src/main/java/com/now/naaga/letter/application/LetterService.java index 47aa47ec3..f7e44998f 100644 --- a/backend/src/main/java/com/now/naaga/letter/application/LetterService.java +++ b/backend/src/main/java/com/now/naaga/letter/application/LetterService.java @@ -20,6 +20,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.Optional; import static com.now.naaga.letter.exception.LetterExceptionType.NO_EXIST; @@ -78,8 +79,17 @@ public Letter findLetter(final LetterReadCommand letterReadCommand) { private void logReadLetter(final Player player, final Letter letter) { final Game gameInProgress = getGameInProgress(player.getId()); - final ReadLetterLog readLetterLog = new ReadLetterLog(gameInProgress, letter); - readLetterLogRepository.save(readLetterLog); + boolean isAlreadyReadLetter = isAlreadyReadLetter(gameInProgress, letter); + if(!isAlreadyReadLetter) { + final ReadLetterLog readLetterLog = new ReadLetterLog(gameInProgress, letter); + readLetterLogRepository.save(readLetterLog); + } + } + private boolean isAlreadyReadLetter(final Game game, + final Letter letter) { + Optional readLetterInGame = readLetterLogRepository + .findByGameIdAndLetterId(game.getId(), letter.getId()); + return readLetterInGame.isPresent(); } @Transactional(readOnly = true) diff --git a/backend/src/main/java/com/now/naaga/letter/repository/letterlog/ReadLetterLogRepository.java b/backend/src/main/java/com/now/naaga/letter/repository/letterlog/ReadLetterLogRepository.java index 7a2d47c79..1aaaeba0f 100644 --- a/backend/src/main/java/com/now/naaga/letter/repository/letterlog/ReadLetterLogRepository.java +++ b/backend/src/main/java/com/now/naaga/letter/repository/letterlog/ReadLetterLogRepository.java @@ -2,9 +2,13 @@ import com.now.naaga.letter.domain.letterlog.ReadLetterLog; import java.util.List; +import java.util.Optional; + import org.springframework.data.jpa.repository.JpaRepository; public interface ReadLetterLogRepository extends JpaRepository { List findByGameId(Long gamedId); + + Optional findByGameIdAndLetterId(Long gam, Long letterId); } diff --git a/backend/src/test/java/com/now/naaga/letter/application/LetterServiceTest.java b/backend/src/test/java/com/now/naaga/letter/application/LetterServiceTest.java index 466162867..3b7cb4ca7 100644 --- a/backend/src/test/java/com/now/naaga/letter/application/LetterServiceTest.java +++ b/backend/src/test/java/com/now/naaga/letter/application/LetterServiceTest.java @@ -39,6 +39,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.SoftAssertions.assertSoftly; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.*; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @ActiveProfiles("test") @@ -63,7 +64,107 @@ class LetterServiceTest { @Autowired private LetterBuilder letterBuilder; - + + @Test + void 이미_읽은_쪽지의_경우_읽은_쪽지_로그를_기록하지_않는다() { + // given + final Player player = playerBuilder.init() + .build(); + + final Place destination = placeBuilder.init() + .position(잠실_루터회관_정문_좌표) + .build(); + + final Game game = gameBuilder.init() + .place(destination) + .player(player) + .startPosition(잠실역_교보문고_좌표) + .build(); + + final Player letterRegister = playerBuilder.init() + .build(); + + final Letter letter = letterBuilder.init() + .registeredPlayer(letterRegister) + .build(); + + LetterService mockReadLetterService = mock(LetterService.class); + + // when + mockReadLetterService.findLetter(new LetterReadCommand(player.getId(), letter.getId())); + mockReadLetterService.findLetter(new LetterReadCommand(player.getId(), letter.getId())); + + //then + verify(mockReadLetterService, atLeast(1)).findLetter(new LetterReadCommand(player.getId(), letter.getId())); + } + + @Test + void 읽은_쪽지_로그를_정상적으로_기록한다() { + // given + final Player player = playerBuilder.init() + .build(); + + final Place destination = placeBuilder.init() + .position(잠실_루터회관_정문_좌표) + .build(); + + final Game game = gameBuilder.init() + .place(destination) + .player(player) + .startPosition(잠실역_교보문고_좌표) + .build(); + + final Player letterRegister = playerBuilder.init() + .build(); + + final Letter letter = letterBuilder.init() + .registeredPlayer(letterRegister) + .build(); + + // when + letterService.findLetter(new LetterReadCommand(player.getId(), letter.getId())); + + // then + final List actual = readLetterLogRepository.findAll(); + final long expected = actual.get(0).getLetter().getId(); + + assertSoftly(softAssertions -> { + softAssertions.assertThat(actual).hasSize(1); + softAssertions.assertThat(expected).isEqualTo(letter.getId()); + }); + } + + + @Test + void 읽은쪽지로그에_데이터저장시_진행중인_게임이없으면_예외가_발생한다() { + // given && when + final Player player = playerBuilder.init() + .build(); + + final Place destination = placeBuilder.init() + .position(잠실_루터회관_정문_좌표) + .build(); + + final Game game = gameBuilder.init() + .place(destination) + .player(player) + .startPosition(잠실역_교보문고_좌표) + .gameStatus(GameStatus.DONE) + .build(); + + final Player letterRegister = playerBuilder.init() + .build(); + + final Letter letter = letterBuilder.init() + .registeredPlayer(letterRegister) + .build(); + + //then + final GameException gameException = assertThrows( + GameException.class, () -> letterService.findLetter(new LetterReadCommand(player.getId(), letter.getId()))); + assertThat(gameException.exceptionType()).isEqualTo(NOT_EXIST_IN_PROGRESS); + } + @Transactional @Test void 쪽지를_정상적으로_생성하고_게임중_등록한_쪽지를_기록으로_남긴다() {