diff --git a/src/main/java/mafia/mafiatogether/config/exception/ErrorResponse.java b/src/main/java/mafia/mafiatogether/config/exception/ErrorResponse.java index 717e9718..5f9c4936 100644 --- a/src/main/java/mafia/mafiatogether/config/exception/ErrorResponse.java +++ b/src/main/java/mafia/mafiatogether/config/exception/ErrorResponse.java @@ -6,15 +6,16 @@ public record ErrorResponse( LocalDateTime localDateTime, + Integer errorCode, String message, List errorList ) { - static ErrorResponse create(final String message) { - return new ErrorResponse(LocalDateTime.now(), message, new ArrayList<>()); + static ErrorResponse create(final Integer errorCode, final String message) { + return new ErrorResponse(LocalDateTime.now(), errorCode, message, new ArrayList<>()); } - static ErrorResponse create(final String message, List errorList) { - return new ErrorResponse(LocalDateTime.now(), message, errorList); + static ErrorResponse create(final Integer errorCode, final String message, List errorList) { + return new ErrorResponse(LocalDateTime.now(), errorCode, message, errorList); } public record FieldErrorResponse(String field, String value, String message) { diff --git a/src/main/java/mafia/mafiatogether/config/exception/ExceptionCode.java b/src/main/java/mafia/mafiatogether/config/exception/ExceptionCode.java index d008d72e..7dda387b 100644 --- a/src/main/java/mafia/mafiatogether/config/exception/ExceptionCode.java +++ b/src/main/java/mafia/mafiatogether/config/exception/ExceptionCode.java @@ -6,6 +6,7 @@ @Getter @RequiredArgsConstructor public enum ExceptionCode { + UNEXPECTED_EXCEPTION(000, "예상치 못한 예외입니다."), INVALID_REQUEST(100, "잘못된 요청입니다."), INVALID_ROOM_INFORMATION(101, "방 구성이 잘 못 되었습니다."), diff --git a/src/main/java/mafia/mafiatogether/config/exception/GlobalExceptionHandler.java b/src/main/java/mafia/mafiatogether/config/exception/GlobalExceptionHandler.java index 20cf88c0..f5a89e91 100644 --- a/src/main/java/mafia/mafiatogether/config/exception/GlobalExceptionHandler.java +++ b/src/main/java/mafia/mafiatogether/config/exception/GlobalExceptionHandler.java @@ -21,6 +21,7 @@ public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) protected ResponseEntity Exception(Exception e) { final ErrorResponse errorResponse = ErrorResponse.create( + ExceptionCode.UNEXPECTED_EXCEPTION.getCode(), "예기치 않은 예외가 발생 했습니다." ); @@ -42,6 +43,7 @@ protected ResponseEntity BindException(BindException e) { } final ErrorResponse errorResponse = ErrorResponse.create( + ExceptionCode.INVALID_REQUEST.getCode(), "", errors ); @@ -50,9 +52,10 @@ protected ResponseEntity BindException(BindException e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse); } - @ExceptionHandler({RoomException.class, CitizenException.class, AuthException.class}) - protected ResponseEntity GlobalException(RuntimeException e) { + @ExceptionHandler(GlobalException.class) + protected ResponseEntity GlobalException(GlobalException e) { final ErrorResponse errorResponse = ErrorResponse.create( + e.getCodes(), e.getMessage() ); @@ -65,6 +68,7 @@ protected ResponseEntity HttpRequestMethodNotSupportedException( final HttpRequestMethodNotSupportedException e ) { final ErrorResponse errorResponse = ErrorResponse.create( + ExceptionCode.MISSING_AUTHENTICATION_HEADER.getCode(), "HTTP 메서드를 확인해 주세요" ); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse); @@ -75,6 +79,7 @@ protected ResponseEntity handleMissingServletRequestParameter( final MissingServletRequestParameterException e ) { final ErrorResponse errorResponse = ErrorResponse.create( + ExceptionCode.INVALID_CONTENT.getCode(), "요청 파라미터를 확인해 주세요" ); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse); diff --git a/src/main/java/mafia/mafiatogether/controller/ChatController.java b/src/main/java/mafia/mafiatogether/controller/ChatController.java index 0e4aa310..4a4d6a15 100644 --- a/src/main/java/mafia/mafiatogether/controller/ChatController.java +++ b/src/main/java/mafia/mafiatogether/controller/ChatController.java @@ -1,5 +1,6 @@ package mafia.mafiatogether.controller; +import jakarta.validation.Valid; import java.util.List; import lombok.RequiredArgsConstructor; import mafia.mafiatogether.service.ChatService; @@ -30,7 +31,7 @@ public ResponseEntity> findAllChat(@PlayerInfo PlayerInfoDto @PostMapping public ResponseEntity saveChat( @PlayerInfo PlayerInfoDto playerInfoDto, - @RequestBody ChatRequest request + @Valid @RequestBody ChatRequest request ) { chatService.saveChat(playerInfoDto.code(), playerInfoDto.name(), request); return ResponseEntity.status(HttpStatus.CREATED).build(); diff --git a/src/main/java/mafia/mafiatogether/domain/Room.java b/src/main/java/mafia/mafiatogether/domain/Room.java index 1c4a9d3b..e0771f13 100644 --- a/src/main/java/mafia/mafiatogether/domain/Room.java +++ b/src/main/java/mafia/mafiatogether/domain/Room.java @@ -7,6 +7,7 @@ import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; +import mafia.mafiatogether.config.exception.CitizenException; import mafia.mafiatogether.config.exception.ExceptionCode; import mafia.mafiatogether.config.exception.RoomException; import mafia.mafiatogether.domain.job.Job; @@ -51,7 +52,14 @@ public void modifyStatus(final StatusType statusType, final Clock clock) { this.status = status.getNextStatus(this, clock); } - public void joinPlayer(final Player player) { + public void joinPlayer(final String name) { + if (players.containsKey(name)) { + throw new RoomException(ExceptionCode.INVALID_NAMES); + } + if (players.size() >= roomInfo.getTotal()) { + throw new RoomException(ExceptionCode.ROOM_FULL); + } + final Player player = Player.create(name); if (master.equals(Player.NONE)) { master = player; } @@ -75,8 +83,12 @@ public Player getPlayer(final String name) { return players.get(name); } - public String executeSkill(final String name, final Player target) { - final Player player = players.get(name); + public String executeSkill(final String name, final String targetName) { + final Player player = getPlayer(name); + final Player target = getPlayer(targetName); + if (!target.isAlive()) { + throw new CitizenException(ExceptionCode.NOT_ALIVE_PLAYER); + } return player.getJob().applySkill(target, jobTarget); } @@ -122,7 +134,11 @@ public Boolean isMaster(final Player player) { return this.master.equals(player); } - public Integer getTotalPlayers(){ + public Integer getTotalPlayers() { return roomInfo.getTotal(); } + + public boolean validateStartStatus() { + return roomInfo.getTotal() == players.size(); + } } diff --git a/src/main/java/mafia/mafiatogether/domain/RoomInfo.java b/src/main/java/mafia/mafiatogether/domain/RoomInfo.java index 22392ed6..ef76194e 100644 --- a/src/main/java/mafia/mafiatogether/domain/RoomInfo.java +++ b/src/main/java/mafia/mafiatogether/domain/RoomInfo.java @@ -7,10 +7,12 @@ import java.util.Queue; import lombok.Getter; import lombok.RequiredArgsConstructor; +import mafia.mafiatogether.config.exception.ExceptionCode; +import mafia.mafiatogether.config.exception.RoomException; import mafia.mafiatogether.domain.job.Doctor; +import mafia.mafiatogether.domain.job.Job; import mafia.mafiatogether.domain.job.Mafia; import mafia.mafiatogether.domain.job.Police; -import mafia.mafiatogether.domain.job.Job; @Getter @RequiredArgsConstructor @@ -21,6 +23,13 @@ public class RoomInfo { private final int doctor; private final int police; + public static RoomInfo of(final int total, final int mafia, final int doctor, final int police) { + if (total / 2 < mafia || total < 3 || mafia == 0) { + throw new RoomException(ExceptionCode.INVALID_ROOM_INFORMATION); + } + return new RoomInfo(total, mafia, doctor, police); + } + public Queue getRandomJobQueue() { final List jobList = new ArrayList<>(); addTimes(new Mafia(), mafia, jobList); @@ -30,7 +39,7 @@ public Queue getRandomJobQueue() { return new LinkedList<>(jobList); } - private void addTimes(final Job job, int times, final List jobList){ + private void addTimes(final Job job, int times, final List jobList) { for (int i = 0; i < times; i++) { jobList.add(job); } diff --git a/src/main/java/mafia/mafiatogether/domain/job/JobTarget.java b/src/main/java/mafia/mafiatogether/domain/job/JobTarget.java index d7abf725..3b44994f 100644 --- a/src/main/java/mafia/mafiatogether/domain/job/JobTarget.java +++ b/src/main/java/mafia/mafiatogether/domain/job/JobTarget.java @@ -21,6 +21,9 @@ public void addTarget(final JobType jobType, final Player player) { } public Player getTarget(final JobType jobType) { + if (!targets.containsKey(jobType)){ + return Player.NONE; + } return targets.get(jobType); } diff --git a/src/main/java/mafia/mafiatogether/domain/status/WaitStatus.java b/src/main/java/mafia/mafiatogether/domain/status/WaitStatus.java index 4581e2e0..84240327 100644 --- a/src/main/java/mafia/mafiatogether/domain/status/WaitStatus.java +++ b/src/main/java/mafia/mafiatogether/domain/status/WaitStatus.java @@ -3,6 +3,8 @@ import java.sql.Timestamp; import java.time.Clock; import java.time.LocalDateTime; +import mafia.mafiatogether.config.exception.ExceptionCode; +import mafia.mafiatogether.config.exception.RoomException; import mafia.mafiatogether.domain.Room; public class WaitStatus extends Status { @@ -21,6 +23,9 @@ public static WaitStatus create(final Clock clock) { @Override public Status getNextStatus(final Room room, final Clock clock) { + if (!room.validateStartStatus()) { + throw new RoomException(ExceptionCode.NOT_ENOUGH_PLAYER); + } room.distributeRole(); return DayStatus.create(room.getPlayerCount(), clock); } diff --git a/src/main/java/mafia/mafiatogether/service/PlayerService.java b/src/main/java/mafia/mafiatogether/service/PlayerService.java index ffa9591c..eabced5e 100644 --- a/src/main/java/mafia/mafiatogether/service/PlayerService.java +++ b/src/main/java/mafia/mafiatogether/service/PlayerService.java @@ -4,10 +4,10 @@ import mafia.mafiatogether.domain.Player; import mafia.mafiatogether.domain.Room; import mafia.mafiatogether.domain.RoomManager; +import mafia.mafiatogether.service.dto.JobResponse; import mafia.mafiatogether.service.dto.MafiaTargetResponse; import mafia.mafiatogether.service.dto.PlayerExecuteAbilityRequest; import mafia.mafiatogether.service.dto.PlayerExecuteAbilityResponse; -import mafia.mafiatogether.service.dto.JobResponse; import org.springframework.stereotype.Service; @Service @@ -28,9 +28,8 @@ public PlayerExecuteAbilityResponse executeSkill( final PlayerExecuteAbilityRequest request ) { final Room room = roomManager.findByCode(code); - final Player target = room.getPlayer(request.target()); final Player player = room.getPlayer(name); - final String result = room.executeSkill(name, target); + final String result = room.executeSkill(name, request.target()); return new PlayerExecuteAbilityResponse(player.getJobSymbol().name(), result); } diff --git a/src/main/java/mafia/mafiatogether/service/RoomService.java b/src/main/java/mafia/mafiatogether/service/RoomService.java index 1c854970..299cba44 100644 --- a/src/main/java/mafia/mafiatogether/service/RoomService.java +++ b/src/main/java/mafia/mafiatogether/service/RoomService.java @@ -26,7 +26,7 @@ public RoomCodeResponse create(final RoomCreateRequest request) { public void join(final String code, final String name) { final Room room = roomManager.findByCode(code); - room.joinPlayer(Player.create(name)); + room.joinPlayer(name); } public RoomStatusResponse findStatus(final String code) { diff --git a/src/main/java/mafia/mafiatogether/service/dto/ChatRequest.java b/src/main/java/mafia/mafiatogether/service/dto/ChatRequest.java index 1be6587a..6f76ce41 100644 --- a/src/main/java/mafia/mafiatogether/service/dto/ChatRequest.java +++ b/src/main/java/mafia/mafiatogether/service/dto/ChatRequest.java @@ -1,6 +1,9 @@ package mafia.mafiatogether.service.dto; +import jakarta.validation.constraints.NotNull; + public record ChatRequest( + @NotNull String contents ) { } diff --git a/src/main/java/mafia/mafiatogether/service/dto/RoomCreateRequest.java b/src/main/java/mafia/mafiatogether/service/dto/RoomCreateRequest.java index 995cf71d..2226b7cd 100644 --- a/src/main/java/mafia/mafiatogether/service/dto/RoomCreateRequest.java +++ b/src/main/java/mafia/mafiatogether/service/dto/RoomCreateRequest.java @@ -10,6 +10,6 @@ public record RoomCreateRequest( ) { public RoomInfo toDomain() { - return new RoomInfo(total, mafia, doctor, police); + return RoomInfo.of(total, mafia, doctor, police); } } diff --git a/src/test/java/mafia/mafiatogether/controller/ChatControllerTest.java b/src/test/java/mafia/mafiatogether/controller/ChatControllerTest.java index c86e1f1f..859fcb93 100644 --- a/src/test/java/mafia/mafiatogether/controller/ChatControllerTest.java +++ b/src/test/java/mafia/mafiatogether/controller/ChatControllerTest.java @@ -7,6 +7,7 @@ import java.util.Base64; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Stream; import mafia.mafiatogether.domain.Message; import mafia.mafiatogether.domain.Player; @@ -53,8 +54,8 @@ void setRoom() { room = roomManager.findByCode(code); player1 = Player.create("power"); player2 = Player.create("metthew"); - room.joinPlayer(player1); - room.joinPlayer(player2); + room.joinPlayer(player1.getName()); + room.joinPlayer(player2.getName()); } @Test @@ -109,7 +110,8 @@ void setRoom() { void 채팅_전송에_실패한다( final String testCase, final String code, - final String name + final String name, + final Optional contents ) { // given final String basic = Base64.getEncoder().encodeToString((code + ":" + name).getBytes()); @@ -118,7 +120,7 @@ void setRoom() { RestAssured.given().log().all() .contentType(ContentType.JSON) .header("Authorization", "Basic " + basic) - .body(Map.of("contents", "contents")) + .body(Map.of("contents", contents)) .when().post("/chat") .then().log().all() .statusCode(HttpStatus.BAD_REQUEST.value()); @@ -126,8 +128,9 @@ void setRoom() { static Stream failCaseProvider() { return Stream.of( - Arguments.of("방에 존재하지 않는 유저의 경우", code, "dali"), - Arguments.of("존재하지 않는 방의 경우", "testCode", "metthew") + Arguments.of("방에 존재하지 않는 유저의 경우", code, "dali", Optional.of("contents")), + Arguments.of("존재하지 않는 방의 경우", "testCode", "metthew", Optional.of("contents")), + Arguments.of("문자열이 비어있는 경우", code, "metthew", Optional.empty()) ); } } diff --git a/src/test/java/mafia/mafiatogether/controller/PlayerControllerTest.java b/src/test/java/mafia/mafiatogether/controller/PlayerControllerTest.java index c7b50d05..a9309944 100644 --- a/src/test/java/mafia/mafiatogether/controller/PlayerControllerTest.java +++ b/src/test/java/mafia/mafiatogether/controller/PlayerControllerTest.java @@ -6,11 +6,16 @@ import io.restassured.http.ContentType; import java.time.Clock; import java.util.Base64; +import java.util.Map; +import mafia.mafiatogether.config.exception.ErrorResponse; +import mafia.mafiatogether.config.exception.ExceptionCode; import mafia.mafiatogether.domain.Player; import mafia.mafiatogether.domain.Room; import mafia.mafiatogether.domain.RoomInfo; import mafia.mafiatogether.domain.RoomManager; +import mafia.mafiatogether.domain.job.JobType; import mafia.mafiatogether.domain.status.StatusType; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -34,18 +39,120 @@ void setUp() { RestAssured.port = port; } + @Test + void 직업_기술을_사용한다() { + // given + String code = roomManager.create(new RoomInfo(3, 1, 0, 0)); + Room room = roomManager.findByCode(code); + room.joinPlayer("t1"); + room.joinPlayer("t2"); + room.joinPlayer("t3"); + + room.modifyStatus(StatusType.DAY, Clock.systemDefaultZone()); + + Player mafia = room.getPlayers().values().stream() + .filter(player -> player.getJobSymbol().equals(JobType.MAFIA)) + .findFirst() + .get(); + String basic = Base64.getEncoder().encodeToString((code + ":" + mafia.getName()).getBytes()); + + // when & then + RestAssured.given().log().all() + .contentType(ContentType.JSON) + .body(Map.of("target", "t2")) + .header("Authorization", "Basic " + basic) + .when().post("/players/skill") + .then().log().all() + .statusCode(HttpStatus.OK.value()); + Assertions.assertThat(room.getJobsTarget(mafia.getName())).isEqualTo("t2"); + } + + @Test + void 이미_죽은사람에게_직업_기술_사용시_실패한다() { + // given + String code = roomManager.create(new RoomInfo(3, 1, 0, 0)); + Room room = roomManager.findByCode(code); + room.joinPlayer("t1"); + room.joinPlayer("t2"); + room.joinPlayer("t3"); + + room.modifyStatus(StatusType.DAY, Clock.systemDefaultZone()); + + Player mafia = room.getPlayers().values().stream() + .filter(player -> player.getJobSymbol().equals(JobType.MAFIA)) + .findFirst() + .get(); + Player dead = room.getPlayers().values().stream() + .filter(player -> !player.equals(mafia)) + .findFirst() + .get(); + dead.kill(); + + String basic = Base64.getEncoder().encodeToString((code + ":" + mafia.getName()).getBytes()); + + // when & then + final ErrorResponse response = RestAssured.given().log().all() + .contentType(ContentType.JSON) + .body(Map.of("target", dead.getName())) + .header("Authorization", "Basic " + basic) + .when().post("/players/skill") + .then().log().all() + .statusCode(HttpStatus.BAD_REQUEST.value()) + .extract() + .as(ErrorResponse.class); + + Assertions.assertThat(response.errorCode()).isEqualTo(ExceptionCode.NOT_ALIVE_PLAYER.getCode()); + } + + @Test + void 방에_없는_사람에게_직업_기술_사용시_실패한다() { + // given + String code = roomManager.create(new RoomInfo(3, 1, 0, 0)); + Room room = roomManager.findByCode(code); + room.joinPlayer("t1"); + room.joinPlayer("t2"); + room.joinPlayer("t3"); + + room.modifyStatus(StatusType.DAY, Clock.systemDefaultZone()); + + Player mafia = room.getPlayers().values().stream() + .filter(player -> player.getJobSymbol().equals(JobType.MAFIA)) + .findFirst() + .get(); + + String basic = Base64.getEncoder().encodeToString((code + ":" + mafia.getName()).getBytes()); + + // when & then + final ErrorResponse response = RestAssured.given().log().all() + .contentType(ContentType.JSON) + .body(Map.of("target", "t4")) + .header("Authorization", "Basic " + basic) + .when().post("/players/skill") + .then().log().all() + .statusCode(HttpStatus.BAD_REQUEST.value()) + .extract() + .as(ErrorResponse.class); + + Assertions.assertThat(response.errorCode()).isEqualTo(ExceptionCode.INVALID_PLAYER.getCode()); + } + @Test void 직업을_조회한다() { //given - String code = roomManager.create(new RoomInfo(5, 0, 0, 0)); - String basic = Base64.getEncoder().encodeToString((code + ":" + "power").getBytes()); + String code = roomManager.create(new RoomInfo(3, 1, 0, 0)); Room room = roomManager.findByCode(code); - room.joinPlayer(Player.create("power")); + room.joinPlayer("t1"); + room.joinPlayer("t2"); + room.joinPlayer("t3"); - //when - room.modifyStatus(StatusType.NIGHT, Clock.systemDefaultZone()); + room.modifyStatus(StatusType.DAY, Clock.systemDefaultZone()); + final Player citizen = room.getPlayers().values().stream() + .filter(player -> player.getJobSymbol().equals(JobType.CITIZEN)) + .findFirst() + .get(); + String basic = Base64.getEncoder().encodeToString((code + ":" + citizen.getName()).getBytes()); - //then + // when & then RestAssured.given().log().all() .contentType(ContentType.JSON) .header("Authorization", "Basic " + basic) diff --git a/src/test/java/mafia/mafiatogether/controller/RoomControllerTest.java b/src/test/java/mafia/mafiatogether/controller/RoomControllerTest.java index 08baa7ce..b97bfd11 100644 --- a/src/test/java/mafia/mafiatogether/controller/RoomControllerTest.java +++ b/src/test/java/mafia/mafiatogether/controller/RoomControllerTest.java @@ -6,7 +6,9 @@ import io.restassured.http.ContentType; import java.time.Clock; import java.util.Base64; -import mafia.mafiatogether.domain.Player; +import java.util.stream.Stream; +import mafia.mafiatogether.config.exception.ErrorResponse; +import mafia.mafiatogether.config.exception.ExceptionCode; import mafia.mafiatogether.domain.Room; import mafia.mafiatogether.domain.RoomInfo; import mafia.mafiatogether.domain.RoomManager; @@ -20,6 +22,9 @@ import org.hamcrest.Matchers; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; @@ -61,6 +66,38 @@ void setUp() { Assertions.assertThat(response.code()).isNotBlank(); } + @ParameterizedTest(name = "{0}일 때 방 생성에 실패한다") + @MethodSource("provideRoomCreateFailCase") + void 방_생성에_실패한다( + final String testCase, + final int total, + final int mafia + ) { + //given + final RoomCreateRequest request = new RoomCreateRequest(total, mafia, 1, 1); + + //when + final ErrorResponse response = RestAssured.given().log().all() + .contentType(ContentType.JSON) + .body(request) + .when().post("/rooms") + .then().log().all() + .statusCode(HttpStatus.BAD_REQUEST.value()) + .extract() + .as(ErrorResponse.class); + + // then + Assertions.assertThat(response.errorCode()).isEqualTo(ExceptionCode.INVALID_ROOM_INFORMATION.getCode()); + } + + static Stream provideRoomCreateFailCase() { + return Stream.of( + Arguments.of("마피아 수가 허용인원 수보다 많을때", 3, 2), + Arguments.of("총인원수가 3 미만일때", 2, 1), + Arguments.of("마피아 수가 0일때", 3, 0) + ); + } + @Test void 방을_상태를_확인할_수_있다() { //given @@ -88,11 +125,11 @@ void setUp() { String basic = Base64.getEncoder().encodeToString((code + ":" + "player1").getBytes()); RoomModifyRequest request = new RoomModifyRequest(StatusType.DAY); Room room = roomManager.findByCode(code); - room.joinPlayer(Player.create("player1")); - room.joinPlayer(Player.create("player2")); - room.joinPlayer(Player.create("player3")); - room.joinPlayer(Player.create("player4")); - room.joinPlayer(Player.create("player5")); + room.joinPlayer("player1"); + room.joinPlayer("player2"); + room.joinPlayer("player3"); + room.joinPlayer("player4"); + room.joinPlayer("player5"); //when RestAssured.given().log().all() @@ -108,6 +145,31 @@ void setUp() { Assertions.assertThat(actual).isEqualTo(StatusType.DAY); } + @Test + void 인원부족시_게임을_시작할_수_없다() { + //given + String code = roomManager.create(new RoomInfo(3, 1, 1, 1)); + String basic = Base64.getEncoder().encodeToString((code + ":" + "player1").getBytes()); + RoomModifyRequest request = new RoomModifyRequest(StatusType.DAY); + Room room = roomManager.findByCode(code); + room.joinPlayer("player1"); + room.joinPlayer("player2"); + + //when + final ErrorResponse response = RestAssured.given().log().all() + .contentType(ContentType.JSON) + .body(request) + .header("Authorization", "Basic " + basic) + .when().patch("/rooms/status") + .then().log().all() + .statusCode(HttpStatus.BAD_REQUEST.value()) + .extract() + .as(ErrorResponse.class); + + // then + Assertions.assertThat(response.errorCode()).isEqualTo(ExceptionCode.NOT_ENOUGH_PLAYER.getCode()); + } + @Test void 방에_참가할_수_있다() { //given @@ -125,6 +187,46 @@ void setUp() { Assertions.assertThat(room.getPlayer("power")).isNotNull(); } + @Test + void 방이_꽉_차_있을때_참가에_실패한다() { + //given + final String code = roomManager.create(new RoomInfo(3, 1, 1, 1)); + final Room room = roomManager.findByCode(code); + room.joinPlayer("A"); + room.joinPlayer("C"); + room.joinPlayer("D"); + //when + final ErrorResponse response = RestAssured.given().log().all() + .contentType(ContentType.JSON) + .when().get("/rooms?code=" + code + "&name=E") + .then().log().all() + .statusCode(HttpStatus.BAD_REQUEST.value()) + .extract() + .as(ErrorResponse.class); + + //then + Assertions.assertThat(response.errorCode()).isEqualTo(ExceptionCode.ROOM_FULL.getCode()); + } + + @Test + void 방에_이미_존재한느_이름으로_참가할때_참가에_실패한다() { + //given + final String code = roomManager.create(new RoomInfo(3, 1, 1, 1)); + final Room room = roomManager.findByCode(code); + room.joinPlayer("A"); + //when + final ErrorResponse response = RestAssured.given().log().all() + .contentType(ContentType.JSON) + .when().get("/rooms?code=" + code + "&name=A") + .then().log().all() + .statusCode(HttpStatus.BAD_REQUEST.value()) + .extract() + .as(ErrorResponse.class); + + //then + Assertions.assertThat(response.errorCode()).isEqualTo(ExceptionCode.INVALID_NAMES.getCode()); + } + @Test void 방의_코드를_찾는다() { // given @@ -161,7 +263,7 @@ void setUp() { final String code = roomManager.create(new RoomInfo(5, 1, 1, 1)); final String basic = Base64.getEncoder().encodeToString((code + ":" + "power").getBytes()); final Room room = roomManager.findByCode(code); - room.joinPlayer(Player.create("power")); + room.joinPlayer("power"); // when & then final RoomInfoResponse response = RestAssured.given().log().all() @@ -190,7 +292,7 @@ void setUp() { final String code = roomManager.create(new RoomInfo(5, 1, 1, 1)); final String basic = Base64.getEncoder().encodeToString((code + ":" + "power").getBytes()); final Room room = roomManager.findByCode(code); - room.joinPlayer(Player.create("power")); + room.joinPlayer("power"); room.getPlayer("power").kill(); // when & then @@ -212,6 +314,5 @@ void setUp() { softly.assertThat(response.players().getFirst().job()).isNotNull(); } ); - } } diff --git a/src/test/java/mafia/mafiatogether/controller/VoteControllerTest.java b/src/test/java/mafia/mafiatogether/controller/VoteControllerTest.java index 6b210c6d..5aa44be4 100644 --- a/src/test/java/mafia/mafiatogether/controller/VoteControllerTest.java +++ b/src/test/java/mafia/mafiatogether/controller/VoteControllerTest.java @@ -46,9 +46,9 @@ void setRoom() { player1 = Player.create("power"); player2 = Player.create("metthew"); player3 = Player.create("dali"); - room.joinPlayer(player1); - room.joinPlayer(player2); - room.joinPlayer(player3); + room.joinPlayer(player1.getName()); + room.joinPlayer(player2.getName()); + room.joinPlayer(player3.getName()); } @Test diff --git a/src/test/java/mafia/mafiatogether/domain/RoomTest.java b/src/test/java/mafia/mafiatogether/domain/RoomTest.java index d1366ff1..2c9ad30c 100644 --- a/src/test/java/mafia/mafiatogether/domain/RoomTest.java +++ b/src/test/java/mafia/mafiatogether/domain/RoomTest.java @@ -17,18 +17,19 @@ class RoomTest { @Test void 직업을_배정할_수_있다() { //given - Room room = Room.create(new RoomInfo(5, 3, 0, 1), Clock.systemDefaultZone()); - Player a = Player.create("A"); - Player b = Player.create("B"); - Player c = Player.create("C"); - Player d = Player.create("D"); - Player e = Player.create("E"); - - room.joinPlayer(a); - room.joinPlayer(b); - room.joinPlayer(c); - room.joinPlayer(d); - room.joinPlayer(e); + Room room = Room.create(new RoomInfo(5, 2, 0, 1), Clock.systemDefaultZone()); + + room.joinPlayer("A"); + room.joinPlayer("B"); + room.joinPlayer("C"); + room.joinPlayer("D"); + room.joinPlayer("E"); + + Player a = room.getPlayer("A"); + Player b = room.getPlayer("B"); + Player c = room.getPlayer("C"); + Player d = room.getPlayer("D"); + Player e = room.getPlayer("E"); //when room.modifyStatus(StatusType.NIGHT, Clock.systemDefaultZone()); @@ -54,24 +55,23 @@ class RoomTest { } } - assertEquals(3, mafiaPlayers); + assertEquals(2, mafiaPlayers); } @Test void 투표를_할_수_있다() { // given final Room room = Room.create(new RoomInfo(5, 3, 0, 1), Clock.systemDefaultZone()); - Player a = Player.create("A"); - Player b = Player.create("B"); - Player c = Player.create("C"); - Player d = Player.create("D"); - Player e = Player.create("E"); - - room.joinPlayer(a); - room.joinPlayer(b); - room.joinPlayer(c); - room.joinPlayer(d); - room.joinPlayer(e); + room.joinPlayer("A"); + room.joinPlayer("B"); + room.joinPlayer("C"); + room.joinPlayer("D"); + room.joinPlayer("E"); + + Player a = room.getPlayer("A"); + Player b = room.getPlayer("B"); + Player c = room.getPlayer("C"); + Player d = room.getPlayer("D"); room.modifyStatus(StatusType.DAY, Clock.systemDefaultZone()); @@ -89,17 +89,17 @@ class RoomTest { void 동표일떄_투표가_무효가_된다() { // given final Room room = Room.create(new RoomInfo(5, 3, 0, 1), Clock.systemDefaultZone()); - Player a = Player.create("A"); - Player b = Player.create("B"); - Player c = Player.create("C"); - Player d = Player.create("D"); - Player e = Player.create("E"); - - room.joinPlayer(a); - room.joinPlayer(b); - room.joinPlayer(c); - room.joinPlayer(d); - room.joinPlayer(e); + room.joinPlayer("A"); + room.joinPlayer("B"); + room.joinPlayer("C"); + room.joinPlayer("D"); + room.joinPlayer("E"); + + Player a = room.getPlayer("A"); + Player b = room.getPlayer("B"); + Player c = room.getPlayer("C"); + Player d = room.getPlayer("D"); + Player e = room.getPlayer("E"); room.modifyStatus(StatusType.DAY, Clock.systemDefaultZone()); diff --git a/src/test/java/mafia/mafiatogether/domain/status/StatusTest.java b/src/test/java/mafia/mafiatogether/domain/status/StatusTest.java index 82fd312e..2e561792 100644 --- a/src/test/java/mafia/mafiatogether/domain/status/StatusTest.java +++ b/src/test/java/mafia/mafiatogether/domain/status/StatusTest.java @@ -19,24 +19,21 @@ class StatusTest { private static final Clock roomCreatedTime = Clock.fixed(Instant.parse("2024-01-01T00:00:00.000000Z"), TIME_ZONE); private Room room; - private Player a = Player.create("A"); - private Player b = Player.create("B"); - private Player c = Player.create("C"); @BeforeEach void setRoom() { room = Room.create(new RoomInfo(5, 2, 0, 1), roomCreatedTime); - a = Player.create("A"); - b = Player.create("B"); - c = Player.create("C"); + Player a = Player.create("A"); + Player b = Player.create("B"); + Player c = Player.create("C"); Player d = Player.create("D"); Player e = Player.create("E"); - room.joinPlayer(a); - room.joinPlayer(b); - room.joinPlayer(c); - room.joinPlayer(d); - room.joinPlayer(e); + room.joinPlayer(a.getName()); + room.joinPlayer(b.getName()); + room.joinPlayer(c.getName()); + room.joinPlayer(d.getName()); + room.joinPlayer(e.getName()); } @Test @@ -105,9 +102,9 @@ void setRoom() { room.modifyStatus(StatusType.DAY, roomCreatedTime); room.getStatusType(dayEndTime); room.getStatusType(voteEndTime); - a.kill(); - b.kill(); - c.kill(); + room.getPlayer("A").kill(); + room.getPlayer("B").kill(); + room.getPlayer("C").kill(); // when & then assertEquals(StatusType.END, room.getStatusType(nightEndTime)); @@ -125,9 +122,9 @@ void setRoom() { room.modifyStatus(StatusType.DAY, roomCreatedTime); room.getStatusType(dayEndTime); room.getStatusType(voteEndTime); - a.kill(); - b.kill(); - c.kill(); + room.getPlayer("A").kill(); + room.getPlayer("B").kill(); + room.getPlayer("C").kill(); room.getStatusType(nightEndTime); // when & then