From 5a967de528f99f0cf335e22341361c4d234f5b3f Mon Sep 17 00:00:00 2001 From: TAEW00KIM Date: Fri, 13 Feb 2026 22:11:44 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[FIX]=20=EA=B2=8C=EC=9E=84=20=EC=A7=81?= =?UTF-8?q?=EC=A0=91=20=EC=A2=85=EB=A3=8C=20=EC=8B=9C=20=EA=B2=B0=EA=B3=BC?= =?UTF-8?q?=20=EC=A0=80=EC=9E=A5=20=EB=88=84=EB=9D=BD=20=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../command/game/application/GameService.java | 17 ++++++++++++-- .../game/application/GameServiceTest.java | 23 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sports/server/command/game/application/GameService.java b/src/main/java/com/sports/server/command/game/application/GameService.java index 11a407fd..e55069ae 100644 --- a/src/main/java/com/sports/server/command/game/application/GameService.java +++ b/src/main/java/com/sports/server/command/game/application/GameService.java @@ -75,12 +75,25 @@ public void updateGame(Long leagueId, Long gameId, GameRequest.Update request, M league.validateRoundWithinLimit(request.round()); Game game = entityUtils.getEntity(gameId, Game.class); + GameState state = GameState.from(request.state()); + game.updateName(request.name()); game.updateStartTime(request.startTime()); game.updateVideoId(request.videoId()); game.updateGameQuarter(request.quarter()); - game.updateState(GameState.from(request.state())); + game.updateState(state); game.updateRound(Round.from(request.round())); + updateResultIfFinished(game, state); + } + + private void updateResultIfFinished(Game game, GameState state) { + if (!GameState.FINISHED.equals(state)) { + return; + } + if (game.getGameTeams().size() != Game.MINIMUM_TEAMS) { + return; + } + game.determineResult(); } @Transactional @@ -182,4 +195,4 @@ private void validateGameTeamsInLeague(League league, GameRequest.TeamLineupRequ } } -} \ No newline at end of file +} diff --git a/src/test/java/com/sports/server/command/game/application/GameServiceTest.java b/src/test/java/com/sports/server/command/game/application/GameServiceTest.java index d5b2729b..663f8037 100644 --- a/src/test/java/com/sports/server/command/game/application/GameServiceTest.java +++ b/src/test/java/com/sports/server/command/game/application/GameServiceTest.java @@ -6,6 +6,7 @@ import static org.mockito.Mockito.when; import com.sports.server.command.game.domain.Game; +import com.sports.server.command.game.domain.GameResult; import com.sports.server.command.game.domain.GameState; import com.sports.server.command.game.domain.GameTeam; import com.sports.server.command.game.domain.LineupPlayerState; @@ -206,6 +207,28 @@ void setUp() { () -> assertThat(game.getVideoId()).isEqualTo(updateDto.videoId())); } + @Test + void 게임을_직접_종료하면_결과가_저장된다() { + // given + GameRequest.Update finishRequest = new GameRequest.Update( + nameOfGame, 4, "경기후", "FINISHED", LocalDateTime.of(2024, 9, 11, 12, 0, 0), "videoId" + ); + + // when + gameService.updateGame(leagueId, gameId, finishRequest, manager); + + // then + Game game = entityUtils.getEntity(gameId, Game.class); + GameTeam firstGameTeam = entityUtils.getEntity(1L, GameTeam.class); + GameTeam secondGameTeam = entityUtils.getEntity(2L, GameTeam.class); + + assertAll( + () -> assertThat(game.getState()).isEqualTo(GameState.FINISHED), + () -> assertThat(firstGameTeam.getResult()).isEqualTo(GameResult.LOSE), + () -> assertThat(secondGameTeam.getResult()).isEqualTo(GameResult.WIN) + ); + } + @Test void 게임이_속한_리그의_매니저가_아닌_회원이_게임을_수정하려고_하면_예외가_발생한다() { // given From b859721b378a7d22abfb95aef1348c885cc05569 Mon Sep 17 00:00:00 2001 From: TAEW00KIM Date: Fri, 13 Feb 2026 23:51:40 +0900 Subject: [PATCH 2/4] =?UTF-8?q?test:=20FixtureMonkey=20Game=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=EB=AA=85=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20CI=20flaky=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EC=95=88=EC=A0=95=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gradle-8.2.1-bin.zip.lck | 0 .../gradle-8.2.1-bin.zip.part | 0 build.gradle | 1 + src/main/resources/.DS_Store | Bin 0 -> 6148 bytes src/main/resources/static/docs/api.html | 4 ++-- .../server/command/game/domain/GameTest.java | 4 ++-- .../domain/GameProgressTimelineTest.java | 6 +++--- 7 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 .gradle-user-home/wrapper/dists/gradle-8.2.1-bin/5hap6b9n41hkg4jeh2au2pllh/gradle-8.2.1-bin.zip.lck create mode 100644 .gradle-user-home/wrapper/dists/gradle-8.2.1-bin/5hap6b9n41hkg4jeh2au2pllh/gradle-8.2.1-bin.zip.part create mode 100644 src/main/resources/.DS_Store diff --git a/.gradle-user-home/wrapper/dists/gradle-8.2.1-bin/5hap6b9n41hkg4jeh2au2pllh/gradle-8.2.1-bin.zip.lck b/.gradle-user-home/wrapper/dists/gradle-8.2.1-bin/5hap6b9n41hkg4jeh2au2pllh/gradle-8.2.1-bin.zip.lck new file mode 100644 index 00000000..e69de29b diff --git a/.gradle-user-home/wrapper/dists/gradle-8.2.1-bin/5hap6b9n41hkg4jeh2au2pllh/gradle-8.2.1-bin.zip.part b/.gradle-user-home/wrapper/dists/gradle-8.2.1-bin/5hap6b9n41hkg4jeh2au2pllh/gradle-8.2.1-bin.zip.part new file mode 100644 index 00000000..e69de29b diff --git a/build.gradle b/build.gradle index 91d80092..0348e123 100644 --- a/build.gradle +++ b/build.gradle @@ -89,6 +89,7 @@ ext { test { outputs.dir snippetsDir useJUnitPlatform() + jvmArgs '-Dnet.bytebuddy.experimental=true' testLogging { events "failed" // 실패한 테스트만 로그 출력 exceptionFormat "full" // Expected vs Actual 포함 diff --git a/src/main/resources/.DS_Store b/src/main/resources/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..66544f017c880eea9e05fd2d544a58a0a328c19d GIT binary patch literal 6148 zcmeHKOKQU~5S>X)F?8c)m%2i3AWV9KT%aX^PzWxxN!DKVTsd0ad^X1I&e?=FFnZEx zo`l}Q;}H?<&-=AVCn7D}P=0Ngo9&y=Y?ToO!g0o@>@M5y;rKNiX4!uSjQcD4-ZW$e#hzg+>MLt-uXFauu5Z literal 0 HcmV?d00001 diff --git a/src/main/resources/static/docs/api.html b/src/main/resources/static/docs/api.html index df705526..73fba1a1 100644 --- a/src/main/resources/static/docs/api.html +++ b/src/main/resources/static/docs/api.html @@ -6429,7 +6429,7 @@

diff --git a/src/test/java/com/sports/server/command/game/domain/GameTest.java b/src/test/java/com/sports/server/command/game/domain/GameTest.java index ee6a7c02..6a501212 100644 --- a/src/test/java/com/sports/server/command/game/domain/GameTest.java +++ b/src/test/java/com/sports/server/command/game/domain/GameTest.java @@ -22,12 +22,12 @@ class GameTest { public void setUp() { game = entityBuilder(Game.class) .set("id", 1L) - .set("teams", new ArrayList<>()) + .set("gameTeams", new ArrayList<>()) .sample(); game2 = entityBuilder(Game.class) .set("id", 2L) - .set("teams", new ArrayList<>()) + .set("gameTeams", new ArrayList<>()) .sample(); team1 = entityBuilder(GameTeam.class) diff --git a/src/test/java/com/sports/server/command/timeline/domain/GameProgressTimelineTest.java b/src/test/java/com/sports/server/command/timeline/domain/GameProgressTimelineTest.java index 039cce29..22bfbb35 100644 --- a/src/test/java/com/sports/server/command/timeline/domain/GameProgressTimelineTest.java +++ b/src/test/java/com/sports/server/command/timeline/domain/GameProgressTimelineTest.java @@ -19,10 +19,10 @@ class GameProgressTimelineTest { @BeforeEach void setUp() { game = entityBuilder(Game.class) - .set("teams", new ArrayList<>()) + .set("gameTeams", new ArrayList<>()) .set("gameQuarter", Quarter.PRE_GAME.getName()) .set("state", GameState.SCHEDULED) - .set("is_pk_taken", false) + .set("isPkTaken", false) .sample(); } @@ -290,4 +290,4 @@ class RollbackTest { GameProgressType.GAME_END ); } -} \ No newline at end of file +} From 16b8b8bb811054291181d1973610f80580dbe708 Mon Sep 17 00:00:00 2001 From: TAEW00KIM Date: Thu, 26 Feb 2026 18:32:35 +0900 Subject: [PATCH 3/4] chore: remove accidental artifacts from game fix branch --- .gitignore | 4 ++++ .../gradle-8.2.1-bin.zip.lck | 0 .../gradle-8.2.1-bin.zip.part | 0 src/main/resources/.DS_Store | Bin 6148 -> 0 bytes src/main/resources/static/docs/api.html | 4 ++-- 5 files changed, 6 insertions(+), 2 deletions(-) delete mode 100644 .gradle-user-home/wrapper/dists/gradle-8.2.1-bin/5hap6b9n41hkg4jeh2au2pllh/gradle-8.2.1-bin.zip.lck delete mode 100644 .gradle-user-home/wrapper/dists/gradle-8.2.1-bin/5hap6b9n41hkg4jeh2au2pllh/gradle-8.2.1-bin.zip.part delete mode 100644 src/main/resources/.DS_Store diff --git a/.gitignore b/.gitignore index f49efccd..a19e2a87 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,7 @@ out/ ## fixture monkey .jqwik-database .mcp.json + +## local artifacts +/.gradle-user-home/ +.DS_Store diff --git a/.gradle-user-home/wrapper/dists/gradle-8.2.1-bin/5hap6b9n41hkg4jeh2au2pllh/gradle-8.2.1-bin.zip.lck b/.gradle-user-home/wrapper/dists/gradle-8.2.1-bin/5hap6b9n41hkg4jeh2au2pllh/gradle-8.2.1-bin.zip.lck deleted file mode 100644 index e69de29b..00000000 diff --git a/.gradle-user-home/wrapper/dists/gradle-8.2.1-bin/5hap6b9n41hkg4jeh2au2pllh/gradle-8.2.1-bin.zip.part b/.gradle-user-home/wrapper/dists/gradle-8.2.1-bin/5hap6b9n41hkg4jeh2au2pllh/gradle-8.2.1-bin.zip.part deleted file mode 100644 index e69de29b..00000000 diff --git a/src/main/resources/.DS_Store b/src/main/resources/.DS_Store deleted file mode 100644 index 66544f017c880eea9e05fd2d544a58a0a328c19d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKOKQU~5S>X)F?8c)m%2i3AWV9KT%aX^PzWxxN!DKVTsd0ad^X1I&e?=FFnZEx zo`l}Q;}H?<&-=AVCn7D}P=0Ngo9&y=Y?ToO!g0o@>@M5y;rKNiX4!uSjQcD4-ZW$e#hzg+>MLt-uXFauu5Z diff --git a/src/main/resources/static/docs/api.html b/src/main/resources/static/docs/api.html index 73fba1a1..df705526 100644 --- a/src/main/resources/static/docs/api.html +++ b/src/main/resources/static/docs/api.html @@ -6429,7 +6429,7 @@

From 5cbf576bfe6b31733fa1880a22356c95351f1c60 Mon Sep 17 00:00:00 2001 From: TAEW00KIM Date: Thu, 26 Feb 2026 23:00:42 +0900 Subject: [PATCH 4/4] refactor: move game result update decision into Game domain --- .../command/game/application/GameService.java | 12 +---- .../server/command/game/domain/Game.java | 10 ++++ .../server/command/game/domain/GameTest.java | 53 +++++++++++++++++++ 3 files changed, 64 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/sports/server/command/game/application/GameService.java b/src/main/java/com/sports/server/command/game/application/GameService.java index e55069ae..745bf978 100644 --- a/src/main/java/com/sports/server/command/game/application/GameService.java +++ b/src/main/java/com/sports/server/command/game/application/GameService.java @@ -83,17 +83,7 @@ public void updateGame(Long leagueId, Long gameId, GameRequest.Update request, M game.updateGameQuarter(request.quarter()); game.updateState(state); game.updateRound(Round.from(request.round())); - updateResultIfFinished(game, state); - } - - private void updateResultIfFinished(Game game, GameState state) { - if (!GameState.FINISHED.equals(state)) { - return; - } - if (game.getGameTeams().size() != Game.MINIMUM_TEAMS) { - return; - } - game.determineResult(); + game.updateResult(); } @Transactional diff --git a/src/main/java/com/sports/server/command/game/domain/Game.java b/src/main/java/com/sports/server/command/game/domain/Game.java index 79c2274b..1251cb2b 100644 --- a/src/main/java/com/sports/server/command/game/domain/Game.java +++ b/src/main/java/com/sports/server/command/game/domain/Game.java @@ -240,6 +240,16 @@ public void determineResult() { markAsDraw(team1, team2); } + public void updateResult() { + if (!GameState.FINISHED.equals(this.state)) { + return; + } + if (gameTeams.size() != MINIMUM_TEAMS) { + return; + } + determineResult(); + } + private static void markAsDraw(GameTeam team1, GameTeam team2) { team1.markAsDraw(); team2.markAsDraw(); diff --git a/src/test/java/com/sports/server/command/game/domain/GameTest.java b/src/test/java/com/sports/server/command/game/domain/GameTest.java index 6a501212..b06d32df 100644 --- a/src/test/java/com/sports/server/command/game/domain/GameTest.java +++ b/src/test/java/com/sports/server/command/game/domain/GameTest.java @@ -259,6 +259,59 @@ void setUp() { } } + @Nested + @DisplayName("결과를 갱신할 때") + class UpdateResultTest { + + @Test + void 종료된_경기에서만_결과를_계산한다() { + // given + team1.score(); + game.updateState(GameState.PLAYING); + GameResult initialTeam1Result = team1.getResult(); + GameResult initialTeam2Result = team2.getResult(); + + // when + game.updateResult(); + + // then + assertAll( + () -> assertThat(team1.getResult()).isEqualTo(initialTeam1Result), + () -> assertThat(team2.getResult()).isEqualTo(initialTeam2Result) + ); + + // when + game.updateState(GameState.FINISHED); + game.updateResult(); + + // then + assertAll( + () -> assertThat(team1.getResult()).isEqualTo(GameResult.WIN), + () -> assertThat(team2.getResult()).isEqualTo(GameResult.LOSE) + ); + } + + @Test + void 참가팀이_2팀이_아니면_결과를_계산하지_않는다() { + // given + GameTeam singleTeam = entityBuilder(GameTeam.class) + .set("id", 999L) + .set("game", game2) + .set("score", 1) + .set("pkScore", 0) + .sample(); + game2.addGameTeam(singleTeam); + game2.updateState(GameState.FINISHED); + GameResult initialResult = singleTeam.getResult(); + + // when + game2.updateResult(); + + // then + assertThat(singleTeam.getResult()).isEqualTo(initialResult); + } + } + @Test void 주장_상태를_변경할_때_게임에_속하지_않는_게임팀에_대한_요청인_경우_예외를_던진다() { // given