From 48425dc4d1117a5dda7683be5d49da1d2995e2a3 Mon Sep 17 00:00:00 2001 From: Park - Jeonghwan <990706leo@gmail.com> Date: Fri, 23 Aug 2024 20:07:10 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20AttributeConverter=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../applegame/domain/game/AppleGame.java | 26 ++++++------ .../game/{Board.java => AppleGameBoard.java} | 10 ++--- ...rter.java => AppleGameBoardConverter.java} | 10 ++--- .../applegame/service/AppleGameService.java | 6 +-- .../controller/SnackgameController.kt | 2 +- .../server/game/snackgame/domain/Board.kt | 1 + .../game/snackgame/domain/BoardConverter.kt | 3 +- .../server/game/snackgame/domain/Snackgame.kt | 2 + .../service/dto/SnackgameResponse.kt | 5 ++- ....java => AppleGameBoardConverterTest.java} | 16 ++++---- ...BoardTest.java => AppleGameBoardTest.java} | 14 +++---- .../applegame/domain/game/AppleGameTest.java | 4 +- .../server/applegame/fixture/TestFixture.java | 10 ++--- .../service/AppleGameServiceTest.java | 4 +- .../snackgame/service/SnackgameServiceTest.kt | 41 +++++++++++++++++++ 15 files changed, 100 insertions(+), 54 deletions(-) rename src/main/java/com/snackgame/server/applegame/domain/game/{Board.java => AppleGameBoard.java} (91%) rename src/main/java/com/snackgame/server/applegame/domain/game/{BoardConverter.java => AppleGameBoardConverter.java} (71%) rename src/test/java/com/snackgame/server/applegame/domain/game/{BoardConverterTest.java => AppleGameBoardConverterTest.java} (70%) rename src/test/java/com/snackgame/server/applegame/domain/game/{BoardTest.java => AppleGameBoardTest.java} (91%) diff --git a/src/main/java/com/snackgame/server/applegame/domain/game/AppleGame.java b/src/main/java/com/snackgame/server/applegame/domain/game/AppleGame.java index 914e66b4..cd49cdab 100644 --- a/src/main/java/com/snackgame/server/applegame/domain/game/AppleGame.java +++ b/src/main/java/com/snackgame/server/applegame/domain/game/AppleGame.java @@ -6,6 +6,7 @@ import java.time.LocalDateTime; import java.util.List; +import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; @@ -37,36 +38,37 @@ public class AppleGame extends BaseEntity { private Long sessionId; private Long ownerId; @Lob - private Board board; + @Convert(converter = AppleGameBoardConverter.class) + private AppleGameBoard appleGameBoard; private int score = 0; private LocalDateTime finishedAt; - public AppleGame(Board board, Long ownerId) { - this.board = board; + public AppleGame(AppleGameBoard appleGameBoard, Long ownerId) { + this.appleGameBoard = appleGameBoard; this.ownerId = ownerId; this.finishedAt = willFinishAt(); } - public AppleGame(Board board, Long ownerId, LocalDateTime finishedAt) { - this.board = board; + public AppleGame(AppleGameBoard appleGameBoard, Long ownerId, LocalDateTime finishedAt) { + this.appleGameBoard = appleGameBoard; this.ownerId = ownerId; this.finishedAt = finishedAt; } - public AppleGame(Board board, Long ownerId, LocalDateTime finishedAt, int score) { - this.board = board; + public AppleGame(AppleGameBoard appleGameBoard, Long ownerId, LocalDateTime finishedAt, int score) { + this.appleGameBoard = appleGameBoard; this.ownerId = ownerId; this.finishedAt = finishedAt; this.score = score; } public static AppleGame ofRandomized(Long ownerId) { - return new AppleGame(new Board(DEFAULT_HEIGHT, DEFAULT_WIDTH), ownerId); + return new AppleGame(new AppleGameBoard(DEFAULT_HEIGHT, DEFAULT_WIDTH), ownerId); } public void restart() { validateOngoing(); - this.board = board.reset(); + this.appleGameBoard = appleGameBoard.reset(); this.score = 0; this.createdAt = now(); this.finishedAt = willFinishAt(); @@ -74,9 +76,9 @@ public void restart() { public void removeApplesIn(Range range) { validateOngoing(); - List removed = board.removeApplesIn(range); + List removed = appleGameBoard.removeApplesIn(range); if (removed.stream().anyMatch(Apple::isGolden)) { - board = board.reset(); + appleGameBoard = appleGameBoard.reset(); } score += removed.size(); } @@ -102,7 +104,7 @@ private LocalDateTime willFinishAt() { } public List> getApples() { - return board.getApples(); + return appleGameBoard.getApples(); } public void increase(int amount) { diff --git a/src/main/java/com/snackgame/server/applegame/domain/game/Board.java b/src/main/java/com/snackgame/server/applegame/domain/game/AppleGameBoard.java similarity index 91% rename from src/main/java/com/snackgame/server/applegame/domain/game/Board.java rename to src/main/java/com/snackgame/server/applegame/domain/game/AppleGameBoard.java index 84a2ad8f..359a687e 100644 --- a/src/main/java/com/snackgame/server/applegame/domain/game/Board.java +++ b/src/main/java/com/snackgame/server/applegame/domain/game/AppleGameBoard.java @@ -16,20 +16,20 @@ import lombok.NoArgsConstructor; @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Board { +public class AppleGameBoard { private static final int REMOVABLE_SUM = 10; private List> apples; - public Board(List> apples) { + public AppleGameBoard(List> apples) { validateSquared(apples); this.apples = apples.stream() .map(ArrayList::new) .collect(Collectors.toList()); } - public Board(int height, int width) { + public AppleGameBoard(int height, int width) { this(ApplesFactory.createRandomized(height, width)); } @@ -39,8 +39,8 @@ private void validateSquared(List> apples) { } } - public Board reset() { - return new Board(this.getHeight(), this.getWidth()); + public AppleGameBoard reset() { + return new AppleGameBoard(this.getHeight(), this.getWidth()); } protected List removeApplesIn(Range range) { diff --git a/src/main/java/com/snackgame/server/applegame/domain/game/BoardConverter.java b/src/main/java/com/snackgame/server/applegame/domain/game/AppleGameBoardConverter.java similarity index 71% rename from src/main/java/com/snackgame/server/applegame/domain/game/BoardConverter.java rename to src/main/java/com/snackgame/server/applegame/domain/game/AppleGameBoardConverter.java index 063cf5a5..6c4e2f56 100644 --- a/src/main/java/com/snackgame/server/applegame/domain/game/BoardConverter.java +++ b/src/main/java/com/snackgame/server/applegame/domain/game/AppleGameBoardConverter.java @@ -9,7 +9,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; @Converter(autoApply = true) -public class BoardConverter implements AttributeConverter { +public class AppleGameBoardConverter implements AttributeConverter { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); @@ -19,18 +19,18 @@ public class BoardConverter implements AttributeConverter { } @Override - public String convertToDatabaseColumn(Board board) { + public String convertToDatabaseColumn(AppleGameBoard appleGameBoard) { try { - return OBJECT_MAPPER.writeValueAsString(board); + return OBJECT_MAPPER.writeValueAsString(appleGameBoard); } catch (JsonProcessingException e) { throw new RuntimeException(e); } } @Override - public Board convertToEntityAttribute(String dbJson) { + public AppleGameBoard convertToEntityAttribute(String dbJson) { try { - return OBJECT_MAPPER.readValue(dbJson, Board.class); + return OBJECT_MAPPER.readValue(dbJson, AppleGameBoard.class); } catch (JsonProcessingException e) { throw new RuntimeException(e); } diff --git a/src/main/java/com/snackgame/server/applegame/service/AppleGameService.java b/src/main/java/com/snackgame/server/applegame/service/AppleGameService.java index a4ba797b..bee60c56 100644 --- a/src/main/java/com/snackgame/server/applegame/service/AppleGameService.java +++ b/src/main/java/com/snackgame/server/applegame/service/AppleGameService.java @@ -10,8 +10,8 @@ import com.snackgame.server.applegame.controller.dto.GameResultResponse; import com.snackgame.server.applegame.controller.dto.RangeRequest; import com.snackgame.server.applegame.domain.game.AppleGame; +import com.snackgame.server.applegame.domain.game.AppleGameBoard; import com.snackgame.server.applegame.domain.game.AppleGames; -import com.snackgame.server.applegame.domain.game.Board; import com.snackgame.server.game.metadata.Metadata; import com.snackgame.server.game.session.event.SessionEndEvent; @@ -32,11 +32,11 @@ public AppleGame startGameFor(Long memberId) { public Optional placeMoves(Long memberId, Long sessionId, List rangeRequests) { AppleGame game = appleGames.getBy(memberId, sessionId); - Board previous = game.getBoard(); + AppleGameBoard previous = game.getAppleGameBoard(); rangeRequests.forEach(request -> game.removeApplesIn(request.toRange())); - if (!game.getBoard().equals(previous)) { + if (!game.getAppleGameBoard().equals(previous)) { return Optional.of(game); } return Optional.empty(); diff --git a/src/main/java/com/snackgame/server/game/snackgame/controller/SnackgameController.kt b/src/main/java/com/snackgame/server/game/snackgame/controller/SnackgameController.kt index 3bd0e4f0..ea48c6c6 100644 --- a/src/main/java/com/snackgame/server/game/snackgame/controller/SnackgameController.kt +++ b/src/main/java/com/snackgame/server/game/snackgame/controller/SnackgameController.kt @@ -62,7 +62,7 @@ class SnackgameController( fun placeMoves( @Authenticated member: Member, @PathVariable sessionId: Long, - @RequestBody @Valid requests: List + @RequestBody requests: List ): ResponseEntity = snackgameService.placeMoves(member.id, sessionId, requests) .map { game -> ResponseEntity diff --git a/src/main/java/com/snackgame/server/game/snackgame/domain/Board.kt b/src/main/java/com/snackgame/server/game/snackgame/domain/Board.kt index 6721ac08..27399c39 100644 --- a/src/main/java/com/snackgame/server/game/snackgame/domain/Board.kt +++ b/src/main/java/com/snackgame/server/game/snackgame/domain/Board.kt @@ -7,6 +7,7 @@ import com.snackgame.server.game.snackgame.snack.EmptySnack import com.snackgame.server.game.snackgame.snack.Snack import java.util.stream.Collectors + class Board() { private var snacks: MutableList> = arrayListOf() diff --git a/src/main/java/com/snackgame/server/game/snackgame/domain/BoardConverter.kt b/src/main/java/com/snackgame/server/game/snackgame/domain/BoardConverter.kt index 8e37ee06..5796ccaf 100644 --- a/src/main/java/com/snackgame/server/game/snackgame/domain/BoardConverter.kt +++ b/src/main/java/com/snackgame/server/game/snackgame/domain/BoardConverter.kt @@ -5,9 +5,8 @@ import com.fasterxml.jackson.annotation.PropertyAccessor import com.fasterxml.jackson.core.JsonProcessingException import com.fasterxml.jackson.databind.ObjectMapper import javax.persistence.AttributeConverter -import javax.persistence.Converter -@Converter(autoApply = true) + class BoardConverter : AttributeConverter { override fun convertToDatabaseColumn(board: Board): String { diff --git a/src/main/java/com/snackgame/server/game/snackgame/domain/Snackgame.kt b/src/main/java/com/snackgame/server/game/snackgame/domain/Snackgame.kt index 2b6638d1..d6c09199 100644 --- a/src/main/java/com/snackgame/server/game/snackgame/domain/Snackgame.kt +++ b/src/main/java/com/snackgame/server/game/snackgame/domain/Snackgame.kt @@ -5,6 +5,7 @@ import com.snackgame.server.game.metadata.Metadata.SNACK_GAME import com.snackgame.server.game.session.domain.Session import com.snackgame.server.game.snackgame.snack.Snack import java.time.Duration +import javax.persistence.Convert import javax.persistence.Entity import javax.persistence.Lob @@ -12,6 +13,7 @@ import javax.persistence.Lob class Snackgame( ownerId: Long, @Lob + @Convert(converter = BoardConverter::class) val board: Board, timeLimit: Duration = SESSION_TIME + SPARE_TIME, score: Int = 0 diff --git a/src/main/java/com/snackgame/server/game/snackgame/service/dto/SnackgameResponse.kt b/src/main/java/com/snackgame/server/game/snackgame/service/dto/SnackgameResponse.kt index db6f0782..06bd09fe 100644 --- a/src/main/java/com/snackgame/server/game/snackgame/service/dto/SnackgameResponse.kt +++ b/src/main/java/com/snackgame/server/game/snackgame/service/dto/SnackgameResponse.kt @@ -4,8 +4,9 @@ import com.snackgame.server.game.session.domain.Session import com.snackgame.server.game.session.service.dto.SessionResponse import com.snackgame.server.game.snackgame.domain.Snackgame -class SnackgameResponse( - session: Session, + +data class SnackgameResponse( + val session: Session, val board: List> ) : SessionResponse(session) { diff --git a/src/test/java/com/snackgame/server/applegame/domain/game/BoardConverterTest.java b/src/test/java/com/snackgame/server/applegame/domain/game/AppleGameBoardConverterTest.java similarity index 70% rename from src/test/java/com/snackgame/server/applegame/domain/game/BoardConverterTest.java rename to src/test/java/com/snackgame/server/applegame/domain/game/AppleGameBoardConverterTest.java index 9079b90d..d98fc571 100644 --- a/src/test/java/com/snackgame/server/applegame/domain/game/BoardConverterTest.java +++ b/src/test/java/com/snackgame/server/applegame/domain/game/AppleGameBoardConverterTest.java @@ -10,31 +10,31 @@ @SuppressWarnings("NonAsciiCharacters") @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -class BoardConverterTest { +class AppleGameBoardConverterTest { - private final BoardConverter converter = new BoardConverter(); + private final AppleGameBoardConverter converter = new AppleGameBoardConverter(); @Test void 게임판을_JSON으로_변환한다() { - Board board = TestFixture.TWO_BY_FOUR(); + AppleGameBoard appleGameBoard = TestFixture.TWO_BY_FOUR(); - String serialized = converter.convertToDatabaseColumn(board); + String serialized = converter.convertToDatabaseColumn(appleGameBoard); assertThat(serialized).isEqualTo(TestFixture.TWO_BY_FOUR_AS_JSON); } @Test void 황금사과를_포함한_게임판을_JSON으로_변환한다() { - Board board = TestFixture.TWO_BY_TWO_WITH_GOLDEN_APPLE(); + AppleGameBoard appleGameBoard = TestFixture.TWO_BY_TWO_WITH_GOLDEN_APPLE(); - String serialized = converter.convertToDatabaseColumn(board); + String serialized = converter.convertToDatabaseColumn(appleGameBoard); assertThat(serialized).isEqualTo(TestFixture.TWO_BY_TWO_WITH_GOLDEN_APPLE_AS_JSON); } @Test void JSON_게임판을_사과객체들로_변환한다() { - Board expected = TestFixture.TWO_BY_FOUR(); + AppleGameBoard expected = TestFixture.TWO_BY_FOUR(); var deserialized = converter.convertToEntityAttribute(TestFixture.TWO_BY_FOUR_AS_JSON); @@ -45,7 +45,7 @@ class BoardConverterTest { @Test void 황금사과를_포함한_게임판을_역직렬화한다() { - Board expected = TestFixture.TWO_BY_TWO_WITH_GOLDEN_APPLE(); + AppleGameBoard expected = TestFixture.TWO_BY_TWO_WITH_GOLDEN_APPLE(); var deserialized = converter.convertToEntityAttribute(TestFixture.TWO_BY_TWO_WITH_GOLDEN_APPLE_AS_JSON); diff --git a/src/test/java/com/snackgame/server/applegame/domain/game/BoardTest.java b/src/test/java/com/snackgame/server/applegame/domain/game/AppleGameBoardTest.java similarity index 91% rename from src/test/java/com/snackgame/server/applegame/domain/game/BoardTest.java rename to src/test/java/com/snackgame/server/applegame/domain/game/AppleGameBoardTest.java index 097d909c..772f5110 100644 --- a/src/test/java/com/snackgame/server/applegame/domain/game/BoardTest.java +++ b/src/test/java/com/snackgame/server/applegame/domain/game/AppleGameBoardTest.java @@ -20,14 +20,14 @@ @SuppressWarnings("NonAsciiCharacters") @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -class BoardTest { +class AppleGameBoardTest { @Test void 게임판_높이는_1이상이어야_한다() { int height = 0; int width = 8; - assertThatThrownBy(() -> new Board(height, width)) + assertThatThrownBy(() -> new AppleGameBoard(height, width)) .isInstanceOf(InvalidBoardSizeException.class) .hasMessage("잘못된 크기의 게임판입니다"); } @@ -37,7 +37,7 @@ class BoardTest { int height = 1; int width = 0; - assertThatThrownBy(() -> new Board(height, width)) + assertThatThrownBy(() -> new AppleGameBoard(height, width)) .isInstanceOf(InvalidBoardSizeException.class) .hasMessage("잘못된 크기의 게임판입니다"); } @@ -47,7 +47,7 @@ class BoardTest { int height = 4; int width = 8; - var board = new Board(height, width); + var board = new AppleGameBoard(height, width); assertThat(board.getApples()).hasSize(height); assertThat(board.getApples()).allSatisfy( @@ -59,7 +59,7 @@ class BoardTest { void 게임판을_초기화해도_같은_크기를_가진다() { int height = 4; int width = 8; - var board = new Board(height, width); + var board = new AppleGameBoard(height, width); var reset = board.reset(); @@ -73,7 +73,7 @@ class BoardTest { void 게임판을_초기화하면_사과들이_바뀐다() { int height = 4; int width = 8; - var board = new Board(height, width); + var board = new AppleGameBoard(height, width); var reset = board.reset(); @@ -132,7 +132,7 @@ class BoardTest { @Test void 하나를_황금사과로_만든다() { - var board = new Board(10, 8); + var board = new AppleGameBoard(10, 8); long goldenAppleCount = board.getApples().stream() .flatMap(Collection::stream) diff --git a/src/test/java/com/snackgame/server/applegame/domain/game/AppleGameTest.java b/src/test/java/com/snackgame/server/applegame/domain/game/AppleGameTest.java index 6f9ed133..9b4f0a49 100644 --- a/src/test/java/com/snackgame/server/applegame/domain/game/AppleGameTest.java +++ b/src/test/java/com/snackgame/server/applegame/domain/game/AppleGameTest.java @@ -47,12 +47,12 @@ class AppleGameTest { new Coordinate(1, 3) ); game.removeApplesIn(range); - var previousBoard = game.getBoard(); + var previousBoard = game.getAppleGameBoard(); var previousCreatedAt = game.getCreatedAt(); game.restart(); - assertThat(game.getBoard()).isNotEqualTo(previousBoard); + assertThat(game.getAppleGameBoard()).isNotEqualTo(previousBoard); assertThat(game.getScore()).isZero(); assertThat(game.getCreatedAt()).isAfter(previousCreatedAt); } diff --git a/src/test/java/com/snackgame/server/applegame/fixture/TestFixture.java b/src/test/java/com/snackgame/server/applegame/fixture/TestFixture.java index 36d0f8ad..9f75c660 100644 --- a/src/test/java/com/snackgame/server/applegame/fixture/TestFixture.java +++ b/src/test/java/com/snackgame/server/applegame/fixture/TestFixture.java @@ -4,7 +4,7 @@ import com.snackgame.server.applegame.domain.apple.EmptyApple; import com.snackgame.server.applegame.domain.apple.PlainApple; -import com.snackgame.server.applegame.domain.game.Board; +import com.snackgame.server.applegame.domain.game.AppleGameBoard; public class TestFixture { @@ -15,8 +15,8 @@ public class TestFixture { *

[1, 1, _, 5]

*

[9, 2, _, 2]

*/ - public static Board TWO_BY_FOUR() { - return new Board(List.of( + public static AppleGameBoard TWO_BY_FOUR() { + return new AppleGameBoard(List.of( List.of(PlainApple.of(1), PlainApple.of(1), EmptyApple.get(), PlainApple.of(5)), List.of(PlainApple.of(9), PlainApple.of(2), EmptyApple.get(), PlainApple.of(2)) )); @@ -27,8 +27,8 @@ public static Board TWO_BY_FOUR() { *

[9, 2]

* 9는 황금사과이다. */ - public static Board TWO_BY_TWO_WITH_GOLDEN_APPLE() { - return new Board(List.of( + public static AppleGameBoard TWO_BY_TWO_WITH_GOLDEN_APPLE() { + return new AppleGameBoard(List.of( List.of(PlainApple.of(1), PlainApple.of(8)), List.of(PlainApple.of(9).golden(), PlainApple.of(2)) )); diff --git a/src/test/java/com/snackgame/server/applegame/service/AppleGameServiceTest.java b/src/test/java/com/snackgame/server/applegame/service/AppleGameServiceTest.java index ef19c156..8055eaf8 100644 --- a/src/test/java/com/snackgame/server/applegame/service/AppleGameServiceTest.java +++ b/src/test/java/com/snackgame/server/applegame/service/AppleGameServiceTest.java @@ -101,9 +101,9 @@ void setUp() { AppleGame current = appleGames.getBy(땡칠().getId(), previous.getSessionId()); assertThat(current.getCreatedAt()).isAfter(previous.getCreatedAt()); - assertThat(current.getBoard()) + assertThat(current.getAppleGameBoard()) .usingRecursiveComparison() - .isNotEqualTo(previous.getBoard()); + .isNotEqualTo(previous.getAppleGameBoard()); } @Test diff --git a/src/test/java/com/snackgame/server/game/snackgame/service/SnackgameServiceTest.kt b/src/test/java/com/snackgame/server/game/snackgame/service/SnackgameServiceTest.kt index 6b1060b2..e87086b0 100644 --- a/src/test/java/com/snackgame/server/game/snackgame/service/SnackgameServiceTest.kt +++ b/src/test/java/com/snackgame/server/game/snackgame/service/SnackgameServiceTest.kt @@ -1,4 +1,45 @@ package com.snackgame.server.game.snackgame.service +import com.snackgame.server.fixture.SeasonFixture +import com.snackgame.server.game.snackgame.domain.Snackgame +import com.snackgame.server.game.snackgame.domain.SnackgameRepository +import com.snackgame.server.game.snackgame.fixture.TestFixture +import com.snackgame.server.game.snackgame.service.dto.StreakRequest +import com.snackgame.server.member.fixture.MemberFixture +import com.snackgame.server.member.fixture.MemberFixture.땡칠 +import com.snackgame.server.support.general.ServiceTest +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired + +@ServiceTest class SnackgameServiceTest { + + @Autowired + private lateinit var snackgameService: SnackgameService + + @Autowired + private lateinit var snackgameRepository: SnackgameRepository + + @BeforeEach + fun setUp() { + MemberFixture.saveAll() + SeasonFixture.saveAll() + } + + @Test + fun `게임을 조작한다`() { + var game = snackgameRepository.save(Snackgame(땡칠().id, TestFixture.TWO_BY_FOUR())) + + var streakRequests = listOf( + StreakRequest(1, 0), + StreakRequest(0, 0) + ) + + snackgameService.placeMoves(땡칠().id, game.sessionId, streakRequests) + + var found = snackgameRepository.findByOwnerIdAndSessionId(땡칠().id, game.sessionId) + assertThat(found?.score).isEqualTo(2) + } } \ No newline at end of file