diff --git a/build.gradle b/build.gradle index 57267157c..40a581b15 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,8 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'io.rest-assured:rest-assured:5.3.1' } diff --git a/src/main/java/roomescape/Reservation.java b/src/main/java/roomescape/Reservation.java new file mode 100644 index 000000000..2f6f28111 --- /dev/null +++ b/src/main/java/roomescape/Reservation.java @@ -0,0 +1,46 @@ +package roomescape; + + +public class Reservation{ + private Long id; + private String name; + private String date; + private String time; + public Reservation(){ + + } + public Reservation(Long id,String name,String date,String time){ + this.id = id; + this.name = name; + this.date = date; + this.time = time; + } + + public Reservation(String name,String date,String time){ + this.name = name; + this.date = date; + this.time = time; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getDate() { + return date; + } + + public String getTime() { + return time; + } + + public static Reservation toEntity(Reservation reservation,Long id){ + return new Reservation(id,reservation.name,reservation.date,reservation.time); + } + + +} \ No newline at end of file diff --git a/src/main/java/roomescape/ReservationController.java b/src/main/java/roomescape/ReservationController.java new file mode 100644 index 000000000..c97133bb8 --- /dev/null +++ b/src/main/java/roomescape/ReservationController.java @@ -0,0 +1,70 @@ +package roomescape; + +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicLong; + +import static org.apache.logging.log4j.util.Strings.isBlank; + +@Controller +public class ReservationController { + + private final List reservations = new ArrayList<>(); + private final AtomicLong index =new AtomicLong(1); + + // render + @GetMapping("/reservation") + public String reservationPage() { + return "reservation"; + } + + // Read + @GetMapping("/reservations") + @ResponseBody + public ResponseEntity> list() { + return ResponseEntity.ok().body(reservations); + } + + // Create + @PostMapping("/reservations") + public ResponseEntity add_reservation(@RequestBody Reservation reservation){ + // handle exception -> any required field empty + if(isBlank(reservation.getName()) || isBlank(reservation.getDate()) || isBlank(reservation.getTime())){ + throw new BadRequestReservationException(); + } + + + Reservation newReservation = Reservation.toEntity(reservation,index.getAndIncrement()); + reservations.add(newReservation); + return ResponseEntity.created(URI.create("/reservations/" + newReservation.getId())).body(newReservation); + } + + // Delete + @DeleteMapping("/reservations/{id}") + public ResponseEntity cancel_reservation(@PathVariable Long id){ + + + Reservation newReservation = reservations.stream() + .filter(it-> Objects.equals(it.getId(),id)) + .findFirst() + //handle exception -> reservation is not found + .orElseThrow(NotFoundReservationException::new); + reservations.remove(newReservation); + return ResponseEntity.noContent().build(); + } + + // Exception Handler + public class NotFoundReservationException extends RuntimeException {} + public class BadRequestReservationException extends RuntimeException {} + @ExceptionHandler({BadRequestReservationException.class, NotFoundReservationException.class}) + public ResponseEntity handleBadRequest(RuntimeException e){ + return ResponseEntity.badRequest().build(); + } + +} diff --git a/src/test/java/roomescape/MissionStepTest.java b/src/test/java/roomescape/MissionStepTest.java index cf4efbe91..69c8148b3 100644 --- a/src/test/java/roomescape/MissionStepTest.java +++ b/src/test/java/roomescape/MissionStepTest.java @@ -1,10 +1,16 @@ package roomescape; import io.restassured.RestAssured; +import io.restassured.http.ContentType; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; +import java.util.HashMap; +import java.util.Map; + +import static org.hamcrest.Matchers.is; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) public class MissionStepTest { @@ -16,4 +22,74 @@ public class MissionStepTest { .then().log().all() .statusCode(200); } + + @Test + void 이단계() { + RestAssured.given().log().all() + .when().get("/reservation") + .then().log().all() + .statusCode(200); + + RestAssured.given().log().all() + .when().get("/reservations") + .then().log().all() + .statusCode(200) + .body("size()", is(3)); + } + + @Test + void 삼단계() { + Map params = new HashMap<>(); + params.put("name", "브라운"); + params.put("date", "2023-08-05"); + params.put("time", "15:40"); + + RestAssured.given().log().all() + .contentType(ContentType.JSON) + .body(params) + .when().post("/reservations") + .then().log().all() + .statusCode(201) + .header("Location", "/reservations/1") + .body("id", is(1)); + + RestAssured.given().log().all() + .when().get("/reservations") + .then().log().all() + .statusCode(200) + .body("size()", is(1)); + + RestAssured.given().log().all() + .when().delete("/reservations/1") + .then().log().all() + .statusCode(204); + + RestAssured.given().log().all() + .when().get("/reservations") + .then().log().all() + .statusCode(200) + .body("size()", is(0)); + } + + @Test + void 사단계() { + Map params = new HashMap<>(); + params.put("name", "브라운"); + params.put("date", ""); + params.put("time", ""); + + // 필요한 인자가 없는 경우 + RestAssured.given().log().all() + .contentType(ContentType.JSON) + .body(params) + .when().post("/reservations") + .then().log().all() + .statusCode(400); + + // 삭제할 예약이 없는 경우 + RestAssured.given().log().all() + .when().delete("/reservations/1") + .then().log().all() + .statusCode(400); + } }