diff --git a/src/integrationTest/java/com/naminhyeok/fantazzk/LiquibasePostgresSmokeTest.java b/src/integrationTest/java/com/naminhyeok/fantazzk/LiquibasePostgresSmokeTest.java index 6a203280..2b0133c3 100644 --- a/src/integrationTest/java/com/naminhyeok/fantazzk/LiquibasePostgresSmokeTest.java +++ b/src/integrationTest/java/com/naminhyeok/fantazzk/LiquibasePostgresSmokeTest.java @@ -32,11 +32,17 @@ class LiquibasePostgresSmokeTest { @Test void liquibase_실제_postgresql_스키마에서_rooms_변경을_검증한다() { assertThat(countTable("rooms")).isEqualTo(1); + assertThat(countColumn("template", "game_type")).isEqualTo(1); + assertThat(isNullable("template", "game_type")).isTrue(); + assertThat(countColumn("template", "position_limit")).isZero(); + assertThat(countColumn("template_player", "position")).isEqualTo(1); + assertThat(isNullable("template_player", "position")).isTrue(); assertThat(countColumn("rooms", "created_at")).isEqualTo(1); + assertThat(countColumn("rooms", "game_type")).isEqualTo(1); + assertThat(isNullable("rooms", "game_type")).isTrue(); assertThat(countColumn("rooms", "min_bid_unit")).isEqualTo(1); assertThat(isNullable("rooms", "min_bid_unit")).isTrue(); - assertThat(countColumn("rooms", "position_limit")).isEqualTo(1); - assertThat(isNullable("rooms", "position_limit")).isTrue(); + assertThat(countColumn("rooms", "position_limit")).isZero(); assertThat(countColumn("rooms", "started_game_id")).isEqualTo(1); assertThat(countColumn("rooms", "started_at")).isEqualTo(1); assertThat(countColumn("rooms", "current_turn_index")).isZero(); @@ -47,6 +53,11 @@ class LiquibasePostgresSmokeTest { assertThat(countTable("room_team_member")).isZero(); assertThat(countTable("room_bid")).isZero(); assertThat(countTable("game_draft_member")).isEqualTo(1); + assertThat(countColumn("games", "game_type")).isEqualTo(1); + assertThat(isNullable("games", "game_type")).isTrue(); + assertThat(countColumn("games", "position_limit")).isZero(); + assertThat(countColumn("game_player", "position")).isEqualTo(1); + assertThat(isNullable("game_player", "position")).isTrue(); assertThat(countColumn("game_draft_member", "members_game_id")).isEqualTo(1); assertThat(countColumn("game_draft_member", "member_order")).isEqualTo(1); assertThat(countColumn("game_draft_member", "team_leader_id")).isEqualTo(1); diff --git a/src/integrationTest/java/com/naminhyeok/fantazzk/LiquibaseSmokeTest.java b/src/integrationTest/java/com/naminhyeok/fantazzk/LiquibaseSmokeTest.java index 5606628d..3a7ec61b 100644 --- a/src/integrationTest/java/com/naminhyeok/fantazzk/LiquibaseSmokeTest.java +++ b/src/integrationTest/java/com/naminhyeok/fantazzk/LiquibaseSmokeTest.java @@ -34,13 +34,19 @@ class LiquibaseSmokeTest { @Test void liquibase_초기_스키마로_자바_jpa_구조를_검증하며_부팅한다() { assertThat(countTable("template")).isEqualTo(1); + assertThat(countColumn("template", "game_type")).isEqualTo(1); + assertThat(isNullable("template", "game_type")).isTrue(); + assertThat(countColumn("template", "position_limit")).isZero(); assertThat(countTable("template_player")).isEqualTo(1); + assertThat(countColumn("template_player", "position")).isEqualTo(1); + assertThat(isNullable("template_player", "position")).isTrue(); assertThat(countTable("rooms")).isEqualTo(1); assertThat(countColumn("rooms", "created_at")).isEqualTo(1); + assertThat(countColumn("rooms", "game_type")).isEqualTo(1); + assertThat(isNullable("rooms", "game_type")).isTrue(); assertThat(countColumn("rooms", "min_bid_unit")).isEqualTo(1); assertThat(isNullable("rooms", "min_bid_unit")).isTrue(); - assertThat(countColumn("rooms", "position_limit")).isEqualTo(1); - assertThat(isNullable("rooms", "position_limit")).isTrue(); + assertThat(countColumn("rooms", "position_limit")).isZero(); assertThat(countColumn("rooms", "started_game_id")).isEqualTo(1); assertThat(countColumn("rooms", "started_at")).isEqualTo(1); assertThat(countColumn("rooms", "current_turn_index")).isZero(); @@ -57,6 +63,11 @@ class LiquibaseSmokeTest { assertThat(countTable("room_team_member")).isZero(); assertThat(countTable("room_bid")).isZero(); assertThat(countTable("game_draft_member")).isEqualTo(1); + assertThat(countColumn("games", "game_type")).isEqualTo(1); + assertThat(isNullable("games", "game_type")).isTrue(); + assertThat(countColumn("games", "position_limit")).isZero(); + assertThat(countColumn("game_player", "position")).isEqualTo(1); + assertThat(isNullable("game_player", "position")).isTrue(); assertThat(countColumn("game_draft_member", "members_game_id")).isEqualTo(1); assertThat(countColumn("game_draft_member", "member_order")).isEqualTo(1); assertThat(countColumn("game_draft_member", "team_leader_id")).isEqualTo(1); diff --git a/src/integrationTest/java/com/naminhyeok/fantazzk/room/application/CreateRoomRetryIntegrationTest.java b/src/integrationTest/java/com/naminhyeok/fantazzk/room/application/CreateRoomRetryIntegrationTest.java index 52f76642..e23d70ab 100644 --- a/src/integrationTest/java/com/naminhyeok/fantazzk/room/application/CreateRoomRetryIntegrationTest.java +++ b/src/integrationTest/java/com/naminhyeok/fantazzk/room/application/CreateRoomRetryIntegrationTest.java @@ -150,6 +150,7 @@ private Room existingRoom(String code) { "선점호스트", "existing-token", new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, diff --git a/src/integrationTest/java/com/naminhyeok/fantazzk/room/application/RoomAuctionIntegrationTest.java b/src/integrationTest/java/com/naminhyeok/fantazzk/room/application/RoomAuctionIntegrationTest.java index 481d245a..0621f2a4 100644 --- a/src/integrationTest/java/com/naminhyeok/fantazzk/room/application/RoomAuctionIntegrationTest.java +++ b/src/integrationTest/java/com/naminhyeok/fantazzk/room/application/RoomAuctionIntegrationTest.java @@ -3,7 +3,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import com.naminhyeok.fantazzk.CoreException; import com.naminhyeok.fantazzk.room.application.CreateRoom; import com.naminhyeok.fantazzk.room.application.JoinRoom; import com.naminhyeok.fantazzk.room.application.PlaceBid; @@ -154,7 +153,7 @@ void clearScheduledTasks() { } @Test - void 같은_포지션_제한에_걸리는_선수에게는_재조회_후에도_입찰할_수_없다() { + void 같은_포지션이어도_메타데이터일뿐이라_재조회_후에도_입찰할_수_있다() { UUID template = templateFixture.createAuctionTemplateId( "포지션제한경매전", @@ -178,13 +177,9 @@ void clearScheduledTasks() { settleAuctionAttempt.settleIfDue(created.room().getCode()); Room reloaded = rooms.findByCode(created.room().getCode()).orElseThrow(); + AuctionBid secondPositionBid = placeBid.place(reloaded.getStartedGameId().gameId(), guest.getActionToken(), 140); - assertThatThrownBy(() -> placeBid.place(reloaded.getStartedGameId().gameId(), guest.getActionToken(), 160)) - .isInstanceOf(CoreException.class) - .isInstanceOfSatisfying( - CoreException.class, - ex -> assertThat(ex.getError().getCode()).isEqualTo("ROOM_AUCTION_POSITION_LIMIT_EXCEEDED") - ); + assertThat(secondPositionBid.amount()).isEqualTo(140); } @Test diff --git a/src/integrationTest/java/com/naminhyeok/fantazzk/room/infrastructure/persistence/RoomGameCleanupMigrationIntegrationTest.java b/src/integrationTest/java/com/naminhyeok/fantazzk/room/infrastructure/persistence/RoomGameCleanupMigrationIntegrationTest.java index 3c8b9360..e28d9872 100644 --- a/src/integrationTest/java/com/naminhyeok/fantazzk/room/infrastructure/persistence/RoomGameCleanupMigrationIntegrationTest.java +++ b/src/integrationTest/java/com/naminhyeok/fantazzk/room/infrastructure/persistence/RoomGameCleanupMigrationIntegrationTest.java @@ -91,6 +91,27 @@ class RoomGameCleanupMigrationIntegrationTest { ); } + @Test + void 레거시_null_position도_cleanup과_demotion을_거친다() { + JdbcTemplate jdbcTemplate = jdbcTemplate(); + applyLegacySchema(jdbcTemplate); + insertLegacyAuctionRoomWithNullPosition(jdbcTemplate); + + new ResourceDatabasePopulator( + new ClassPathResource("db/changelog/db.changelog-room-game-cleanup.sql"), + new ClassPathResource("db/changelog/db.changelog-metadata-demotion.sql") + ).execute(jdbcTemplate.getDataSource()); + + Map migratedPlayer = + jdbcTemplate.queryForMap( + "select position from game_player where player_pool_game_id = ? and player_id = ?", + uuid("00000000-0000-0000-0000-0000000000b1"), + 0 + ); + + assertThat(migratedPlayer.get("POSITION")).isEqualTo(""); + } + private JdbcTemplate jdbcTemplate() { String databaseName = "room-game-cleanup-" + UUID.randomUUID(); DriverManagerDataSource dataSource = new DriverManagerDataSource(); @@ -231,6 +252,51 @@ insert into rooms ( ); } + private void insertLegacyAuctionRoomWithNullPosition(JdbcTemplate jdbcTemplate) { + jdbcTemplate.update( + """ + insert into rooms ( + room_id, code, created_at, host_id, status, mode, team_count, team_size, budget, + draft_order_strategy, current_turn_index, current_auction_round, pick_ban_time, + min_bid_unit, position_limit, current_auction_round_ends_at, started_game_id, started_at + ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + """, + uuid("00000000-0000-0000-0000-0000000000b1"), + "AUC902", + Instant.parse("2026-04-12T00:00:00Z").toString(), + "host-b", + "IN_PROGRESS", + "AUCTION", + 2, + 2, + 300, + null, + null, + 1, + 45, + 10, + null, + Instant.parse("2026-04-12T00:05:00Z").toString(), + null, + null + ); + + jdbcTemplate.batchUpdate( + "insert into room_player (players_room_id, room_player_id, name, display_order, status, position) values (?, ?, ?, ?, ?, ?)", + List.of( + new Object[] { uuid("00000000-0000-0000-0000-0000000000b1"), 0, "선수X", 0, "AVAILABLE", null }, + new Object[] { uuid("00000000-0000-0000-0000-0000000000b1"), 1, "선수Y", 1, "AVAILABLE", "JUNGLE" } + ) + ); + jdbcTemplate.batchUpdate( + "insert into room_team_leader (leaders_room_id, team_leader_id, nickname, remaining_budget, action_token, draft_position) values (?, ?, ?, ?, ?, ?)", + List.of( + new Object[] { uuid("00000000-0000-0000-0000-0000000000b1"), "host-b", "호스트B", 300, "host-token-b", null }, + new Object[] { uuid("00000000-0000-0000-0000-0000000000b1"), "guest-b", "게스트B", 300, "guest-token-b", null } + ) + ); + } + private UUID uuid(String value) { return UUID.fromString(value); } diff --git a/src/integrationTest/java/com/naminhyeok/fantazzk/room/query/FindJoinableRoomsIntegrationTest.java b/src/integrationTest/java/com/naminhyeok/fantazzk/room/query/FindJoinableRoomsIntegrationTest.java index 813aa2da..61df0f5b 100644 --- a/src/integrationTest/java/com/naminhyeok/fantazzk/room/query/FindJoinableRoomsIntegrationTest.java +++ b/src/integrationTest/java/com/naminhyeok/fantazzk/room/query/FindJoinableRoomsIntegrationTest.java @@ -74,6 +74,7 @@ private Room waitingRoom(String code, Instant createdAt) { "호스트-" + code, "token-" + code, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, diff --git a/src/integrationTest/java/com/naminhyeok/fantazzk/room/repository/GameRepositoryIntegrationTest.java b/src/integrationTest/java/com/naminhyeok/fantazzk/room/repository/GameRepositoryIntegrationTest.java index 7f5f82d6..c9ed6d8f 100644 --- a/src/integrationTest/java/com/naminhyeok/fantazzk/room/repository/GameRepositoryIntegrationTest.java +++ b/src/integrationTest/java/com/naminhyeok/fantazzk/room/repository/GameRepositoryIntegrationTest.java @@ -65,8 +65,9 @@ class GameRepositoryIntegrationTest { room.getCode(), new GameId(UUID.fromString("00000000-0000-0000-0000-000000000101")), STARTED_AT, + room.getGameType(), RoomMode.AUCTION, - GameRules.auction(2, 2, 300, 45, 10, 1), + GameRules.auction(2, 2, 300, 45, 10), List.of( GameParticipant.auction(new TeamLeaderId("host-1"), "호스트", 300), GameParticipant.auction(new TeamLeaderId("guest-1"), "게스트", 300) @@ -88,9 +89,10 @@ class GameRepositoryIntegrationTest { assertThat(reloaded.getId()).isEqualTo(saved.getId()); assertThat(reloaded.getRoomId()).isEqualTo(room.getId()); assertThat(reloaded.getRoomCode()).isEqualTo("ROOM01"); + assertThat(reloaded.getGameType()).isEqualTo(room.getGameType()); assertThat(reloaded.getStatus()).isEqualTo(GameStatus.IN_PROGRESS); assertThat(reloaded.getStartedAt()).isEqualTo(STARTED_AT); - assertThat(reloaded.getRules()).isEqualTo(GameRules.auction(2, 2, 300, 45, 10, 1)); + assertThat(reloaded.getRules()).isEqualTo(GameRules.auction(2, 2, 300, 45, 10)); assertThat(reloaded.getParticipants()) .containsExactly( GameParticipant.auction(new TeamLeaderId("host-1"), "호스트", 300), @@ -121,8 +123,9 @@ class GameRepositoryIntegrationTest { room.getCode(), new GameId(UUID.fromString("00000000-0000-0000-0000-000000000103")), STARTED_AT, + room.getGameType(), RoomMode.AUCTION, - GameRules.auction(2, 2, 300, 45, 10, 1), + GameRules.auction(2, 2, 300, 45, 10), List.of( GameParticipant.auction(new TeamLeaderId("host-1"), "호스트", 300), GameParticipant.auction(new TeamLeaderId("guest-1"), "게스트", 300) @@ -166,6 +169,7 @@ class GameRepositoryIntegrationTest { room.getCode(), new GameId(UUID.fromString("00000000-0000-0000-0000-000000000102")), STARTED_AT, + room.getGameType(), RoomMode.DRAFT, GameRules.draft(2, 2, 30, DraftOrderStrategy.SNAKE), List.of( @@ -220,6 +224,7 @@ class GameRepositoryIntegrationTest { room.getCode(), new GameId(UUID.fromString("00000000-0000-0000-0000-000000000104")), STARTED_AT, + room.getGameType(), RoomMode.DRAFT, GameRules.draft(2, 2, 30, DraftOrderStrategy.SNAKE), List.of( @@ -254,13 +259,13 @@ private static Room auctionRoom(String code, Instant createdAt) { "호스트", "host-action-token", new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, 300, 45, 10, - 1, null, List.of( new RoomTemplateSpec.Player(new RoomPlayerId(0), "선수1", "TOP", 0), @@ -278,6 +283,7 @@ private static Room draftRoom(String code, Instant createdAt) { "호스트", "host-action-token", new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.DRAFT, 2, 2, diff --git a/src/integrationTest/java/com/naminhyeok/fantazzk/room/repository/RoomRepositoryIntegrationTest.java b/src/integrationTest/java/com/naminhyeok/fantazzk/room/repository/RoomRepositoryIntegrationTest.java index 2a82c0d5..4c6f790b 100644 --- a/src/integrationTest/java/com/naminhyeok/fantazzk/room/repository/RoomRepositoryIntegrationTest.java +++ b/src/integrationTest/java/com/naminhyeok/fantazzk/room/repository/RoomRepositoryIntegrationTest.java @@ -52,6 +52,7 @@ class RoomRepositoryIntegrationTest { "호스트", "host-action-token", new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.DRAFT, 2, 2, @@ -104,6 +105,7 @@ class RoomRepositoryIntegrationTest { "호스트", "host-action-token", new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.DRAFT, 2, 2, @@ -130,7 +132,7 @@ class RoomRepositoryIntegrationTest { @Test @Transactional - void 경매_방의_minBidUnit과_positionLimit을_저장하고_다시_읽는다() { + void 경매_방의_minBidUnit과_gameType을_저장하고_다시_읽는다() { Room room = Room.createFromTemplate( "ROOM04", @@ -138,13 +140,13 @@ class RoomRepositoryIntegrationTest { "호스트", "host-action-token", new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, 300, 30, 10, - 1, null, List.of( new RoomTemplateSpec.Player(new RoomPlayerId(0), "선수1", "TOP", 0), @@ -160,8 +162,8 @@ class RoomRepositoryIntegrationTest { Room reloaded = rooms.findById(saved.getId()).orElseThrow(); + assertThat(reloaded.getGameType()).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(reloaded.getMinBidUnit()).isEqualTo(10); - assertThat(reloaded.getPositionLimit()).isEqualTo(1); } @Test @@ -193,6 +195,7 @@ class RoomRepositoryIntegrationTest { "호스트", "host-action-token", new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.DRAFT, 2, 2, @@ -217,6 +220,7 @@ private Room auctionRoomForStartPersistence() { "호스트", "host-action-token", new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, diff --git a/src/integrationTest/java/com/naminhyeok/fantazzk/room/web/RoomApiIntegrationTest.java b/src/integrationTest/java/com/naminhyeok/fantazzk/room/web/RoomApiIntegrationTest.java index 06a16af3..b8223bbe 100644 --- a/src/integrationTest/java/com/naminhyeok/fantazzk/room/web/RoomApiIntegrationTest.java +++ b/src/integrationTest/java/com/naminhyeok/fantazzk/room/web/RoomApiIntegrationTest.java @@ -82,6 +82,7 @@ class RoomApiIntegrationTest { assertThat(body.resultType()).isEqualTo("SUCCESS"); assertThat(body.success()).hasSize(2); assertThat(body.success()).extracting(JoinableRoomResponse::code).containsExactly("ROOM99", "ROOM01"); + assertThat(body.success()).extracting(JoinableRoomResponse::gameType).containsOnly("LEAGUE_OF_LEGENDS"); } @Test @@ -115,6 +116,7 @@ class RoomApiIntegrationTest { assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(body.at("/resultType").asText()).isEqualTo("SUCCESS"); assertThat(body.at("/success/roomCode").asText()).isEqualTo("ROOM11"); + assertThat(body.at("/success/gameType").asText()).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(body.at("/success/status").asText()).isEqualTo("STARTED"); assertThat(body.at("/success/startedGameId").asText()).isEqualTo(room.getStartedGameId().gameId().toString()); assertThat(body.at("/success/auctionProgress").isMissingNode()).isTrue(); @@ -148,6 +150,7 @@ class RoomApiIntegrationTest { assertThat(body.at("/resultType").asText()).isEqualTo("SUCCESS"); assertThat(body.at("/success/gameId").asText()).isEqualTo(room.getStartedGameId().gameId().toString()); assertThat(body.at("/success/roomCode").asText()).isEqualTo("ROOM12"); + assertThat(body.at("/success/gameType").asText()).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(body.at("/success/status").asText()).isEqualTo("IN_PROGRESS"); assertThat(body.at("/success/auctionProgress/currentRound").asInt()).isEqualTo(1); assertThat(body.at("/success/auctionProgress/currentAuctionTarget/name").asText()).isEqualTo("선수1"); @@ -181,6 +184,7 @@ class RoomApiIntegrationTest { JsonNode body = readBody(response); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(body.at("/success/gameType").asText()).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(body.at("/success/status").asText()).isEqualTo("IN_PROGRESS"); assertThat(body.at("/success/roster/0/teamLeaderId").asText()).isEqualTo("host-ROOM14"); assertThat(body.at("/success/roster/0/playerName").asText()).isEqualTo("선수1"); @@ -200,6 +204,7 @@ private Room startedAuctionRoom(String code, Instant createdAt) { "호스트-" + code, "host-action-token-" + code, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, @@ -239,6 +244,7 @@ private Room joinableAuctionRoom(String code, Instant createdAt) { "호스트-" + code, "host-action-token-" + code, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, @@ -274,6 +280,7 @@ private Room joinableDraftRoom(String code, Instant createdAt) { "호스트-" + code, "host-action-token-" + code, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.DRAFT, 2, 2, diff --git a/src/integrationTest/java/com/naminhyeok/fantazzk/template/application/TemplateCatalogIntegrationTest.java b/src/integrationTest/java/com/naminhyeok/fantazzk/template/application/TemplateCatalogIntegrationTest.java index 667361d1..ca7f13ed 100644 --- a/src/integrationTest/java/com/naminhyeok/fantazzk/template/application/TemplateCatalogIntegrationTest.java +++ b/src/integrationTest/java/com/naminhyeok/fantazzk/template/application/TemplateCatalogIntegrationTest.java @@ -38,7 +38,7 @@ class TemplateCatalogIntegrationTest { createTemplate.create( new CreateTemplateCommand.Draft( "사내 리그 드래프트", - TemplateCatalog.GameType.OVERWATCH_2, + "OVERWATCH_2", 2, 3, 30, @@ -54,12 +54,12 @@ class TemplateCatalogIntegrationTest { TemplateCatalog.TemplateBlueprint blueprint = templateCatalog.getTemplate(created.getId().templateId()); + assertThat(blueprint.gameType()).isEqualTo("OVERWATCH_2"); assertThat(blueprint.mode()).isEqualTo(TemplateCatalog.Mode.DRAFT); assertThat(blueprint.teamCount()).isEqualTo(2); assertThat(blueprint.teamSize()).isEqualTo(3); assertThat(blueprint.pickBanTime()).isEqualTo(30); assertThat(blueprint.minBidUnit()).isNull(); - assertThat(blueprint.positionLimit()).isNull(); assertThat(blueprint.draftOrderStrategy()).isEqualTo(TemplateCatalog.DraftOrderStrategy.FIXED); assertThat(blueprint.players()) .extracting("playerIndex", "name", "position") diff --git a/src/integrationTest/java/com/naminhyeok/fantazzk/template/repository/TemplateRepositoryIntegrationTest.java b/src/integrationTest/java/com/naminhyeok/fantazzk/template/repository/TemplateRepositoryIntegrationTest.java index e4fc10a0..5fd118f5 100644 --- a/src/integrationTest/java/com/naminhyeok/fantazzk/template/repository/TemplateRepositoryIntegrationTest.java +++ b/src/integrationTest/java/com/naminhyeok/fantazzk/template/repository/TemplateRepositoryIntegrationTest.java @@ -38,13 +38,12 @@ class TemplateRepositoryIntegrationTest { templates.save( Template.createAuction( "주말 풋살 경매전", - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, + "LEAGUE_OF_LEGENDS", 2, 2, 300, 45, 10, - 1, List.of( new TemplatePlayer("선수1", "TOP", 0), new TemplatePlayer("선수2", "JUNGLE", 1) @@ -59,11 +58,10 @@ class TemplateRepositoryIntegrationTest { assertThat(reloaded.getId()).isEqualTo(saved.getId()); assertThat(reloaded.getName()).isEqualTo("주말 풋살 경매전"); - assertThat(reloaded.getGameType()).isEqualTo(TemplateCatalog.GameType.LEAGUE_OF_LEGENDS); + assertThat(reloaded.getGameType()).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(reloaded.getMode()).isEqualTo(TemplateCatalog.Mode.AUCTION); assertThat(reloaded.getPickBanTime()).isEqualTo(45); assertThat(reloaded.getMinBidUnit()).isEqualTo(10); - assertThat(reloaded.getPositionLimit()).isEqualTo(1); assertThat(reloaded.getPlayers()) .extracting(TemplatePlayer::displayOrder, TemplatePlayer::name, TemplatePlayer::position) .containsExactly( diff --git a/src/integrationTest/java/com/naminhyeok/fantazzk/template/support/TemplateFixture.java b/src/integrationTest/java/com/naminhyeok/fantazzk/template/support/TemplateFixture.java index e9c49d7e..c6c7ed53 100644 --- a/src/integrationTest/java/com/naminhyeok/fantazzk/template/support/TemplateFixture.java +++ b/src/integrationTest/java/com/naminhyeok/fantazzk/template/support/TemplateFixture.java @@ -21,13 +21,12 @@ public UUID createAuctionTemplateId(String name, int teamCount, int teamSize, in return createTemplate.create( new CreateTemplateCommand.Auction( name, - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, + "LEAGUE_OF_LEGENDS", teamCount, teamSize, budget, 45, 10, - 1, toPlayers(players) ) ).getId().templateId(); @@ -43,7 +42,7 @@ public UUID createDraftTemplateId( return createTemplate.create( new CreateTemplateCommand.Draft( name, - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, + "LEAGUE_OF_LEGENDS", teamCount, teamSize, 30, diff --git a/src/integrationTest/java/com/naminhyeok/fantazzk/template/web/TemplateApiIntegrationTest.java b/src/integrationTest/java/com/naminhyeok/fantazzk/template/web/TemplateApiIntegrationTest.java index bb5756fd..7156857c 100644 --- a/src/integrationTest/java/com/naminhyeok/fantazzk/template/web/TemplateApiIntegrationTest.java +++ b/src/integrationTest/java/com/naminhyeok/fantazzk/template/web/TemplateApiIntegrationTest.java @@ -51,7 +51,6 @@ class TemplateApiIntegrationTest { "budget": 300, "pickBanTime": 45, "minBidUnit": 10, - "positionLimit": 1, "players": [ {"name": "선수1", "position": "TOP"}, {"name": "선수2", "position": "JUNGLE"} @@ -68,9 +67,69 @@ class TemplateApiIntegrationTest { assertThat(success.get("name")).isEqualTo("경매전"); assertThat(success.get("gameType")).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(success.get("mode")).isEqualTo("AUCTION"); + assertThat(success.containsKey("positionLimit")).isFalse(); assertThat(((List) success.get("players"))).hasSize(2); } + @Test + void gameType이_임의_문자열이고_position이_비어있어도_메타데이터로_저장한다() { + ResponseEntity response = restTemplate.exchange( + RequestEntity.post("/api/v1/templates") + .contentType(MediaType.APPLICATION_JSON) + .body( + """ + { + "name": "메타데이터 템플릿", + "gameType": "custom-fe-game", + "mode": "DRAFT", + "teamCount": 2, + "teamSize": 2, + "pickBanTime": 30, + "draftOrderStrategy": "SNAKE", + "players": [ + {"name": "선수1", "position": ""}, + {"name": "선수2", "position": null} + ] + } + """ + ), + Map.class + ); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CREATED); + assertThat(response.getBody()).containsEntry("resultType", "SUCCESS"); + Map success = (Map) response.getBody().get("success"); + String templateId = (String) success.get("id"); + assertThat(success.get("gameType")).isEqualTo("custom-fe-game"); + assertThat(success.containsKey("positionLimit")).isFalse(); + List> players = (List>) success.get("players"); + assertThat(players).hasSize(2); + assertThat(players.get(0)).containsEntry("name", "선수1").containsEntry("position", "").containsEntry("displayOrder", 0); + assertThat(players.get(1)).containsEntry("name", "선수2").containsEntry("displayOrder", 1); + assertThat(players.get(1).get("position")).isNull(); + + ResponseEntity detailResponse = restTemplate.getForEntity("/api/v1/templates/" + templateId, Map.class); + Map detailSuccess = (Map) detailResponse.getBody().get("success"); + List> detailPlayers = (List>) detailSuccess.get("players"); + assertThat(detailSuccess.get("gameType")).isEqualTo("custom-fe-game"); + assertThat(detailSuccess.containsKey("positionLimit")).isFalse(); + assertThat(detailPlayers.get(0).get("position")).isEqualTo(""); + assertThat(detailPlayers.get(1).get("position")).isNull(); + + ResponseEntity listResponse = restTemplate.getForEntity("/api/v1/templates", Map.class); + List> templates = (List>) listResponse.getBody().get("success"); + assertThat(templates).anySatisfy(template -> { + if (!"메타데이터 템플릿".equals(template.get("name"))) { + return; + } + assertThat(template.get("gameType")).isEqualTo("custom-fe-game"); + assertThat(template).doesNotContainKey("positionLimit"); + List> listPlayers = (List>) template.get("players"); + assertThat(listPlayers.get(0).get("position")).isEqualTo(""); + assertThat(listPlayers.get(1).get("position")).isNull(); + }); + } + @Test void 상세_조회는_선수_display_order를_응답에_유지한다() { ResponseEntity createResponse = restTemplate.exchange( @@ -87,7 +146,6 @@ class TemplateApiIntegrationTest { "budget": 300, "pickBanTime": 45, "minBidUnit": 10, - "positionLimit": 1, "players": [ {"name": "선수1", "position": "TOP"}, {"name": "선수2", "position": "JUNGLE"} @@ -107,6 +165,7 @@ class TemplateApiIntegrationTest { Map success = (Map) response.getBody().get("success"); assertThat(success.get("id")).isEqualTo(templateId); assertThat(success.get("name")).isEqualTo("상세조회용 경매전"); + assertThat(success.containsKey("positionLimit")).isFalse(); List> players = (List>) success.get("players"); assertThat(players) .containsExactly( @@ -164,7 +223,6 @@ class TemplateApiIntegrationTest { "teamSize": 2, "budget": 300, "pickBanTime": 45, - "positionLimit": 1, "players": [ {"name": "선수1", "position": "TOP"}, {"name": "선수2", "position": "JUNGLE"} @@ -217,40 +275,6 @@ class TemplateApiIntegrationTest { assertThat(error.get("data")).isNull(); } - @Test - void 드래프트_요청에_포지션_제한이_있으면_400을_반환한다() { - ResponseEntity response = restTemplate.exchange( - RequestEntity.post("/api/v1/templates") - .contentType(MediaType.APPLICATION_JSON) - .body( - """ - { - "name": "드래프트전", - "gameType": "OVERWATCH_2", - "mode": "DRAFT", - "teamCount": 2, - "teamSize": 2, - "pickBanTime": 30, - "positionLimit": 1, - "draftOrderStrategy": "SNAKE", - "players": [ - {"name": "선수1", "position": "TANK"}, - {"name": "선수2", "position": "SUPPORT"} - ] - } - """ - ), - Map.class - ); - - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); - assertThat(response.getBody()).containsEntry("resultType", "ERROR"); - Map error = (Map) response.getBody().get("error"); - assertThat(error.get("code")).isEqualTo("TEMPLATE_DRAFT_POSITION_LIMIT_NOT_ALLOWED"); - assertThat(error.get("message")).isEqualTo("드래프트 템플릿에는 포지션 제한을 지정할 수 없습니다"); - assertThat(error.get("data")).isNull(); - } - @Test void 요청_필드_검증에_실패하면_400과_필드_에러를_반환한다() { ResponseEntity response = restTemplate.exchange( @@ -267,7 +291,6 @@ class TemplateApiIntegrationTest { "budget": 300, "pickBanTime": 0, "minBidUnit": 10, - "positionLimit": 1, "players": [] } """ @@ -318,7 +341,6 @@ class TemplateApiIntegrationTest { "budget": 300, "pickBanTime": 45, "minBidUnit": 10, - "positionLimit": 1, "players": [ {"name": "선수1", "position": "TOP"}, {"name": "선수2", "position": "JUNGLE"} @@ -336,9 +358,16 @@ class TemplateApiIntegrationTest { List> templates = (List>) response.getBody().get("success"); assertThat(templates).anySatisfy(template -> { assertThat(template.get("name")).isEqualTo("목록용 경매전"); + assertThat(template.get("gameType")).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(template.get("mode")).isEqualTo("AUCTION"); assertThat(template.get("teamCount")).isEqualTo(2); - assertThat(template).doesNotContainKey("players"); + assertThat(template.get("pickBanTime")).isEqualTo(45); + assertThat(template.get("minBidUnit")).isEqualTo(10); + assertThat(template).doesNotContainKey("positionLimit"); + List> players = (List>) template.get("players"); + assertThat(players).hasSize(2); + assertThat(players.get(0)).containsEntry("name", "선수1").containsEntry("position", "TOP").containsEntry("displayOrder", 0); + assertThat(players.get(1)).containsEntry("name", "선수2").containsEntry("position", "JUNGLE").containsEntry("displayOrder", 1); }); } } diff --git a/src/main/java/com/naminhyeok/fantazzk/OpenApiDocumentation.java b/src/main/java/com/naminhyeok/fantazzk/OpenApiDocumentation.java index 94a26495..1ccb8aac 100644 --- a/src/main/java/com/naminhyeok/fantazzk/OpenApiDocumentation.java +++ b/src/main/java/com/naminhyeok/fantazzk/OpenApiDocumentation.java @@ -64,7 +64,6 @@ public final class OpenApiDocumentation { "budget": null, "pickBanTime": 30, "minBidUnit": null, - "positionLimit": null, "draftOrderStrategy": "SNAKE", "players": [ { @@ -97,7 +96,6 @@ public final class OpenApiDocumentation { "budget": null, "pickBanTime": 30, "minBidUnit": null, - "positionLimit": null, "draftOrderStrategy": "SNAKE", "players": [ { @@ -122,6 +120,7 @@ public final class OpenApiDocumentation { "success": { "room": { "roomCode": "ROOM01", + "gameType": "LEAGUE_OF_LEGENDS", "status": "WAITING", "mode": "DRAFT", "teamCount": 2, @@ -184,6 +183,7 @@ public final class OpenApiDocumentation { "success": { "room": { "roomCode": "ROOM01", + "gameType": "LEAGUE_OF_LEGENDS", "status": "WAITING", "mode": "DRAFT", "teamCount": 2, @@ -251,6 +251,7 @@ public final class OpenApiDocumentation { "resultType": "SUCCESS", "success": { "roomCode": "ROOM01", + "gameType": "LEAGUE_OF_LEGENDS", "status": "WAITING", "mode": "DRAFT", "teamCount": 2, @@ -313,6 +314,7 @@ public final class OpenApiDocumentation { "success": { "gameId": "00000000-0000-0000-0000-000000000202", "roomCode": "ROOM01", + "gameType": "LEAGUE_OF_LEGENDS", "mode": "DRAFT", "status": "IN_PROGRESS", "teamCount": 2, @@ -376,6 +378,7 @@ public final class OpenApiDocumentation { "success": { "gameId": "00000000-0000-0000-0000-000000000201", "roomCode": "ROOM01", + "gameType": "LEAGUE_OF_LEGENDS", "mode": "AUCTION", "status": "IN_PROGRESS", "teamCount": 2, diff --git a/src/main/java/com/naminhyeok/fantazzk/room/domain/AuctionGame.java b/src/main/java/com/naminhyeok/fantazzk/room/domain/AuctionGame.java index 89763dc2..3d8f4c95 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/domain/AuctionGame.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/domain/AuctionGame.java @@ -46,6 +46,7 @@ public AuctionGame( GameId id, RoomId roomId, String roomCode, + String gameType, Instant startedAt, GameRules rules, List participants, @@ -53,7 +54,7 @@ public AuctionGame( int currentRound, Instant currentRoundEndsAt ) { - super(id, roomId, roomCode, startedAt, GameStatus.IN_PROGRESS, rules, playerPool); + super(id, roomId, roomCode, gameType, startedAt, GameStatus.IN_PROGRESS, rules, playerPool); this.participants = new ArrayList<>(participants); this.currentRound = currentRound; this.currentRoundEndsAt = currentRoundEndsAt; @@ -71,8 +72,7 @@ public GameRules getRules() { getTeamSize(), getBudget(), getPickBanTime(), - getMinBidUnit(), - getPositionLimit() + getMinBidUnit() ); } @@ -98,8 +98,6 @@ public AuctionBid placeBid(TeamLeaderId teamLeaderId, int amount, Instant now) { AuctionParticipant leader = findParticipant(teamLeaderId, RoomErrorType.ROOM_BIDDER_NOT_FOUND); GameParticipant.AuctionState bidder = leader.auctionState(); GamePlayer target = requireCurrentAuctionTarget(); - validateAuctionPositionLimit(teamLeaderId, target); - if (bidder.remainingBudget() < amount) { throw CoreException.of(RoomErrorType.ROOM_BID_BUDGET_EXCEEDED); } @@ -165,7 +163,6 @@ public AuctionSettlement settleAuction(Instant now) { } AuctionParticipant winner = findParticipant(winningBid.teamLeaderId(), RoomErrorType.ROOM_BIDDER_NOT_FOUND); - validateAuctionPositionLimit(winner.teamLeaderId(), target); spend(winner.teamLeaderId(), winningBid.amount()); members.add(new RosterMember(winningBid.teamLeaderId(), target.name(), members.size())); @@ -244,31 +241,6 @@ private void spend(TeamLeaderId leaderId, int amount) { throw RoomStateInvalidException.auctionWinnerMissing(leaderId); } - private void validateAuctionPositionLimit(TeamLeaderId leaderId, GamePlayer target) { - Integer positionLimit = getRules().auctionRules().positionLimit(); - if (positionLimit == null) { - return; - } - - long assignedCount = - members.stream() - .filter(member -> member.teamLeaderId().equals(leaderId)) - .map(this::findAssignedPlayerPosition) - .filter(target.position()::equals) - .count(); - if (assignedCount >= positionLimit) { - throw CoreException.of(RoomErrorType.ROOM_AUCTION_POSITION_LIMIT_EXCEEDED); - } - } - - private String findAssignedPlayerPosition(RosterMember member) { - return mutablePlayerPool().stream() - .filter(player -> player.name().equals(member.playerName())) - .findFirst() - .map(GamePlayer::position) - .orElse(null); - } - private List mutableParticipants() { return participants; } diff --git a/src/main/java/com/naminhyeok/fantazzk/room/domain/DraftGame.java b/src/main/java/com/naminhyeok/fantazzk/room/domain/DraftGame.java index aead17b9..45d8a9d7 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/domain/DraftGame.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/domain/DraftGame.java @@ -38,13 +38,14 @@ public DraftGame( GameId id, RoomId roomId, String roomCode, + String gameType, Instant startedAt, GameRules rules, List participants, List playerPool, int currentTurnIndex ) { - super(id, roomId, roomCode, startedAt, GameStatus.IN_PROGRESS, rules, playerPool); + super(id, roomId, roomCode, gameType, startedAt, GameStatus.IN_PROGRESS, rules, playerPool); this.participants = new ArrayList<>(participants); this.currentTurnIndex = currentTurnIndex; this.members = new ArrayList<>(); diff --git a/src/main/java/com/naminhyeok/fantazzk/room/domain/Game.java b/src/main/java/com/naminhyeok/fantazzk/room/domain/Game.java index 97f17f37..11b1b3da 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/domain/Game.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/domain/Game.java @@ -42,6 +42,8 @@ public abstract class Game implements AggregateRoot { private final RoomId roomId; @Column(name = "room_code", nullable = false, updatable = false) private final String roomCode; + @Column(name = "game_type", updatable = false) + private final String gameType; @Column(name = "started_at", nullable = false, updatable = false) private final Instant startedAt; @Enumerated(EnumType.STRING) @@ -57,8 +59,6 @@ public abstract class Game implements AggregateRoot { private final int pickBanTime; @Column(name = "min_bid_unit", updatable = false) private final Integer minBidUnit; - @Column(name = "position_limit", updatable = false) - private final Integer positionLimit; @Enumerated(EnumType.STRING) @Column(name = "draft_order_strategy", updatable = false) private final DraftOrderStrategy draftOrderStrategy; @@ -74,6 +74,7 @@ protected Game() { this.version = 0L; this.roomId = null; this.roomCode = null; + this.gameType = null; this.startedAt = null; this.status = null; this.teamCount = 0; @@ -81,7 +82,6 @@ protected Game() { this.budget = null; this.pickBanTime = 0; this.minBidUnit = null; - this.positionLimit = null; this.draftOrderStrategy = null; this.playerPool = new ArrayList<>(); this.domainEvents = new ArrayList<>(); @@ -91,6 +91,7 @@ public Game( GameId id, RoomId roomId, String roomCode, + String gameType, Instant startedAt, GameStatus status, GameRules rules, @@ -100,6 +101,7 @@ public Game( this.version = 0L; this.roomId = roomId; this.roomCode = roomCode; + this.gameType = gameType; this.startedAt = startedAt; this.status = status; this.teamCount = rules.teamCount(); @@ -107,7 +109,6 @@ public Game( this.budget = rules.budget(); this.pickBanTime = rules.pickBanTime(); this.minBidUnit = rules.minBidUnit(); - this.positionLimit = rules.positionLimit(); this.draftOrderStrategy = rules.draftOrderStrategy(); this.playerPool = new ArrayList<>(playerPool); this.domainEvents = new ArrayList<>(); diff --git a/src/main/java/com/naminhyeok/fantazzk/room/domain/GameFactory.java b/src/main/java/com/naminhyeok/fantazzk/room/domain/GameFactory.java index 75477ae1..7973e855 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/domain/GameFactory.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/domain/GameFactory.java @@ -10,6 +10,7 @@ public Game create(StartedGameSnapshot snapshot) { snapshot.gameId(), snapshot.roomId(), snapshot.roomCode(), + snapshot.gameType(), snapshot.startedAt(), snapshot.rules(), snapshot.participants().stream().map(AuctionParticipant.class::cast).toList(), @@ -21,6 +22,7 @@ public Game create(StartedGameSnapshot snapshot) { snapshot.gameId(), snapshot.roomId(), snapshot.roomCode(), + snapshot.gameType(), snapshot.startedAt(), snapshot.rules(), snapshot.participants().stream().map(DraftParticipant.class::cast).toList(), diff --git a/src/main/java/com/naminhyeok/fantazzk/room/domain/GamePlayer.java b/src/main/java/com/naminhyeok/fantazzk/room/domain/GamePlayer.java index fb0e0c1e..e82f8cf1 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/domain/GamePlayer.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/domain/GamePlayer.java @@ -28,7 +28,7 @@ public GamePlayer() { public GamePlayer(RoomPlayerId playerId, String name, String position, int displayOrder) { this.playerId = java.util.Objects.requireNonNull(playerId, "playerId must not be null"); this.name = java.util.Objects.requireNonNull(name, "name must not be null"); - this.position = java.util.Objects.requireNonNull(position, "position must not be null"); + this.position = position; this.displayOrder = displayOrder; } diff --git a/src/main/java/com/naminhyeok/fantazzk/room/domain/GameRules.java b/src/main/java/com/naminhyeok/fantazzk/room/domain/GameRules.java index 9413cef5..29aeb67d 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/domain/GameRules.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/domain/GameRules.java @@ -9,11 +9,10 @@ public record GameRules( Integer budget, int pickBanTime, Integer minBidUnit, - Integer positionLimit, DraftOrderStrategy draftOrderStrategy ) { - public static GameRules auction(int teamCount, int teamSize, int budget, int pickBanTime, int minBidUnit, Integer positionLimit) { - return new GameRules(RoomMode.AUCTION, teamCount, teamSize, budget, pickBanTime, minBidUnit, positionLimit, null); + public static GameRules auction(int teamCount, int teamSize, int budget, int pickBanTime, int minBidUnit) { + return new GameRules(RoomMode.AUCTION, teamCount, teamSize, budget, pickBanTime, minBidUnit, null); } public static GameRules draft(int teamCount, int teamSize, int pickBanTime, DraftOrderStrategy draftOrderStrategy) { @@ -24,7 +23,6 @@ public static GameRules draft(int teamCount, int teamSize, int pickBanTime, Draf null, pickBanTime, null, - null, Objects.requireNonNull(draftOrderStrategy) ); } @@ -33,7 +31,7 @@ public AuctionRules auctionRules() { if (mode != RoomMode.AUCTION || budget == null || minBidUnit == null) { throw new IllegalStateException("auction rules are not available"); } - return new AuctionRules(budget, pickBanTime, minBidUnit, positionLimit); + return new AuctionRules(budget, pickBanTime, minBidUnit); } public DraftRules draftRules() { @@ -46,8 +44,7 @@ public DraftRules draftRules() { public record AuctionRules( int budget, int pickBanTime, - int minBidUnit, - Integer positionLimit + int minBidUnit ) { } diff --git a/src/main/java/com/naminhyeok/fantazzk/room/domain/Room.java b/src/main/java/com/naminhyeok/fantazzk/room/domain/Room.java index a78c3c51..ae4f0ad3 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/domain/Room.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/domain/Room.java @@ -37,6 +37,8 @@ public class Room implements AggregateRoot { private final TeamLeaderId hostLeaderId; @Enumerated(EnumType.STRING) private RoomStatus status; + @Column(name = "game_type") + private final String gameType; @Enumerated(EnumType.STRING) private final RoomMode mode; private final int teamCount; @@ -45,8 +47,6 @@ public class Room implements AggregateRoot { @Column(name = "pick_ban_time") private final int pickBanTime; private final Integer minBidUnit; - @Column(name = "position_limit") - private final Integer positionLimit; @Enumerated(EnumType.STRING) private final DraftOrderStrategy draftOrderStrategy; @Column(name = "started_game_id") @@ -65,13 +65,13 @@ public Room( String code, Instant createdAt, TeamLeaderId hostLeaderId, + String gameType, RoomMode mode, int teamCount, int teamSize, Integer budget, int pickBanTime, Integer minBidUnit, - Integer positionLimit, DraftOrderStrategy draftOrderStrategy ) { this.id = new RoomId(UUID.randomUUID()); @@ -79,13 +79,13 @@ public Room( this.createdAt = Objects.requireNonNull(createdAt, "createdAt must not be null"); this.hostLeaderId = Objects.requireNonNull(hostLeaderId, "hostLeaderId must not be null"); this.status = RoomStatus.WAITING; + this.gameType = gameType; this.mode = mode; this.teamCount = teamCount; this.teamSize = teamSize; this.budget = budget; this.pickBanTime = pickBanTime; this.minBidUnit = minBidUnit; - this.positionLimit = positionLimit; this.draftOrderStrategy = draftOrderStrategy; this.startedGameId = null; this.startedAt = null; @@ -106,13 +106,13 @@ public static Room createFromTemplate( code, createdAt, hostLeaderId, + spec.gameType(), spec.mode() == RoomMode.AUCTION ? RoomMode.AUCTION : RoomMode.DRAFT, spec.teamCount(), spec.teamSize(), spec.budget(), spec.pickBanTime(), spec.minBidUnit(), - spec.positionLimit(), spec.draftOrderStrategy() ); @@ -219,9 +219,10 @@ public StartedGameSnapshot start(TeamLeaderId callerLeaderId, GameId gameId, Ins code, startedGameId, startedAt, + gameType, mode, mode == RoomMode.AUCTION - ? GameRules.auction(teamCount, teamSize, budget, pickBanTime, minBidUnit, positionLimit) + ? GameRules.auction(teamCount, teamSize, budget, pickBanTime, minBidUnit) : GameRules.draft(teamCount, teamSize, pickBanTime, draftOrderStrategy), leaders.stream() .map(leader -> mode == RoomMode.AUCTION diff --git a/src/main/java/com/naminhyeok/fantazzk/room/domain/RoomTemplateSpec.java b/src/main/java/com/naminhyeok/fantazzk/room/domain/RoomTemplateSpec.java index 0f9af90d..e744156c 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/domain/RoomTemplateSpec.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/domain/RoomTemplateSpec.java @@ -5,13 +5,13 @@ import java.util.Objects; public record RoomTemplateSpec( + String gameType, RoomMode mode, int teamCount, int teamSize, Integer budget, int pickBanTime, Integer minBidUnit, - Integer positionLimit, DraftOrderStrategy draftOrderStrategy, List players ) { @@ -47,28 +47,12 @@ public record RoomTemplateSpec( if (minBidUnit != null) { throw new IllegalArgumentException("드래프트 방 생성 명세에는 최소 입찰 단위를 지정할 수 없습니다"); } - if (positionLimit != null) { - throw new IllegalArgumentException("드래프트 방 생성 명세에는 포지션 제한을 지정할 수 없습니다"); - } if (draftOrderStrategy == null) { throw new IllegalArgumentException("드래프트 방 생성 명세에는 순서 전략이 필요합니다"); } } } - public RoomTemplateSpec( - RoomMode mode, - int teamCount, - int teamSize, - Integer budget, - int pickBanTime, - Integer minBidUnit, - DraftOrderStrategy draftOrderStrategy, - List players - ) { - this(mode, teamCount, teamSize, budget, pickBanTime, minBidUnit, null, draftOrderStrategy, players); - } - public static RoomTemplateSpec from(TemplateCatalog.TemplateBlueprint template) { Objects.requireNonNull(template, "template must not be null"); List players = template.players().stream().map(Player::from).toList(); @@ -77,13 +61,13 @@ public static RoomTemplateSpec from(TemplateCatalog.TemplateBlueprint template) throw new IllegalArgumentException("선수 수는 정확히 " + requiredPlayerCount + "명이어야 합니다"); } return new RoomTemplateSpec( + template.gameType(), RoomMode.from(template.mode()), template.teamCount(), template.teamSize(), template.budget(), requirePickBanTime(template.pickBanTime()), template.minBidUnit(), - template.positionLimit(), DraftOrderStrategy.from(template.draftOrderStrategy()), players ); diff --git a/src/main/java/com/naminhyeok/fantazzk/room/domain/StartedGameSnapshot.java b/src/main/java/com/naminhyeok/fantazzk/room/domain/StartedGameSnapshot.java index d4f227fe..02c8e1f3 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/domain/StartedGameSnapshot.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/domain/StartedGameSnapshot.java @@ -9,6 +9,7 @@ public record StartedGameSnapshot( String roomCode, GameId gameId, Instant startedAt, + String gameType, RoomMode gameMode, GameRules rules, List participants, diff --git a/src/main/java/com/naminhyeok/fantazzk/room/query/AuctionTargetResponse.java b/src/main/java/com/naminhyeok/fantazzk/room/query/AuctionTargetResponse.java index b8af9c6c..ba1689b4 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/query/AuctionTargetResponse.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/query/AuctionTargetResponse.java @@ -8,7 +8,7 @@ public record AuctionTargetResponse( @Schema(description = "선수 이름", example = "선수2") String name, - @Schema(description = "선수 포지션", example = "JUNGLE") + @Schema(description = "FE가 관리하는 선수 포지션 메타데이터", example = "JUNGLE", nullable = true) String position ) { public static AuctionTargetResponse from(RoomPlayer player) { diff --git a/src/main/java/com/naminhyeok/fantazzk/room/query/GameDetailResponse.java b/src/main/java/com/naminhyeok/fantazzk/room/query/GameDetailResponse.java index 2dc9fdac..ea579643 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/query/GameDetailResponse.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/query/GameDetailResponse.java @@ -18,6 +18,8 @@ public record GameDetailResponse( String gameId, @Schema(description = "원본 방 코드", example = "ROOM01") String roomCode, + @Schema(description = "FE가 관리하는 게임 타입 메타데이터", example = "LEAGUE_OF_LEGENDS", nullable = true) + String gameType, @Schema(description = "게임 모드", example = "AUCTION", allowableValues = {"DRAFT", "AUCTION"}) String mode, @Schema(description = "게임 상태", example = "IN_PROGRESS", allowableValues = {"IN_PROGRESS", "COMPLETED"}) @@ -47,6 +49,7 @@ public static GameDetailResponse from(Game game) { return new GameDetailResponse( game.getId().gameId().toString(), game.getRoomCode(), + game.getGameType(), modeOf(game), game.getStatus().name(), game.getTeamCount(), diff --git a/src/main/java/com/naminhyeok/fantazzk/room/query/GamePlayerResponse.java b/src/main/java/com/naminhyeok/fantazzk/room/query/GamePlayerResponse.java index c59b6e31..d8ea3cfe 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/query/GamePlayerResponse.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/query/GamePlayerResponse.java @@ -8,7 +8,7 @@ public record GamePlayerResponse( @Schema(description = "선수 이름", example = "선수1") String name, - @Schema(description = "선수 포지션", example = "TOP") + @Schema(description = "FE가 관리하는 선수 포지션 메타데이터", example = "TOP", nullable = true) String position, @Schema(description = "노출 순서. 경매 모드에서는 현재 경매 순서, 드래프트 모드에서는 원래 displayOrder 입니다.", example = "0") int displayOrder, diff --git a/src/main/java/com/naminhyeok/fantazzk/room/query/JoinableRoomResponse.java b/src/main/java/com/naminhyeok/fantazzk/room/query/JoinableRoomResponse.java index 6255cf1b..5bf1785e 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/query/JoinableRoomResponse.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/query/JoinableRoomResponse.java @@ -7,6 +7,8 @@ public record JoinableRoomResponse( @Schema(description = "방 코드", example = "ROOM01") String code, + @Schema(description = "FE가 관리하는 게임 타입 메타데이터", example = "LEAGUE_OF_LEGENDS", nullable = true) + String gameType, @Schema(description = "게임 모드", example = "DRAFT", allowableValues = {"DRAFT", "AUCTION"}) String mode, @Schema(description = "총 팀 수", example = "2") @@ -26,6 +28,7 @@ public static JoinableRoomResponse from(Room room) { int joinedLeaderCount = room.getLeaders().size(); return new JoinableRoomResponse( room.getCode(), + room.getGameType(), room.getMode().name(), room.getTeamCount(), joinedLeaderCount, diff --git a/src/main/java/com/naminhyeok/fantazzk/room/query/RoomDetailResponse.java b/src/main/java/com/naminhyeok/fantazzk/room/query/RoomDetailResponse.java index cf424bfa..309ae18c 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/query/RoomDetailResponse.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/query/RoomDetailResponse.java @@ -8,6 +8,8 @@ public record RoomDetailResponse( @Schema(description = "방 코드", example = "ROOM01") String roomCode, + @Schema(description = "FE가 관리하는 게임 타입 메타데이터", example = "LEAGUE_OF_LEGENDS", nullable = true) + String gameType, @Schema(description = "방 상태", example = "WAITING", allowableValues = {"WAITING", "STARTED"}) String status, @Schema(description = "게임 모드", example = "DRAFT", allowableValues = {"DRAFT", "AUCTION"}) @@ -44,6 +46,7 @@ public record RoomDetailResponse( public static RoomDetailResponse from(Room room) { return new RoomDetailResponse( room.getCode(), + room.getGameType(), room.getStatus().name(), room.getMode().name(), room.getTeamCount(), diff --git a/src/main/java/com/naminhyeok/fantazzk/room/query/RoomPlayerResponse.java b/src/main/java/com/naminhyeok/fantazzk/room/query/RoomPlayerResponse.java index 90d6d682..978a239b 100644 --- a/src/main/java/com/naminhyeok/fantazzk/room/query/RoomPlayerResponse.java +++ b/src/main/java/com/naminhyeok/fantazzk/room/query/RoomPlayerResponse.java @@ -8,7 +8,7 @@ public record RoomPlayerResponse( @Schema(description = "선수 이름", example = "선수1") String name, - @Schema(description = "선수 포지션", example = "TOP") + @Schema(description = "FE가 관리하는 선수 포지션 메타데이터", example = "TOP", nullable = true) String position, @Schema(description = "노출 순서", example = "0") int displayOrder, diff --git a/src/main/java/com/naminhyeok/fantazzk/template/TemplateCatalog.java b/src/main/java/com/naminhyeok/fantazzk/template/TemplateCatalog.java index ccd73ba0..55207d45 100644 --- a/src/main/java/com/naminhyeok/fantazzk/template/TemplateCatalog.java +++ b/src/main/java/com/naminhyeok/fantazzk/template/TemplateCatalog.java @@ -1,43 +1,11 @@ package com.naminhyeok.fantazzk.template; import java.util.List; -import java.util.Set; import java.util.UUID; public interface TemplateCatalog { TemplateBlueprint getTemplate(UUID templateId); - enum GameType { - LEAGUE_OF_LEGENDS(Set.of("TOP", "JUNGLE", "MID", "ADC", "SUPPORT")), - OVERWATCH_2(Set.of("TANK", "DPS", "SUPPORT")); - - private final Set supportedPositions; - - GameType(Set supportedPositions) { - this.supportedPositions = supportedPositions; - } - - public boolean supportsPosition(String position) { - return supportedPositions.contains(normalize(position)); - } - - public void validatePosition(String position) { - String normalizedPosition = normalize(position); - - if (!supportsPosition(normalizedPosition)) { - throw new IllegalArgumentException(name() + " 게임은 " + normalizedPosition + " 포지션을 지원하지 않습니다"); - } - } - - private static String normalize(String position) { - if (position == null || position.isBlank()) { - throw new IllegalArgumentException("포지션은 비어 있을 수 없습니다"); - } - - return position.trim().toUpperCase(); - } - } - enum Mode { AUCTION, DRAFT @@ -49,13 +17,13 @@ enum DraftOrderStrategy { } record TemplateBlueprint( + String gameType, Mode mode, int teamCount, int teamSize, Integer budget, Integer pickBanTime, Integer minBidUnit, - Integer positionLimit, DraftOrderStrategy draftOrderStrategy, List players ) { diff --git a/src/main/java/com/naminhyeok/fantazzk/template/application/CreateTemplate.java b/src/main/java/com/naminhyeok/fantazzk/template/application/CreateTemplate.java index 67a027bf..a44d243b 100644 --- a/src/main/java/com/naminhyeok/fantazzk/template/application/CreateTemplate.java +++ b/src/main/java/com/naminhyeok/fantazzk/template/application/CreateTemplate.java @@ -24,7 +24,6 @@ public Template create(CreateTemplateCommand command) { auction.budget(), auction.pickBanTime(), auction.minBidUnit(), - auction.positionLimit(), auction.players().stream() .map(player -> new TemplatePlayer(player.name(), player.position(), player.displayOrder())) .toList() diff --git a/src/main/java/com/naminhyeok/fantazzk/template/application/CreateTemplateCommand.java b/src/main/java/com/naminhyeok/fantazzk/template/application/CreateTemplateCommand.java index 947b506c..dd3818ba 100644 --- a/src/main/java/com/naminhyeok/fantazzk/template/application/CreateTemplateCommand.java +++ b/src/main/java/com/naminhyeok/fantazzk/template/application/CreateTemplateCommand.java @@ -6,7 +6,7 @@ public sealed interface CreateTemplateCommand permits CreateTemplateCommand.Auction, CreateTemplateCommand.Draft { String name(); - TemplateCatalog.GameType gameType(); + String gameType(); int teamCount(); @@ -21,20 +21,19 @@ record Player(String name, String position, int displayOrder) { record Auction( String name, - TemplateCatalog.GameType gameType, + String gameType, int teamCount, int teamSize, int budget, int pickBanTime, int minBidUnit, - Integer positionLimit, List players ) implements CreateTemplateCommand { } record Draft( String name, - TemplateCatalog.GameType gameType, + String gameType, int teamCount, int teamSize, int pickBanTime, diff --git a/src/main/java/com/naminhyeok/fantazzk/template/application/ProvideTemplateCatalog.java b/src/main/java/com/naminhyeok/fantazzk/template/application/ProvideTemplateCatalog.java index 161938ea..2ba7da42 100644 --- a/src/main/java/com/naminhyeok/fantazzk/template/application/ProvideTemplateCatalog.java +++ b/src/main/java/com/naminhyeok/fantazzk/template/application/ProvideTemplateCatalog.java @@ -22,13 +22,13 @@ public TemplateBlueprint getTemplate(UUID templateId) { TemplateDetail detail = findTemplates.getDetail(new TemplateId(templateId)); Template template = detail.template(); return new TemplateBlueprint( + template.getGameType(), template.getMode(), template.getTeamCount(), template.getTeamSize(), template.getBudget(), template.getPickBanTime(), template.getMinBidUnit(), - template.getPositionLimit(), template.getDraftOrderStrategy(), detail.players().stream() .map(player -> new PlayerBlueprint(player.name(), player.position(), player.displayOrder())) diff --git a/src/main/java/com/naminhyeok/fantazzk/template/domain/Template.java b/src/main/java/com/naminhyeok/fantazzk/template/domain/Template.java index 25a7ff50..b69eb984 100644 --- a/src/main/java/com/naminhyeok/fantazzk/template/domain/Template.java +++ b/src/main/java/com/naminhyeok/fantazzk/template/domain/Template.java @@ -15,47 +15,48 @@ public class Template implements AggregateRoot { private final TemplateId id; private String name; + private String gameType; private TemplateConfiguration configuration; @ElementCollection @CollectionTable(name = "template_player", joinColumns = @JoinColumn(name = "players_template_id")) private List players; - Template(String name, TemplateConfiguration configuration) { + Template(String name, String gameType, TemplateConfiguration configuration) { if (name == null || name.isBlank()) { throw new IllegalArgumentException("템플릿 이름은 비어 있을 수 없습니다"); } this.id = new TemplateId(UUID.randomUUID()); this.name = name; + this.gameType = gameType; this.configuration = configuration; this.players = new ArrayList<>(); } public static Template createAuction( String name, - TemplateCatalog.GameType gameType, + String gameType, int teamCount, int teamSize, int budget, int pickBanTime, int minBidUnit, - Integer positionLimit, List players ) { - return new Template(name, TemplateConfiguration.auction(gameType, teamCount, teamSize, budget, pickBanTime, minBidUnit, positionLimit)) + return new Template(name, gameType, TemplateConfiguration.auction(teamCount, teamSize, budget, pickBanTime, minBidUnit)) .registerPlayers(players); } public static Template createDraft( String name, - TemplateCatalog.GameType gameType, + String gameType, int teamCount, int teamSize, int pickBanTime, TemplateCatalog.DraftOrderStrategy strategy, List players ) { - return new Template(name, TemplateConfiguration.draft(gameType, teamCount, teamSize, pickBanTime, strategy)) + return new Template(name, gameType, TemplateConfiguration.draft(teamCount, teamSize, pickBanTime, strategy)) .registerPlayers(players); } @@ -63,8 +64,8 @@ public TemplateCatalog.Mode getMode() { return configuration.getMode(); } - public TemplateCatalog.GameType getGameType() { - return configuration.getGameType(); + public String getGameType() { + return gameType; } public int getTeamCount() { @@ -87,10 +88,6 @@ public Integer getMinBidUnit() { return configuration.getMinBidUnit(); } - public Integer getPositionLimit() { - return configuration.getPositionLimit(); - } - public TemplateCatalog.DraftOrderStrategy getDraftOrderStrategy() { return configuration.getDraftOrderStrategy(); } @@ -111,10 +108,7 @@ private Template registerPlayers(List templatePlayers) { } players.clear(); - for (TemplatePlayer player : templatePlayers) { - configuration.getGameType().validatePosition(player.position()); - players.add(player); - } + players.addAll(templatePlayers); return this; } diff --git a/src/main/java/com/naminhyeok/fantazzk/template/domain/TemplateConfiguration.java b/src/main/java/com/naminhyeok/fantazzk/template/domain/TemplateConfiguration.java index 40c1f2ea..d265c145 100644 --- a/src/main/java/com/naminhyeok/fantazzk/template/domain/TemplateConfiguration.java +++ b/src/main/java/com/naminhyeok/fantazzk/template/domain/TemplateConfiguration.java @@ -10,8 +10,6 @@ @Getter @EqualsAndHashCode public final class TemplateConfiguration implements ValueObject { - @Enumerated(EnumType.STRING) - private final TemplateCatalog.GameType gameType; @Enumerated(EnumType.STRING) private final TemplateCatalog.Mode mode; private final int teamCount; @@ -19,24 +17,18 @@ public final class TemplateConfiguration implements ValueObject { private final Integer budget; private final int pickBanTime; private final Integer minBidUnit; - private final Integer positionLimit; @Enumerated(EnumType.STRING) private final TemplateCatalog.DraftOrderStrategy draftOrderStrategy; private TemplateConfiguration( - TemplateCatalog.GameType gameType, TemplateCatalog.Mode mode, int teamCount, int teamSize, Integer budget, int pickBanTime, Integer minBidUnit, - Integer positionLimit, TemplateCatalog.DraftOrderStrategy draftOrderStrategy ) { - if (gameType == null) { - throw new IllegalArgumentException("게임 타입은 필수입니다"); - } if (teamCount <= 0) { throw new IllegalArgumentException("팀 수는 0보다 커야 합니다"); } @@ -60,9 +52,6 @@ private TemplateConfiguration( if (minBidUnit <= 0) { throw new IllegalArgumentException("최소 입찰 단위는 0보다 커야 합니다"); } - if (positionLimit != null && positionLimit <= 0) { - throw new IllegalArgumentException("포지션 제한은 0보다 커야 합니다"); - } if (draftOrderStrategy != null) { throw new IllegalArgumentException("경매 템플릿에는 드래프트 순서 전략을 지정할 수 없습니다"); } @@ -75,76 +64,62 @@ private TemplateConfiguration( if (minBidUnit != null) { throw new IllegalArgumentException("드래프트 템플릿에는 최소 입찰 단위를 지정할 수 없습니다"); } - if (positionLimit != null) { - throw new IllegalArgumentException("드래프트 템플릿에는 포지션 제한을 지정할 수 없습니다"); - } if (draftOrderStrategy == null) { throw new IllegalArgumentException("드래프트 템플릿에는 순서 전략이 필요합니다"); } } - this.gameType = gameType; this.mode = mode; this.teamCount = teamCount; this.teamSize = teamSize; this.budget = budget; this.pickBanTime = pickBanTime; this.minBidUnit = minBidUnit; - this.positionLimit = positionLimit; this.draftOrderStrategy = draftOrderStrategy; } public static TemplateConfiguration auction( - TemplateCatalog.GameType gameType, int teamCount, int teamSize, int budget, int pickBanTime, - int minBidUnit, - Integer positionLimit + int minBidUnit ) { return new TemplateConfiguration( - gameType, TemplateCatalog.Mode.AUCTION, teamCount, teamSize, budget, pickBanTime, minBidUnit, - positionLimit, null ); } public static TemplateConfiguration draft( - TemplateCatalog.GameType gameType, int teamCount, int teamSize, int pickBanTime, TemplateCatalog.DraftOrderStrategy strategy ) { return new TemplateConfiguration( - gameType, TemplateCatalog.Mode.DRAFT, teamCount, teamSize, null, pickBanTime, null, - null, strategy ); } public static TemplateConfiguration from( - TemplateCatalog.GameType gameType, TemplateCatalog.Mode mode, int teamCount, int teamSize, Integer budget, int pickBanTime, Integer minBidUnit, - Integer positionLimit, TemplateCatalog.DraftOrderStrategy draftOrderStrategy ) { return switch (mode) { @@ -158,7 +133,7 @@ public static TemplateConfiguration from( if (minBidUnit == null) { throw new IllegalArgumentException("경매 템플릿에는 최소 입찰 단위가 필요합니다"); } - yield auction(gameType, teamCount, teamSize, budget, pickBanTime, minBidUnit, positionLimit); + yield auction(teamCount, teamSize, budget, pickBanTime, minBidUnit); } case DRAFT -> { if (budget != null) { @@ -167,13 +142,10 @@ public static TemplateConfiguration from( if (minBidUnit != null) { throw new IllegalArgumentException("드래프트 템플릿에는 최소 입찰 단위를 지정할 수 없습니다"); } - if (positionLimit != null) { - throw new IllegalArgumentException("드래프트 템플릿에는 포지션 제한을 지정할 수 없습니다"); - } if (draftOrderStrategy == null) { throw new IllegalArgumentException("드래프트 템플릿에는 순서 전략이 필요합니다"); } - yield draft(gameType, teamCount, teamSize, pickBanTime, draftOrderStrategy); + yield draft(teamCount, teamSize, pickBanTime, draftOrderStrategy); } }; } diff --git a/src/main/java/com/naminhyeok/fantazzk/template/domain/TemplatePlayer.java b/src/main/java/com/naminhyeok/fantazzk/template/domain/TemplatePlayer.java index 959006c8..2725dfa9 100644 --- a/src/main/java/com/naminhyeok/fantazzk/template/domain/TemplatePlayer.java +++ b/src/main/java/com/naminhyeok/fantazzk/template/domain/TemplatePlayer.java @@ -17,12 +17,9 @@ public TemplatePlayer(String name, String position, int displayOrder) { if (name == null || name.isBlank()) { throw new IllegalArgumentException("선수 이름은 비어 있을 수 없습니다"); } - if (position == null || position.isBlank()) { - throw new IllegalArgumentException("선수 포지션은 비어 있을 수 없습니다"); - } this.name = name.trim(); - this.position = position.trim().toUpperCase(); + this.position = position; this.displayOrder = displayOrder; } diff --git a/src/main/java/com/naminhyeok/fantazzk/template/query/TemplateDetailResponse.java b/src/main/java/com/naminhyeok/fantazzk/template/query/TemplateDetailResponse.java index b02cf887..d767c36a 100644 --- a/src/main/java/com/naminhyeok/fantazzk/template/query/TemplateDetailResponse.java +++ b/src/main/java/com/naminhyeok/fantazzk/template/query/TemplateDetailResponse.java @@ -11,8 +11,8 @@ public record TemplateDetailResponse( String id, @Schema(description = "템플릿 이름", example = "LOL 2인 드래프트") String name, - @Schema(description = "게임 타입", example = "LEAGUE_OF_LEGENDS") - TemplateCatalog.GameType gameType, + @Schema(description = "FE가 관리하는 게임 타입 메타데이터", example = "LEAGUE_OF_LEGENDS", nullable = true) + String gameType, @Schema(description = "게임 모드", example = "DRAFT") TemplateCatalog.Mode mode, @Schema(description = "팀 수", example = "2") @@ -25,8 +25,6 @@ public record TemplateDetailResponse( Integer pickBanTime, @Schema(description = "최소 입찰 증가 단위", example = "10", nullable = true) Integer minBidUnit, - @Schema(description = "동일 포지션 최대 보유 인원", example = "1", nullable = true) - Integer positionLimit, @Schema(description = "드래프트 순서 전략", example = "SNAKE", nullable = true) TemplateCatalog.DraftOrderStrategy draftOrderStrategy, @Schema(description = "선수 풀 목록") @@ -48,7 +46,6 @@ public static TemplateDetailResponse from(TemplateDetail detail) { template.getBudget(), template.getPickBanTime(), template.getMinBidUnit(), - template.getPositionLimit(), template.getDraftOrderStrategy(), detail.players().stream().map(TemplatePlayerResponse::from).toList() ); diff --git a/src/main/java/com/naminhyeok/fantazzk/template/query/TemplatePlayerResponse.java b/src/main/java/com/naminhyeok/fantazzk/template/query/TemplatePlayerResponse.java index 36ea4908..4ca2d1c2 100644 --- a/src/main/java/com/naminhyeok/fantazzk/template/query/TemplatePlayerResponse.java +++ b/src/main/java/com/naminhyeok/fantazzk/template/query/TemplatePlayerResponse.java @@ -7,7 +7,7 @@ public record TemplatePlayerResponse( @Schema(description = "선수 이름", example = "선수1") String name, - @Schema(description = "포지션 코드", example = "TOP") + @Schema(description = "FE가 관리하는 선수 포지션 메타데이터", example = "TOP", nullable = true) String position, @Schema(description = "화면 노출 순서", example = "0") int displayOrder diff --git a/src/main/java/com/naminhyeok/fantazzk/template/query/TemplateSummaryResponse.java b/src/main/java/com/naminhyeok/fantazzk/template/query/TemplateSummaryResponse.java index d2503e50..deb7842c 100644 --- a/src/main/java/com/naminhyeok/fantazzk/template/query/TemplateSummaryResponse.java +++ b/src/main/java/com/naminhyeok/fantazzk/template/query/TemplateSummaryResponse.java @@ -6,7 +6,7 @@ public record TemplateSummaryResponse( String id, String name, - TemplateCatalog.GameType gameType, + String gameType, TemplateCatalog.Mode mode, int teamCount, int teamSize diff --git a/src/main/java/com/naminhyeok/fantazzk/template/web/TemplateApiController.java b/src/main/java/com/naminhyeok/fantazzk/template/web/TemplateApiController.java index 8a912343..c3e0bef3 100644 --- a/src/main/java/com/naminhyeok/fantazzk/template/web/TemplateApiController.java +++ b/src/main/java/com/naminhyeok/fantazzk/template/web/TemplateApiController.java @@ -5,9 +5,7 @@ import com.naminhyeok.fantazzk.template.application.CreateTemplate; import com.naminhyeok.fantazzk.template.domain.TemplateId; import com.naminhyeok.fantazzk.template.query.FindTemplates; -import com.naminhyeok.fantazzk.template.query.TemplateDetail; import com.naminhyeok.fantazzk.template.query.TemplateDetailResponse; -import com.naminhyeok.fantazzk.template.query.TemplateSummaryResponse; import com.naminhyeok.fantazzk.template.web.request.CreateTemplateRequest; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -86,7 +84,7 @@ ApiResponse getById( examples = @ExampleObject(value = OpenApiDocumentation.TEMPLATE_LIST_SUCCESS_EXAMPLE) ) ) - ApiResponse> list() { - return ApiResponse.success(findTemplates.list().stream().map(TemplateDetail::template).map(TemplateSummaryResponse::from).toList()); + ApiResponse> list() { + return ApiResponse.success(findTemplates.list().stream().map(TemplateDetailResponse::from).toList()); } } diff --git a/src/main/java/com/naminhyeok/fantazzk/template/web/request/CreateTemplateRequest.java b/src/main/java/com/naminhyeok/fantazzk/template/web/request/CreateTemplateRequest.java index 8bb2c157..ad7ed3df 100644 --- a/src/main/java/com/naminhyeok/fantazzk/template/web/request/CreateTemplateRequest.java +++ b/src/main/java/com/naminhyeok/fantazzk/template/web/request/CreateTemplateRequest.java @@ -8,7 +8,6 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Positive; import java.util.List; import java.util.stream.IntStream; @@ -17,10 +16,10 @@ public record CreateTemplateRequest( @Schema(description = "템플릿 이름", example = "LOL 2인 드래프트") @NotBlank(message = "템플릿 이름은 비어 있을 수 없습니다") String name, - @Schema(description = "게임 타입", example = "LEAGUE_OF_LEGENDS") - @NotNull(message = "게임 타입은 필수입니다") TemplateCatalog.GameType gameType, + @Schema(description = "FE가 관리하는 게임 타입 메타데이터", example = "LEAGUE_OF_LEGENDS", nullable = true) + String gameType, @Schema(description = "템플릿 모드", example = "DRAFT") - @NotNull(message = "템플릿 모드는 필수입니다") TemplateCatalog.Mode mode, + @jakarta.validation.constraints.NotNull(message = "템플릿 모드는 필수입니다") TemplateCatalog.Mode mode, @Schema(description = "팀 수", example = "2") @Positive(message = "팀 수는 1 이상이어야 합니다") int teamCount, @Schema(description = "팀 전체 크기. 실제로 뽑아야 하는 선수 수는 `teamSize - 1` 입니다.", example = "3") @@ -31,8 +30,6 @@ public record CreateTemplateRequest( Integer budget, @Schema(description = "경매 모드에서만 사용되는 최소 입찰 증가 단위", example = "10", nullable = true) Integer minBidUnit, - @Schema(description = "경매 모드에서만 사용되는 동일 포지션 최대 보유 인원", example = "1", nullable = true) - Integer positionLimit, @Schema(description = "드래프트 모드에서만 사용되는 라운드 순서 전략", example = "SNAKE", nullable = true) TemplateCatalog.DraftOrderStrategy draftOrderStrategy, @Schema(description = "선수 풀 목록. 길이는 정확히 `teamCount * (teamSize - 1)` 이어야 합니다.") @@ -42,8 +39,8 @@ public record CreateTemplateRequest( record PlayerRequest( @Schema(description = "선수 이름", example = "선수1") @NotBlank(message = "선수 이름은 비어 있을 수 없습니다") String name, - @Schema(description = "게임 타입에 맞는 포지션 코드", example = "TOP") - @NotBlank(message = "선수 포지션은 비어 있을 수 없습니다") String position + @Schema(description = "FE가 관리하는 선수 포지션 메타데이터", example = "TOP", nullable = true) + String position ) { } @@ -67,7 +64,6 @@ public CreateTemplateCommand toCommand() { budget, pickBanTime, minBidUnit, - positionLimit, toPlayers() ); } @@ -78,9 +74,6 @@ public CreateTemplateCommand toCommand() { if (minBidUnit != null) { throw CoreException.of(TemplateErrorType.TEMPLATE_DRAFT_MIN_BID_UNIT_NOT_ALLOWED); } - if (positionLimit != null) { - throw CoreException.of(TemplateErrorType.TEMPLATE_DRAFT_POSITION_LIMIT_NOT_ALLOWED); - } if (draftOrderStrategy == null) { throw CoreException.of(TemplateErrorType.TEMPLATE_DRAFT_ORDER_STRATEGY_REQUIRED); } diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index 1870d7b3..f9cdead9 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -151,3 +151,14 @@ databaseChangeLog: path: db/changelog/db.changelog-room-game-cleanup.sql splitStatements: true stripComments: false + - changeSet: + id: 14-metadata-demotion + author: codex + changes: + - sqlFile: + dbms: h2,postgresql + encoding: UTF-8 + endDelimiter: ; + path: db/changelog/db.changelog-metadata-demotion.sql + splitStatements: true + stripComments: false diff --git a/src/main/resources/db/changelog/db.changelog-metadata-demotion.sql b/src/main/resources/db/changelog/db.changelog-metadata-demotion.sql new file mode 100644 index 00000000..ff9f5d05 --- /dev/null +++ b/src/main/resources/db/changelog/db.changelog-metadata-demotion.sql @@ -0,0 +1,12 @@ +ALTER TABLE template ALTER COLUMN game_type DROP NOT NULL; +ALTER TABLE template DROP COLUMN position_limit; + +ALTER TABLE template_player ALTER COLUMN position DROP NOT NULL; + +ALTER TABLE rooms ADD COLUMN game_type VARCHAR(255); +ALTER TABLE rooms DROP COLUMN position_limit; + +ALTER TABLE games ADD COLUMN game_type VARCHAR(255); +ALTER TABLE games DROP COLUMN position_limit; + +ALTER TABLE game_player ALTER COLUMN position DROP NOT NULL; diff --git a/src/main/resources/db/changelog/db.changelog-room-game-cleanup.sql b/src/main/resources/db/changelog/db.changelog-room-game-cleanup.sql index 7d380d5b..18caa93d 100644 --- a/src/main/resources/db/changelog/db.changelog-room-game-cleanup.sql +++ b/src/main/resources/db/changelog/db.changelog-room-game-cleanup.sql @@ -116,7 +116,7 @@ SELECT player_rows.player_pool_order, player_rows.player_id, player_rows.name, - player_rows.position, + COALESCE(player_rows.position, ''), player_rows.display_order FROM ( SELECT diff --git a/src/test/java/com/naminhyeok/fantazzk/room/application/CreateRoomTest.java b/src/test/java/com/naminhyeok/fantazzk/room/application/CreateRoomTest.java index 9a9e5270..575a944c 100644 --- a/src/test/java/com/naminhyeok/fantazzk/room/application/CreateRoomTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/room/application/CreateRoomTest.java @@ -175,13 +175,13 @@ private static final class StubTemplateCatalog implements TemplateCatalog { @Override public TemplateBlueprint getTemplate(UUID templateId) { return new TemplateBlueprint( + "LEAGUE_OF_LEGENDS", Mode.AUCTION, 2, 2, 300, 45, 10, - 1, null, List.of( new PlayerBlueprint("선수1", "TOP", 0), diff --git a/src/test/java/com/naminhyeok/fantazzk/room/application/RoomRealtimePublishingTest.java b/src/test/java/com/naminhyeok/fantazzk/room/application/RoomRealtimePublishingTest.java index 8042b7ce..7b028508 100644 --- a/src/test/java/com/naminhyeok/fantazzk/room/application/RoomRealtimePublishingTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/room/application/RoomRealtimePublishingTest.java @@ -271,6 +271,7 @@ private static Room waitingAuctionRoom() { "호스트", HOST_ACTION_TOKEN, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, @@ -315,6 +316,7 @@ private static Room waitingDraftRoomForPositionChange() { "호스트", HOST_ACTION_TOKEN, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.DRAFT, 2, 2, @@ -340,6 +342,7 @@ private static Game gameFor(Room room) { room.getCode(), room.getStartedGameId(), room.getStartedAt(), + room.getGameType(), room.getMode(), room.getMode() == RoomMode.AUCTION ? GameRules.auction( @@ -347,8 +350,7 @@ private static Game gameFor(Room room) { room.getTeamSize(), room.getBudget(), room.getPickBanTime(), - room.getMinBidUnit(), - room.getPositionLimit() + room.getMinBidUnit() ) : GameRules.draft( room.getTeamCount(), diff --git a/src/test/java/com/naminhyeok/fantazzk/room/application/StartedGameContextLoaderTest.java b/src/test/java/com/naminhyeok/fantazzk/room/application/StartedGameContextLoaderTest.java index 787df88a..fda1ffed 100644 --- a/src/test/java/com/naminhyeok/fantazzk/room/application/StartedGameContextLoaderTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/room/application/StartedGameContextLoaderTest.java @@ -103,13 +103,13 @@ private Room startedAuctionRoom() { "호스트", "host-action-token", new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, 300, 45, 10, - 1, null, List.of( new RoomTemplateSpec.Player(new RoomPlayerId(0), "선수1", "TOP", 0), @@ -130,8 +130,9 @@ private Game startedGameOf(Room room) { room.getCode(), room.getStartedGameId(), room.getStartedAt(), + room.getGameType(), room.getMode(), - GameRules.auction(room.getTeamCount(), room.getTeamSize(), room.getBudget(), room.getPickBanTime(), room.getMinBidUnit(), room.getPositionLimit()), + GameRules.auction(room.getTeamCount(), room.getTeamSize(), room.getBudget(), room.getPickBanTime(), room.getMinBidUnit()), List.of( GameParticipant.auction(new TeamLeaderId("host-1"), "호스트", 300), GameParticipant.auction(new TeamLeaderId("guest-1"), "게스트", 300) diff --git a/src/test/java/com/naminhyeok/fantazzk/room/domain/AuctionGameTest.java b/src/test/java/com/naminhyeok/fantazzk/room/domain/AuctionGameTest.java index bca8c8c4..749e7748 100644 --- a/src/test/java/com/naminhyeok/fantazzk/room/domain/AuctionGameTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/room/domain/AuctionGameTest.java @@ -114,8 +114,9 @@ private AuctionGame startedAuctionGame() { new GameId(UUID.fromString("00000000-0000-0000-0000-000000000101")), new RoomId(UUID.fromString("00000000-0000-0000-0000-000000000001")), "ROOM01", + "LEAGUE_OF_LEGENDS", STARTED_AT, - GameRules.auction(2, 2, 300, PICK_BAN_TIME, MIN_BID_UNIT, null), + GameRules.auction(2, 2, 300, PICK_BAN_TIME, MIN_BID_UNIT), List.of( GameParticipant.auction(HOST_ID, "호스트", 300), GameParticipant.auction(GUEST_ID, "게스트", 300) @@ -133,8 +134,9 @@ private AuctionGame startedAuctionGameWithTwoPlayers() { new GameId(UUID.fromString("00000000-0000-0000-0000-000000000102")), new RoomId(UUID.fromString("00000000-0000-0000-0000-000000000002")), "ROOM02", + "LEAGUE_OF_LEGENDS", STARTED_AT, - GameRules.auction(2, 2, 300, PICK_BAN_TIME, MIN_BID_UNIT, null), + GameRules.auction(2, 2, 300, PICK_BAN_TIME, MIN_BID_UNIT), List.of( GameParticipant.auction(HOST_ID, "호스트", 300), GameParticipant.auction(GUEST_ID, "게스트", 300) diff --git a/src/test/java/com/naminhyeok/fantazzk/room/domain/DraftGameTest.java b/src/test/java/com/naminhyeok/fantazzk/room/domain/DraftGameTest.java index 4a0b7849..3d9ba34d 100644 --- a/src/test/java/com/naminhyeok/fantazzk/room/domain/DraftGameTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/room/domain/DraftGameTest.java @@ -124,6 +124,7 @@ private DraftGame startedDraftGame( new GameId(UUID.fromString("00000000-0000-0000-0000-000000000101")), new RoomId(UUID.fromString("00000000-0000-0000-0000-000000000001")), "ROOM01", + "LEAGUE_OF_LEGENDS", STARTED_AT, GameRules.draft(2, teamSize, 30, draftOrderStrategy), List.of( diff --git a/src/test/java/com/naminhyeok/fantazzk/room/domain/GameCapabilitySeamTest.java b/src/test/java/com/naminhyeok/fantazzk/room/domain/GameCapabilitySeamTest.java index 9dde82d8..38b685be 100644 --- a/src/test/java/com/naminhyeok/fantazzk/room/domain/GameCapabilitySeamTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/room/domain/GameCapabilitySeamTest.java @@ -14,17 +14,16 @@ class GameCapabilitySeamTest { @Test void 경매_규칙은_auction_seam으로_드러난다() { - GameRules rules = GameRules.auction(2, 2, 300, 45, 10, 1); + GameRules rules = GameRules.auction(2, 2, 300, 45, 10); assertThat(rules.mode()).isEqualTo(RoomMode.AUCTION); assertThat(rules.auctionRules()) .extracting( GameRules.AuctionRules::budget, GameRules.AuctionRules::pickBanTime, - GameRules.AuctionRules::minBidUnit, - GameRules.AuctionRules::positionLimit + GameRules.AuctionRules::minBidUnit ) - .containsExactly(300, 45, 10, 1); + .containsExactly(300, 45, 10); assertThatThrownBy(rules::draftRules).isInstanceOf(IllegalStateException.class); } diff --git a/src/test/java/com/naminhyeok/fantazzk/room/domain/GameFactoryTest.java b/src/test/java/com/naminhyeok/fantazzk/room/domain/GameFactoryTest.java index 9a6afcd3..a92e761e 100644 --- a/src/test/java/com/naminhyeok/fantazzk/room/domain/GameFactoryTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/room/domain/GameFactoryTest.java @@ -35,8 +35,9 @@ class GameFactoryTest { "ROOM01", new GameId(UUID.fromString("00000000-0000-0000-0000-000000000101")), STARTED_AT, + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, - GameRules.auction(2, 2, 300, 45, 10, 1), + GameRules.auction(2, 2, 300, 45, 10), List.of( GameParticipant.auction(new TeamLeaderId("host-1"), "호스트", 300), GameParticipant.auction(new TeamLeaderId("guest-1"), "게스트", 300) @@ -53,6 +54,7 @@ class GameFactoryTest { assertThat(created.getId()).isEqualTo(snapshot.gameId()); assertThat(created.getRoomId()).isEqualTo(snapshot.roomId()); assertThat(created.getRoomCode()).isEqualTo(snapshot.roomCode()); + assertThat(created.getGameType()).isEqualTo(snapshot.gameType()); assertThat(created.getStatus()).isEqualTo(GameStatus.IN_PROGRESS); assertThat(created.getStartedAt()).isEqualTo(snapshot.startedAt()); assertThat(created.getRules()).isEqualTo(snapshot.rules()); @@ -71,6 +73,7 @@ class GameFactoryTest { "ROOM02", new GameId(UUID.fromString("00000000-0000-0000-0000-000000000102")), STARTED_AT, + "LEAGUE_OF_LEGENDS", RoomMode.DRAFT, GameRules.draft(2, 2, 30, DraftOrderStrategy.SNAKE), List.of( @@ -89,6 +92,7 @@ class GameFactoryTest { assertThat(created.getId()).isEqualTo(snapshot.gameId()); assertThat(created.getRoomId()).isEqualTo(snapshot.roomId()); assertThat(created.getRoomCode()).isEqualTo(snapshot.roomCode()); + assertThat(created.getGameType()).isEqualTo(snapshot.gameType()); assertThat(created.getStatus()).isEqualTo(GameStatus.IN_PROGRESS); assertThat(created.getStartedAt()).isEqualTo(snapshot.startedAt()); assertThat(created.getRules()).isEqualTo(snapshot.rules()); diff --git a/src/test/java/com/naminhyeok/fantazzk/room/domain/RoomAggregateTest.java b/src/test/java/com/naminhyeok/fantazzk/room/domain/RoomAggregateTest.java index 9310d493..b2492ad4 100644 --- a/src/test/java/com/naminhyeok/fantazzk/room/domain/RoomAggregateTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/room/domain/RoomAggregateTest.java @@ -44,6 +44,7 @@ class RoomAggregateTest { " 호스트 ", HOST_ACTION_TOKEN, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 3, @@ -112,6 +113,7 @@ class RoomAggregateTest { "Faker", HOST_ACTION_TOKEN, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, @@ -205,6 +207,7 @@ class RoomAggregateTest { "호스트", HOST_ACTION_TOKEN, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 1, 2, @@ -243,6 +246,7 @@ class 시작 { assertThat(snapshot.roomCode()).isEqualTo(room.getCode()); assertThat(snapshot.gameId()).isEqualTo(gameId); assertThat(snapshot.startedAt()).isEqualTo(STARTED_AT); + assertThat(snapshot.gameType()).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(snapshot.gameMode()).isEqualTo(room.getMode()); assertThat(snapshot.rules()) .isEqualTo( @@ -251,8 +255,7 @@ class 시작 { room.getTeamSize(), room.getBudget(), room.getPickBanTime(), - room.getMinBidUnit(), - room.getPositionLimit() + room.getMinBidUnit() ) ); assertThat(snapshot.participants()) @@ -351,6 +354,7 @@ private static Room auctionWaitingRoom(Instant createdAt) { "호스트", HOST_ACTION_TOKEN, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, @@ -390,6 +394,7 @@ private static Room waitingDraftRoom(Instant createdAt) { "호스트", HOST_ACTION_TOKEN, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.DRAFT, 2, 2, diff --git a/src/test/java/com/naminhyeok/fantazzk/room/domain/RoomTemplateSpecTest.java b/src/test/java/com/naminhyeok/fantazzk/room/domain/RoomTemplateSpecTest.java index 3057386f..fe7a24ff 100644 --- a/src/test/java/com/naminhyeok/fantazzk/room/domain/RoomTemplateSpecTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/room/domain/RoomTemplateSpecTest.java @@ -18,13 +18,13 @@ class RoomTemplateSpecTest { RoomTemplateSpec spec = RoomTemplateSpec.from( new TemplateCatalog.TemplateBlueprint( + "LEAGUE_OF_LEGENDS", TemplateCatalog.Mode.DRAFT, 2, 3, null, 30, null, - null, TemplateCatalog.DraftOrderStrategy.SNAKE, List.of( new TemplateCatalog.PlayerBlueprint("선수1", "TOP", 0), @@ -35,6 +35,7 @@ class RoomTemplateSpecTest { ) ); + assertThat(spec.gameType()).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(spec.mode()).isEqualTo(RoomMode.DRAFT); assertThat(spec.teamCount()).isEqualTo(2); assertThat(spec.teamSize()).isEqualTo(3); @@ -55,6 +56,7 @@ class RoomTemplateSpecTest { assertThatThrownBy( () -> RoomTemplateSpec.from( new TemplateCatalog.TemplateBlueprint( + "LEAGUE_OF_LEGENDS", TemplateCatalog.Mode.DRAFT, 2, 2, @@ -62,7 +64,6 @@ class RoomTemplateSpecTest { 30, null, null, - null, List.of( new TemplateCatalog.PlayerBlueprint("선수1", "TOP", 0), new TemplateCatalog.PlayerBlueprint("선수2", "JUNGLE", 1) @@ -79,6 +80,7 @@ class RoomTemplateSpecTest { assertThatThrownBy( () -> RoomTemplateSpec.from( new TemplateCatalog.TemplateBlueprint( + "LEAGUE_OF_LEGENDS", TemplateCatalog.Mode.AUCTION, 2, 2, @@ -86,7 +88,6 @@ class RoomTemplateSpecTest { null, 10, null, - null, List.of( new TemplateCatalog.PlayerBlueprint("선수1", "TOP", 0), new TemplateCatalog.PlayerBlueprint("선수2", "JUNGLE", 1) diff --git a/src/test/java/com/naminhyeok/fantazzk/room/infrastructure/realtime/RoomRealtimeEventFactoryTest.java b/src/test/java/com/naminhyeok/fantazzk/room/infrastructure/realtime/RoomRealtimeEventFactoryTest.java index 48138800..d7a2f587 100644 --- a/src/test/java/com/naminhyeok/fantazzk/room/infrastructure/realtime/RoomRealtimeEventFactoryTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/room/infrastructure/realtime/RoomRealtimeEventFactoryTest.java @@ -82,6 +82,7 @@ private Room waitingAuctionRoom() { "호스트", "host-action-token", new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, @@ -111,8 +112,9 @@ private Game startedGameOf(Room room) { room.getCode(), room.getStartedGameId(), room.getStartedAt(), + room.getGameType(), room.getMode(), - GameRules.auction(room.getTeamCount(), room.getTeamSize(), room.getBudget(), room.getPickBanTime(), room.getMinBidUnit(), room.getPositionLimit()), + GameRules.auction(room.getTeamCount(), room.getTeamSize(), room.getBudget(), room.getPickBanTime(), room.getMinBidUnit()), List.of( GameParticipant.auction(new TeamLeaderId("host-1"), "호스트", 300), GameParticipant.auction(new TeamLeaderId("guest-1"), "게스트1", 300) diff --git a/src/test/java/com/naminhyeok/fantazzk/room/infrastructure/realtime/SupabaseRoomRealtimePublisherTest.java b/src/test/java/com/naminhyeok/fantazzk/room/infrastructure/realtime/SupabaseRoomRealtimePublisherTest.java index a4dbdf84..90bffcd6 100644 --- a/src/test/java/com/naminhyeok/fantazzk/room/infrastructure/realtime/SupabaseRoomRealtimePublisherTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/room/infrastructure/realtime/SupabaseRoomRealtimePublisherTest.java @@ -246,6 +246,7 @@ private static Room waitingAuctionRoom() { "호스트", "host-token", new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, diff --git a/src/test/java/com/naminhyeok/fantazzk/room/infrastructure/schedule/RoomAuctionDeadlineSchedulerTest.java b/src/test/java/com/naminhyeok/fantazzk/room/infrastructure/schedule/RoomAuctionDeadlineSchedulerTest.java index 8a10dc4f..7d4a44f8 100644 --- a/src/test/java/com/naminhyeok/fantazzk/room/infrastructure/schedule/RoomAuctionDeadlineSchedulerTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/room/infrastructure/schedule/RoomAuctionDeadlineSchedulerTest.java @@ -209,6 +209,7 @@ private static StartedAuctionContext auctionRoomWithDeadline(String code, Instan "호스트", "host-token-" + code, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, diff --git a/src/test/java/com/naminhyeok/fantazzk/room/support/RoomApiTestFixtures.java b/src/test/java/com/naminhyeok/fantazzk/room/support/RoomApiTestFixtures.java index fd7f930e..ff8758a9 100644 --- a/src/test/java/com/naminhyeok/fantazzk/room/support/RoomApiTestFixtures.java +++ b/src/test/java/com/naminhyeok/fantazzk/room/support/RoomApiTestFixtures.java @@ -42,6 +42,7 @@ public static Room waitingAuctionRoom(String code, Instant createdAt) { "호스트", HOST_TOKEN, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 2, @@ -76,6 +77,7 @@ public static Room waitingDraftRoom(String code, Instant createdAt) { "호스트", HOST_TOKEN, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.DRAFT, 2, 2, @@ -118,6 +120,7 @@ public static StartedRoomSnapshot inProgressAuctionDetails() { "호스트", HOST_TOKEN, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.AUCTION, 2, 3, @@ -154,6 +157,7 @@ public static StartedRoomSnapshot inProgressDraftDetails() { "호스트", HOST_TOKEN, new RoomTemplateSpec( + "LEAGUE_OF_LEGENDS", RoomMode.DRAFT, 2, 3, @@ -186,14 +190,14 @@ private static AuctionGame startedAuctionGame(Room room) { room.getCode(), room.getStartedGameId(), CREATED_AT, + room.getGameType(), room.getMode(), GameRules.auction( room.getTeamCount(), room.getTeamSize(), room.getBudget(), room.getPickBanTime(), - room.getMinBidUnit(), - room.getPositionLimit() + room.getMinBidUnit() ), room.getLeaders().stream() .map(leader -> room.getMode() == RoomMode.AUCTION diff --git a/src/test/java/com/naminhyeok/fantazzk/template/application/CreateTemplateTest.java b/src/test/java/com/naminhyeok/fantazzk/template/application/CreateTemplateTest.java index 5023fa00..475e6c25 100644 --- a/src/test/java/com/naminhyeok/fantazzk/template/application/CreateTemplateTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/template/application/CreateTemplateTest.java @@ -30,13 +30,12 @@ class CreateTemplateTest { cut.create( new CreateTemplateCommand.Auction( "경매전", - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, + "LEAGUE_OF_LEGENDS", 2, 2, 500, 45, 10, - 1, List.of( new CreateTemplateCommand.Player("선수A", "TOP", 0), new CreateTemplateCommand.Player("선수B", "JUNGLE", 1) @@ -45,8 +44,9 @@ class CreateTemplateTest { ); assertThat(template.getName()).isEqualTo("경매전"); + assertThat(template.getGameType()).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(template.getConfiguration()) - .isEqualTo(TemplateConfiguration.auction(TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, 2, 2, 500, 45, 10, 1)); + .isEqualTo(TemplateConfiguration.auction(2, 2, 500, 45, 10)); assertThat(template.getPlayers()) .extracting(TemplatePlayer::displayOrder, TemplatePlayer::name, TemplatePlayer::position) .containsExactly( @@ -65,7 +65,7 @@ class CreateTemplateTest { cut.create( new CreateTemplateCommand.Draft( "드래프트전", - TemplateCatalog.GameType.OVERWATCH_2, + "OVERWATCH_2", 2, 2, 30, @@ -78,7 +78,8 @@ class CreateTemplateTest { ); assertThat(template.getConfiguration()) - .isEqualTo(TemplateConfiguration.draft(TemplateCatalog.GameType.OVERWATCH_2, 2, 2, 30, TemplateCatalog.DraftOrderStrategy.SNAKE)); + .isEqualTo(TemplateConfiguration.draft(2, 2, 30, TemplateCatalog.DraftOrderStrategy.SNAKE)); + assertThat(template.getGameType()).isEqualTo("OVERWATCH_2"); assertThat(template.getBudget()).isNull(); } @@ -90,13 +91,12 @@ class CreateTemplateTest { cut.create( new CreateTemplateCommand.Auction( "실패", - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, + "LEAGUE_OF_LEGENDS", 2, 2, 300, 45, 10, - 1, List.of(new CreateTemplateCommand.Player("선수1", "TOP", 0)) ) ) diff --git a/src/test/java/com/naminhyeok/fantazzk/template/domain/TemplateAggregateTest.java b/src/test/java/com/naminhyeok/fantazzk/template/domain/TemplateAggregateTest.java index 0e48d1a7..3d574d64 100644 --- a/src/test/java/com/naminhyeok/fantazzk/template/domain/TemplateAggregateTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/template/domain/TemplateAggregateTest.java @@ -12,6 +12,31 @@ import org.junit.jupiter.api.Test; class TemplateAggregateTest { + @Test + void 메타데이터인_gameType과_position은_비어있어도_보관한다() { + Template template = + Template.createDraft( + "메타데이터 테스트", + null, + 2, + 2, + 30, + TemplateCatalog.DraftOrderStrategy.FIXED, + List.of( + new TemplatePlayer("선수1", "", 0), + new TemplatePlayer("선수2", null, 1) + ) + ); + + assertThat(template.getGameType()).isNull(); + assertThat(template.getPlayers()) + .extracting(TemplatePlayer::name, TemplatePlayer::position) + .containsExactly( + tuple("선수1", ""), + tuple("선수2", null) + ); + } + @Nested class 경매_템플릿_생성 { @Test @@ -19,13 +44,12 @@ class 경매_템플릿_생성 { Template template = Template.createAuction( "주말 경매전", - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, + "LEAGUE_OF_LEGENDS", 2, 2, 300, 45, 10, - 1, List.of( new TemplatePlayer("선수2", "JUNGLE", 0), new TemplatePlayer("선수1", "TOP", 1) @@ -45,13 +69,12 @@ class 경매_템플릿_생성 { assertThatThrownBy(() -> Template.createAuction( "주말 경매전", - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, + "LEAGUE_OF_LEGENDS", 2, 2, 300, 45, 10, - 1, List.of(new TemplatePlayer("선수1", "TOP", 0)) ) ) @@ -59,40 +82,17 @@ class 경매_템플릿_생성 { .hasMessage("선수 수는 정확히 2명이어야 합니다"); } - @Test - void 선택한_게임_타입에서_지원하지_않는_포지션이면_거부한다() { - assertThatThrownBy(() -> - Template.createAuction( - "주말 경매전", - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, - 2, - 2, - 300, - 45, - 10, - 1, - List.of( - new TemplatePlayer("선수1", "TANK", 0), - new TemplatePlayer("선수2", "SUPPORT", 1) - ) - ) - ) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("LEAGUE_OF_LEGENDS 게임은 TANK 포지션을 지원하지 않습니다"); - } - @Test void 경매_설정을_flat_필드로_노출한다() { Template template = Template.createAuction( "경매전", - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, + "LEAGUE_OF_LEGENDS", 2, 3, 300, 45, 10, - 2, List.of( new TemplatePlayer("선수1", "TOP", 0), new TemplatePlayer("선수2", "JUNGLE", 1), @@ -102,14 +102,13 @@ class 경매_템플릿_생성 { ); assertThat(template.getName()).isEqualTo("경매전"); - assertThat(template.getGameType()).isEqualTo(TemplateCatalog.GameType.LEAGUE_OF_LEGENDS); + assertThat(template.getGameType()).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(template.getMode()).isEqualTo(TemplateCatalog.Mode.AUCTION); assertThat(template.getTeamCount()).isEqualTo(2); assertThat(template.getTeamSize()).isEqualTo(3); assertThat(template.getBudget()).isEqualTo(300); assertThat(template.getPickBanTime()).isEqualTo(45); assertThat(template.getMinBidUnit()).isEqualTo(10); - assertThat(template.getPositionLimit()).isEqualTo(2); assertThat(template.getDraftOrderStrategy()).isNull(); assertThat(template.getPicksPerTeam()).isEqualTo(2); } @@ -122,7 +121,7 @@ class 드래프트_템플릿_생성 { Template template = Template.createDraft( "사내 리그 드래프트", - TemplateCatalog.GameType.OVERWATCH_2, + "OVERWATCH_2", 2, 2, 30, @@ -133,12 +132,11 @@ class 드래프트_템플릿_생성 { ) ); - assertThat(template.getGameType()).isEqualTo(TemplateCatalog.GameType.OVERWATCH_2); + assertThat(template.getGameType()).isEqualTo("OVERWATCH_2"); assertThat(template.getMode()).isEqualTo(TemplateCatalog.Mode.DRAFT); assertThat(template.getBudget()).isNull(); assertThat(template.getPickBanTime()).isEqualTo(30); assertThat(template.getMinBidUnit()).isNull(); - assertThat(template.getPositionLimit()).isNull(); assertThat(template.getDraftOrderStrategy()).isEqualTo(TemplateCatalog.DraftOrderStrategy.FIXED); } } diff --git a/src/test/java/com/naminhyeok/fantazzk/template/domain/TemplateConfigurationTest.java b/src/test/java/com/naminhyeok/fantazzk/template/domain/TemplateConfigurationTest.java index 705d74dd..15813ad9 100644 --- a/src/test/java/com/naminhyeok/fantazzk/template/domain/TemplateConfigurationTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/template/domain/TemplateConfigurationTest.java @@ -4,32 +4,21 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.naminhyeok.fantazzk.template.TemplateCatalog; -import com.naminhyeok.fantazzk.template.domain.TemplateConfiguration; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; class TemplateConfigurationTest { - @Test - void 지원_게임_타입은_리그오브레전드와_오버워치2다() { - assertThat(TemplateCatalog.GameType.values()).containsExactly( - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, - TemplateCatalog.GameType.OVERWATCH_2 - ); - } - @Nested class 경매_설정 { @Test - void 게임타입과_픽밴시간_최소입찰단위_포지션제한을_노출한다() { + void 픽밴시간과_최소입찰단위를_노출한다() { TemplateConfiguration configuration = - TemplateConfiguration.auction(TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, 2, 3, 300, 45, 10, 2); + TemplateConfiguration.auction(2, 3, 300, 45, 10); - assertThat(configuration.getGameType()).isEqualTo(TemplateCatalog.GameType.LEAGUE_OF_LEGENDS); assertThat(configuration.getMode()).isEqualTo(TemplateCatalog.Mode.AUCTION); assertThat(configuration.getBudget()).isEqualTo(300); assertThat(configuration.getPickBanTime()).isEqualTo(45); assertThat(configuration.getMinBidUnit()).isEqualTo(10); - assertThat(configuration.getPositionLimit()).isEqualTo(2); assertThat(configuration.requiredPlayerCount()).isEqualTo(4); assertThat(configuration.getDraftOrderStrategy()).isNull(); } @@ -38,14 +27,12 @@ class 경매_설정 { void 예산이_필요하다() { assertThatThrownBy(() -> TemplateConfiguration.from( - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, TemplateCatalog.Mode.AUCTION, 2, 3, null, 45, 10, - 2, null ) ) @@ -57,14 +44,12 @@ class 경매_설정 { void 최소_입찰_단위가_필요하다() { assertThatThrownBy(() -> TemplateConfiguration.from( - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, TemplateCatalog.Mode.AUCTION, 2, 3, 300, 45, null, - 2, null ) ) @@ -76,14 +61,12 @@ class 경매_설정 { void 드래프트_순서_전략을_가질_수_없다() { assertThatThrownBy(() -> TemplateConfiguration.from( - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, TemplateCatalog.Mode.AUCTION, 2, 3, 300, 45, 10, - 2, TemplateCatalog.DraftOrderStrategy.SNAKE ) ) @@ -95,16 +78,14 @@ class 경매_설정 { @Nested class 드래프트_설정 { @Test - void 게임타입과_픽밴시간_순서전략과_필요한_선수_수를_노출한다() { + void 픽밴시간과_순서전략과_필요한_선수_수를_노출한다() { TemplateConfiguration configuration = - TemplateConfiguration.draft(TemplateCatalog.GameType.OVERWATCH_2, 2, 3, 30, TemplateCatalog.DraftOrderStrategy.SNAKE); + TemplateConfiguration.draft(2, 3, 30, TemplateCatalog.DraftOrderStrategy.SNAKE); - assertThat(configuration.getGameType()).isEqualTo(TemplateCatalog.GameType.OVERWATCH_2); assertThat(configuration.getMode()).isEqualTo(TemplateCatalog.Mode.DRAFT); assertThat(configuration.getBudget()).isNull(); assertThat(configuration.getPickBanTime()).isEqualTo(30); assertThat(configuration.getMinBidUnit()).isNull(); - assertThat(configuration.getPositionLimit()).isNull(); assertThat(configuration.getDraftOrderStrategy()).isEqualTo(TemplateCatalog.DraftOrderStrategy.SNAKE); assertThat(configuration.requiredPlayerCount()).isEqualTo(4); } @@ -113,14 +94,12 @@ class 드래프트_설정 { void 순서_전략이_필요하다() { assertThatThrownBy(() -> TemplateConfiguration.from( - TemplateCatalog.GameType.OVERWATCH_2, TemplateCatalog.Mode.DRAFT, 2, 3, null, 30, null, - null, null ) ) @@ -132,14 +111,12 @@ class 드래프트_설정 { void 예산을_가질_수_없다() { assertThatThrownBy(() -> TemplateConfiguration.from( - TemplateCatalog.GameType.OVERWATCH_2, TemplateCatalog.Mode.DRAFT, 2, 3, 300, 30, null, - null, TemplateCatalog.DraftOrderStrategy.SNAKE ) ) @@ -151,67 +128,46 @@ class 드래프트_설정 { void 최소_입찰_단위를_가질_수_없다() { assertThatThrownBy(() -> TemplateConfiguration.from( - TemplateCatalog.GameType.OVERWATCH_2, TemplateCatalog.Mode.DRAFT, 2, 3, null, 30, 10, - null, TemplateCatalog.DraftOrderStrategy.SNAKE ) ) .isInstanceOf(IllegalArgumentException.class) .hasMessage("드래프트 템플릿에는 최소 입찰 단위를 지정할 수 없습니다"); } - - @Test - void 포지션_제한을_가질_수_없다() { - assertThatThrownBy(() -> - TemplateConfiguration.from( - TemplateCatalog.GameType.OVERWATCH_2, - TemplateCatalog.Mode.DRAFT, - 2, - 3, - null, - 30, - null, - 2, - TemplateCatalog.DraftOrderStrategy.SNAKE - ) - ) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("드래프트 템플릿에는 포지션 제한을 지정할 수 없습니다"); - } } @Nested class 공통_검증 { @Test void 팀_수는_0보다_커야_한다() { - assertThatThrownBy(() -> TemplateConfiguration.auction(TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, 0, 2, 300, 45, 10, 2)) + assertThatThrownBy(() -> TemplateConfiguration.auction(0, 2, 300, 45, 10)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("팀 수는 0보다 커야 합니다"); } @Test void 팀_크기는_0보다_커야_한다() { - assertThatThrownBy(() -> TemplateConfiguration.draft(TemplateCatalog.GameType.OVERWATCH_2, 2, 0, 30, TemplateCatalog.DraftOrderStrategy.FIXED)) + assertThatThrownBy(() -> TemplateConfiguration.draft(2, 0, 30, TemplateCatalog.DraftOrderStrategy.FIXED)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("팀 크기는 0보다 커야 합니다"); } @Test void 예산은_0보다_커야_한다() { - assertThatThrownBy(() -> TemplateConfiguration.auction(TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, 2, 2, 0, 45, 10, 2)) + assertThatThrownBy(() -> TemplateConfiguration.auction(2, 2, 0, 45, 10)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("예산은 0보다 커야 합니다"); } @Test void 픽밴_시간은_0보다_커야_한다() { - assertThatThrownBy(() -> TemplateConfiguration.draft(TemplateCatalog.GameType.OVERWATCH_2, 2, 2, 0, TemplateCatalog.DraftOrderStrategy.FIXED)) + assertThatThrownBy(() -> TemplateConfiguration.draft(2, 2, 0, TemplateCatalog.DraftOrderStrategy.FIXED)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("픽밴 시간은 0보다 커야 합니다"); } diff --git a/src/test/java/com/naminhyeok/fantazzk/template/query/FindTemplatesTest.java b/src/test/java/com/naminhyeok/fantazzk/template/query/FindTemplatesTest.java index e7c73159..4ce8e6b6 100644 --- a/src/test/java/com/naminhyeok/fantazzk/template/query/FindTemplatesTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/template/query/FindTemplatesTest.java @@ -45,13 +45,12 @@ class FindTemplatesTest { templates.save( Template.createAuction( "첫째", - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, + "LEAGUE_OF_LEGENDS", 2, 2, 300, 45, 10, - 1, List.of( new TemplatePlayer("선수1", "TOP", 0), new TemplatePlayer("선수2", "JUNGLE", 1) @@ -61,7 +60,7 @@ class FindTemplatesTest { templates.save( Template.createDraft( "둘째", - TemplateCatalog.GameType.OVERWATCH_2, + "OVERWATCH_2", 2, 2, 30, @@ -84,13 +83,12 @@ class FindTemplatesTest { Template template = Template.createAuction( "첫째", - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, + "LEAGUE_OF_LEGENDS", 2, 2, 300, 45, 10, - 1, List.of( new TemplatePlayer("선수1", "TOP", 0), new TemplatePlayer("선수2", "JUNGLE", 1) @@ -102,10 +100,9 @@ class FindTemplatesTest { TemplateDetail detail = cut.getDetail(template.getId()); assertThat(detail.template().getId()).isEqualTo(template.getId()); - assertThat(detail.template().getGameType()).isEqualTo(TemplateCatalog.GameType.LEAGUE_OF_LEGENDS); + assertThat(detail.template().getGameType()).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(detail.template().getPickBanTime()).isEqualTo(45); assertThat(detail.template().getMinBidUnit()).isEqualTo(10); - assertThat(detail.template().getPositionLimit()).isEqualTo(1); assertThat(detail.players()) .extracting(TemplatePlayer::displayOrder, TemplatePlayer::name, TemplatePlayer::position) .containsExactly( @@ -120,13 +117,12 @@ class FindTemplatesTest { Template template = Template.createAuction( "첫째", - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, + "LEAGUE_OF_LEGENDS", 2, 2, 300, 45, 10, - 1, List.of( new TemplatePlayer("선수1", "TOP", 0), new TemplatePlayer("선수2", "JUNGLE", 1) @@ -138,9 +134,9 @@ class FindTemplatesTest { TemplateCatalog.TemplateBlueprint blueprint = catalog.getTemplate(template.getId().templateId()); + assertThat(blueprint.gameType()).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(blueprint.pickBanTime()).isEqualTo(45); assertThat(blueprint.minBidUnit()).isEqualTo(10); - assertThat(blueprint.positionLimit()).isEqualTo(1); assertThat(blueprint.players()) .extracting("playerIndex", "name", "position") .containsExactly( diff --git a/src/test/java/com/naminhyeok/fantazzk/template/query/TemplateResponseTest.java b/src/test/java/com/naminhyeok/fantazzk/template/query/TemplateResponseTest.java index 9586a1ba..0c445cfc 100644 --- a/src/test/java/com/naminhyeok/fantazzk/template/query/TemplateResponseTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/template/query/TemplateResponseTest.java @@ -8,7 +8,6 @@ import com.naminhyeok.fantazzk.template.domain.TemplatePlayer; import com.naminhyeok.fantazzk.template.query.TemplateDetailResponse; import com.naminhyeok.fantazzk.template.query.TemplatePlayerResponse; -import com.naminhyeok.fantazzk.template.query.TemplateSummaryResponse; import java.util.List; import org.junit.jupiter.api.Test; @@ -18,13 +17,12 @@ class TemplateResponseTest { Template template = Template.createAuction( "경매전", - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, + "LEAGUE_OF_LEGENDS", 2, 2, 300, 45, 10, - 1, List.of( new TemplatePlayer("선수1", "TOP", 0), new TemplatePlayer("선수2", "JUNGLE", 1) @@ -34,12 +32,11 @@ class TemplateResponseTest { TemplateDetailResponse response = TemplateDetailResponse.from(template); assertThat(response.name()).isEqualTo("경매전"); - assertThat(response.gameType()).isEqualTo(TemplateCatalog.GameType.LEAGUE_OF_LEGENDS); + assertThat(response.gameType()).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(response.mode()).isEqualTo(TemplateCatalog.Mode.AUCTION); assertThat(response.budget()).isEqualTo(300); assertThat(response.pickBanTime()).isEqualTo(45); assertThat(response.minBidUnit()).isEqualTo(10); - assertThat(response.positionLimit()).isEqualTo(1); assertThat(response.players()) .extracting(TemplatePlayerResponse::displayOrder, TemplatePlayerResponse::name, TemplatePlayerResponse::position) .containsExactly( @@ -53,7 +50,7 @@ class TemplateResponseTest { Template template = Template.createDraft( "드래프트전", - TemplateCatalog.GameType.OVERWATCH_2, + "OVERWATCH_2", 2, 2, 30, @@ -66,40 +63,40 @@ class TemplateResponseTest { TemplateDetailResponse response = TemplateDetailResponse.from(template); - assertThat(response.gameType()).isEqualTo(TemplateCatalog.GameType.OVERWATCH_2); + assertThat(response.gameType()).isEqualTo("OVERWATCH_2"); assertThat(response.mode()).isEqualTo(TemplateCatalog.Mode.DRAFT); assertThat(response.budget()).isNull(); assertThat(response.pickBanTime()).isEqualTo(30); assertThat(response.minBidUnit()).isNull(); - assertThat(response.positionLimit()).isNull(); assertThat(response.draftOrderStrategy()).isEqualTo(TemplateCatalog.DraftOrderStrategy.SNAKE); } @Test - void 템플릿_요약_응답은_목록에_필요한_필드만_노출한다() { + void 템플릿_목록_아이템은_카드에_필요한_메타데이터를_노출한다() { Template template = Template.createAuction( "경매전", - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, + "LEAGUE_OF_LEGENDS", 2, 2, 300, 45, 10, - 1, List.of( new TemplatePlayer("선수1", "TOP", 0), new TemplatePlayer("선수2", "JUNGLE", 1) ) ); - TemplateSummaryResponse response = TemplateSummaryResponse.from(template); + TemplateDetailResponse response = TemplateDetailResponse.from(template); assertThat(response.id()).isEqualTo(template.getId().templateId().toString()); assertThat(response.name()).isEqualTo("경매전"); - assertThat(response.gameType()).isEqualTo(TemplateCatalog.GameType.LEAGUE_OF_LEGENDS); + assertThat(response.gameType()).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(response.mode()).isEqualTo(TemplateCatalog.Mode.AUCTION); assertThat(response.teamCount()).isEqualTo(2); assertThat(response.teamSize()).isEqualTo(2); + assertThat(response.pickBanTime()).isEqualTo(45); + assertThat(response.players()).hasSize(2); } } diff --git a/src/test/java/com/naminhyeok/fantazzk/template/web/TemplateApiControllerWebMvcTest.java b/src/test/java/com/naminhyeok/fantazzk/template/web/TemplateApiControllerWebMvcTest.java index be991ccd..c9f0140f 100644 --- a/src/test/java/com/naminhyeok/fantazzk/template/web/TemplateApiControllerWebMvcTest.java +++ b/src/test/java/com/naminhyeok/fantazzk/template/web/TemplateApiControllerWebMvcTest.java @@ -45,7 +45,7 @@ class TemplateApiControllerWebMvcTest { private FindTemplates findTemplates; @Test - void list는_템플릿_요약_목록만_반환한다() throws Exception { + void list는_FE_카드에_필요한_메타데이터를_반환한다() throws Exception { Template template = auctionTemplate(); given(findTemplates.list()).willReturn(List.of(new TemplateDetail(template, template.getPlayers()))); @@ -56,9 +56,10 @@ class TemplateApiControllerWebMvcTest { assertThat(body.at("/resultType").asText()).isEqualTo("SUCCESS"); assertThat(body.at("/success/0/id").asText()).isEqualTo(template.getId().templateId().toString()); assertThat(body.at("/success/0/name").asText()).isEqualTo("경매전"); + assertThat(body.at("/success/0/gameType").asText()).isEqualTo("LEAGUE_OF_LEGENDS"); assertThat(body.at("/success/0/teamCount").asInt()).isEqualTo(2); - assertThat(body.at("/success/0/players").isMissingNode()).isTrue(); - assertThat(body.at("/success/0/pickBanTime").isMissingNode()).isTrue(); + assertThat(body.at("/success/0/pickBanTime").asInt()).isEqualTo(45); + assertThat(body.at("/success/0/players/0/name").asText()).isEqualTo("선수1"); } @Test @@ -96,7 +97,6 @@ class TemplateApiControllerWebMvcTest { "pickBanTime": 45, "budget": 300, "minBidUnit": 10, - "positionLimit": 1, "players": [ { "name": "선수1", "position": "TOP" }, { "name": "선수2", "position": "JUNGLE" } @@ -120,13 +120,12 @@ private MockMvcTester mockMvcTester() { private Template auctionTemplate() { return Template.createAuction( "경매전", - TemplateCatalog.GameType.LEAGUE_OF_LEGENDS, + "LEAGUE_OF_LEGENDS", 2, 2, 300, 45, 10, - 1, List.of( new TemplatePlayer("선수1", "TOP", 0), new TemplatePlayer("선수2", "JUNGLE", 1) @@ -137,7 +136,7 @@ private Template auctionTemplate() { private Template draftTemplate() { return Template.createDraft( "드래프트전", - TemplateCatalog.GameType.OVERWATCH_2, + "OVERWATCH_2", 2, 2, 30,