From 679da5aeca71db88525f3307fd3bbc7ae1290482 Mon Sep 17 00:00:00 2001 From: csh3424 Date: Sat, 2 Nov 2024 05:35:26 +0900 Subject: [PATCH 1/9] =?UTF-8?q?Feat:=201=EB=8B=A8=EA=B3=84=20=ED=99=88?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 ++ .../java/roomescape/Controller/ViewController.java | 13 +++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 src/main/java/roomescape/Controller/ViewController.java 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/Controller/ViewController.java b/src/main/java/roomescape/Controller/ViewController.java new file mode 100644 index 000000000..0faea07af --- /dev/null +++ b/src/main/java/roomescape/Controller/ViewController.java @@ -0,0 +1,13 @@ +package roomescape.Controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class ViewController { + + @GetMapping("/") + public String home() { + return "home"; + } +} From df4175673d40848d861adf39a6db4498a51591c3 Mon Sep 17 00:00:00 2001 From: csh3424 Date: Sat, 2 Nov 2024 08:16:41 +0900 Subject: [PATCH 2/9] =?UTF-8?q?Feat:=202=EB=8B=A8=EA=B3=84=20=EC=98=88?= =?UTF-8?q?=EC=95=BD=20=EC=A1=B0=ED=9A=8C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controller/ReservationController.java | 28 ++++++++++++++++ .../roomescape/Controller/ViewController.java | 5 +++ .../java/roomescape/Domain/Reservation.java | 33 +++++++++++++++++++ src/test/java/roomescape/MissionStepTest.java | 16 +++++++++ 4 files changed, 82 insertions(+) create mode 100644 src/main/java/roomescape/Controller/ReservationController.java create mode 100644 src/main/java/roomescape/Domain/Reservation.java diff --git a/src/main/java/roomescape/Controller/ReservationController.java b/src/main/java/roomescape/Controller/ReservationController.java new file mode 100644 index 000000000..f247f27d2 --- /dev/null +++ b/src/main/java/roomescape/Controller/ReservationController.java @@ -0,0 +1,28 @@ +package roomescape.Controller; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import roomescape.Domain.Reservation; + +@RestController +public class ReservationController { + private List reservations = new ArrayList<>(); + + public ReservationController() { + Reservation reservation1 = new Reservation(1, "브라운", "2023-01-01", "10:00"); + Reservation reservation2 = new Reservation(2, "브라운", "2023-01-02", "11:00"); + Reservation reservation3 = new Reservation(3, "브라운", "2023-01-03", "12:00"); + + reservations.add(reservation1); + reservations.add(reservation2); + reservations.add(reservation3); + } + + @GetMapping("/reservations") + public ResponseEntity> read() { + return ResponseEntity.ok().body(reservations); + } +} diff --git a/src/main/java/roomescape/Controller/ViewController.java b/src/main/java/roomescape/Controller/ViewController.java index 0faea07af..f623e6391 100644 --- a/src/main/java/roomescape/Controller/ViewController.java +++ b/src/main/java/roomescape/Controller/ViewController.java @@ -10,4 +10,9 @@ public class ViewController { public String home() { return "home"; } + + @GetMapping("/reservation") + public String reservation() { + return "reservation"; + } } diff --git a/src/main/java/roomescape/Domain/Reservation.java b/src/main/java/roomescape/Domain/Reservation.java new file mode 100644 index 000000000..304afcf8d --- /dev/null +++ b/src/main/java/roomescape/Domain/Reservation.java @@ -0,0 +1,33 @@ +package roomescape.Domain; + +public class Reservation { + private Integer id; + private String name; + private String date; + private String time; + + public Reservation() {} + + public Reservation(Integer id, String name, String date, String time) { + this.id = id; + this.name = name; + this.date = date; + this.time = time; + } + + public Integer getId() { + return id; + } + + public String getName() { + return name; + } + + public String getDate() { + return date; + } + + public String getTime() { + return time; + } +} diff --git a/src/test/java/roomescape/MissionStepTest.java b/src/test/java/roomescape/MissionStepTest.java index cf4efbe91..d2ee01703 100644 --- a/src/test/java/roomescape/MissionStepTest.java +++ b/src/test/java/roomescape/MissionStepTest.java @@ -1,5 +1,7 @@ package roomescape; +import static org.hamcrest.Matchers.is; + import io.restassured.RestAssured; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @@ -16,4 +18,18 @@ 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)); // 아직 생성 요청이 없으니 Controller에서 임의로 넣어준 Reservation 갯수 만큼 검증하거나 0개임을 확인하세요. + } } From 7668352342fd4e6e9e06b168a1fabb0fd0009020 Mon Sep 17 00:00:00 2001 From: csh3424 Date: Sat, 2 Nov 2024 08:59:44 +0900 Subject: [PATCH 3/9] =?UTF-8?q?Feat:=203=EB=8B=A8=EA=B3=84=20=EC=98=88?= =?UTF-8?q?=EC=95=BD=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=B7=A8=EC=86=8C?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controller/ReservationController.java | 33 ++++++++++++---- .../java/roomescape/Domain/Reservation.java | 12 ++++-- src/test/java/roomescape/MissionStepTest.java | 39 ++++++++++++++++++- 3 files changed, 72 insertions(+), 12 deletions(-) diff --git a/src/main/java/roomescape/Controller/ReservationController.java b/src/main/java/roomescape/Controller/ReservationController.java index f247f27d2..10c215298 100644 --- a/src/main/java/roomescape/Controller/ReservationController.java +++ b/src/main/java/roomescape/Controller/ReservationController.java @@ -1,28 +1,45 @@ package roomescape.Controller; +import java.net.URI; import java.util.ArrayList; import java.util.List; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicLong; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import roomescape.Domain.Reservation; @RestController public class ReservationController { private List reservations = new ArrayList<>(); + private AtomicLong index = new AtomicLong(1); - public ReservationController() { - Reservation reservation1 = new Reservation(1, "브라운", "2023-01-01", "10:00"); - Reservation reservation2 = new Reservation(2, "브라운", "2023-01-02", "11:00"); - Reservation reservation3 = new Reservation(3, "브라운", "2023-01-03", "12:00"); - - reservations.add(reservation1); - reservations.add(reservation2); - reservations.add(reservation3); + @PostMapping("/reservations") + public ResponseEntity create(@RequestBody Reservation reservation) { + Reservation newReservation = Reservation.toEntity(reservation, index.getAndIncrement()); + reservations.add(newReservation); + return ResponseEntity.created(URI.create("/reservations/" + newReservation.getId())) + .body(newReservation); } @GetMapping("/reservations") public ResponseEntity> read() { return ResponseEntity.ok().body(reservations); } + + @DeleteMapping("/reservations/{id}") + public ResponseEntity delete(@PathVariable long id) { + Reservation reservation = reservations.stream() + .filter(it -> Objects.equals(it.getId(), id)) + .findFirst() + .orElseThrow(RuntimeException::new); + + reservations.remove(reservation); + return ResponseEntity.noContent().build(); + } } diff --git a/src/main/java/roomescape/Domain/Reservation.java b/src/main/java/roomescape/Domain/Reservation.java index 304afcf8d..800ce3dc5 100644 --- a/src/main/java/roomescape/Domain/Reservation.java +++ b/src/main/java/roomescape/Domain/Reservation.java @@ -1,21 +1,21 @@ package roomescape.Domain; public class Reservation { - private Integer id; + private Long id; private String name; private String date; private String time; public Reservation() {} - public Reservation(Integer id, String name, String date, String time) { + public Reservation(Long id, String name, String date, String time) { this.id = id; this.name = name; this.date = date; this.time = time; } - public Integer getId() { + public Long getId() { return id; } @@ -30,4 +30,10 @@ public String getDate() { public String getTime() { return time; } + + public static Reservation toEntity (Reservation reservation, Long id) { + return new Reservation( + id, reservation.getName(), reservation.getDate(), reservation.getTime() + ); + } } diff --git a/src/test/java/roomescape/MissionStepTest.java b/src/test/java/roomescape/MissionStepTest.java index d2ee01703..3273bd2be 100644 --- a/src/test/java/roomescape/MissionStepTest.java +++ b/src/test/java/roomescape/MissionStepTest.java @@ -3,6 +3,9 @@ import static org.hamcrest.Matchers.is; import io.restassured.RestAssured; +import io.restassured.http.ContentType; +import java.util.HashMap; +import java.util.Map; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; @@ -30,6 +33,40 @@ public class MissionStepTest { .when().get("/reservations") .then().log().all() .statusCode(200) - .body("size()", is(3)); // 아직 생성 요청이 없으니 Controller에서 임의로 넣어준 Reservation 갯수 만큼 검증하거나 0개임을 확인하세요. + .body("size()", is(0)); // 아직 생성 요청이 없으니 Controller에서 임의로 넣어준 Reservation 갯수 만큼 검증하거나 0개임을 확인하세요. + } + + @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)); } } From 46ae63ed91ed241d284d983da8dddb2fc4774105 Mon Sep 17 00:00:00 2001 From: csh3424 Date: Mon, 4 Nov 2024 23:34:31 +0900 Subject: [PATCH 4/9] =?UTF-8?q?Feat:=204=EB=8B=A8=EA=B3=84=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controller/ReservationController.java | 13 ++++++++++- .../NotFoundReservationException.java | 7 ++++++ src/test/java/roomescape/MissionStepTest.java | 22 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/main/java/roomescape/Exception/NotFoundReservationException.java diff --git a/src/main/java/roomescape/Controller/ReservationController.java b/src/main/java/roomescape/Controller/ReservationController.java index 10c215298..b84c10289 100644 --- a/src/main/java/roomescape/Controller/ReservationController.java +++ b/src/main/java/roomescape/Controller/ReservationController.java @@ -7,12 +7,14 @@ import java.util.concurrent.atomic.AtomicLong; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import roomescape.Domain.Reservation; +import roomescape.Exception.NotFoundReservationException; @RestController public class ReservationController { @@ -22,6 +24,10 @@ public class ReservationController { @PostMapping("/reservations") public ResponseEntity create(@RequestBody Reservation reservation) { Reservation newReservation = Reservation.toEntity(reservation, index.getAndIncrement()); + if(newReservation.getName().isEmpty() || newReservation.getDate().isEmpty() + || newReservation.getTime().isEmpty()) { + throw new NotFoundReservationException("Reservation not found"); + } reservations.add(newReservation); return ResponseEntity.created(URI.create("/reservations/" + newReservation.getId())) .body(newReservation); @@ -37,9 +43,14 @@ public ResponseEntity delete(@PathVariable long id) { Reservation reservation = reservations.stream() .filter(it -> Objects.equals(it.getId(), id)) .findFirst() - .orElseThrow(RuntimeException::new); + .orElseThrow(() -> new NotFoundReservationException("Deletion not found")); reservations.remove(reservation); return ResponseEntity.noContent().build(); } + + @ExceptionHandler(NotFoundReservationException.class) + public ResponseEntity handleException(NotFoundReservationException e) { + return ResponseEntity.badRequest().build(); + } } diff --git a/src/main/java/roomescape/Exception/NotFoundReservationException.java b/src/main/java/roomescape/Exception/NotFoundReservationException.java new file mode 100644 index 000000000..c50765fdd --- /dev/null +++ b/src/main/java/roomescape/Exception/NotFoundReservationException.java @@ -0,0 +1,7 @@ +package roomescape.Exception; + +public class NotFoundReservationException extends RuntimeException { + public NotFoundReservationException(String message) { + super(message); + } +} diff --git a/src/test/java/roomescape/MissionStepTest.java b/src/test/java/roomescape/MissionStepTest.java index 3273bd2be..f17c7b713 100644 --- a/src/test/java/roomescape/MissionStepTest.java +++ b/src/test/java/roomescape/MissionStepTest.java @@ -69,4 +69,26 @@ public class MissionStepTest { .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); + } } From 64d907cea228a86cf13a3c633033700a477cfabe Mon Sep 17 00:00:00 2001 From: csh3424 Date: Tue, 5 Nov 2024 23:51:19 +0900 Subject: [PATCH 5/9] =?UTF-8?q?Feat:=205=EB=8B=A8=EA=B3=84=20DB=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 ++ src/main/resources/application.properties | 3 +++ src/main/resources/schema.sql | 8 ++++++++ src/test/java/roomescape/MissionStepTest.java | 19 +++++++++++++++++++ 4 files changed, 32 insertions(+) create mode 100644 src/main/resources/schema.sql diff --git a/build.gradle b/build.gradle index 40a581b15..1f450261e 100644 --- a/build.gradle +++ b/build.gradle @@ -16,6 +16,8 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' + implementation 'org.springframework.boot:spring-boot-starter-jdbc' + runtimeOnly 'com.h2database:h2' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'io.rest-assured:rest-assured:5.3.1' } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e69de29bb..f597afeef 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -0,0 +1,3 @@ +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console +spring.datasource.url=jdbc:h2:mem:database \ No newline at end of file diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 000000000..f5ef3d5f5 --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,8 @@ +CREATE TABLE reservation +( + id BIGINT NOT NULL AUTO_INCREMENT, + name VARCHAR(255) NOT NULL, + date VARCHAR(255) NOT NULL, + time VARCHAR(255) NOT NULL, + PRIMARY KEY (id) +); \ No newline at end of file diff --git a/src/test/java/roomescape/MissionStepTest.java b/src/test/java/roomescape/MissionStepTest.java index f17c7b713..16c6ada10 100644 --- a/src/test/java/roomescape/MissionStepTest.java +++ b/src/test/java/roomescape/MissionStepTest.java @@ -1,13 +1,18 @@ package roomescape; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.hamcrest.Matchers.is; import io.restassured.RestAssured; import io.restassured.http.ContentType; +import java.sql.Connection; +import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.annotation.DirtiesContext; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @@ -91,4 +96,18 @@ public class MissionStepTest { .then().log().all() .statusCode(400); } + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Test + void 오단계() { + try (Connection connection = jdbcTemplate.getDataSource().getConnection()) { + assertThat(connection).isNotNull(); + assertThat(connection.getCatalog()).isEqualTo("DATABASE"); + assertThat(connection.getMetaData().getTables(null, null, "RESERVATION", null).next()).isTrue(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } } From ae997a84f27f2e9a9c7dcce11a81a8d643043611 Mon Sep 17 00:00:00 2001 From: csh3424 Date: Sat, 9 Nov 2024 18:34:47 +0900 Subject: [PATCH 6/9] =?UTF-8?q?Feat:=206,7=EB=8B=A8=EA=B3=84=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=A1=B0=ED=9A=8C,=EC=B6=94=EA=B0=80,?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controller/ReservationController.java | 81 +++++++++++++++---- src/test/java/roomescape/MissionStepTest.java | 44 ++++++++++ 2 files changed, 109 insertions(+), 16 deletions(-) diff --git a/src/main/java/roomescape/Controller/ReservationController.java b/src/main/java/roomescape/Controller/ReservationController.java index b84c10289..ea37f178e 100644 --- a/src/main/java/roomescape/Controller/ReservationController.java +++ b/src/main/java/roomescape/Controller/ReservationController.java @@ -1,11 +1,16 @@ package roomescape.Controller; import java.net.URI; -import java.util.ArrayList; +import java.sql.PreparedStatement; import java.util.List; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicLong; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.PathVariable; @@ -18,37 +23,81 @@ @RestController public class ReservationController { - private List reservations = new ArrayList<>(); - private AtomicLong index = new AtomicLong(1); + private final JdbcTemplate jdbcTemplate; + + @Autowired + public ReservationController(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } @PostMapping("/reservations") public ResponseEntity create(@RequestBody Reservation reservation) { - Reservation newReservation = Reservation.toEntity(reservation, index.getAndIncrement()); - if(newReservation.getName().isEmpty() || newReservation.getDate().isEmpty() - || newReservation.getTime().isEmpty()) { + + if (reservation.getName() == null || reservation.getName().isEmpty() || + reservation.getDate() == null || reservation.getDate().isEmpty() || + reservation.getTime() == null || reservation.getTime().isEmpty()) { throw new NotFoundReservationException("Reservation not found"); } - reservations.add(newReservation); - return ResponseEntity.created(URI.create("/reservations/" + newReservation.getId())) - .body(newReservation); + + KeyHolder keyHolder = new GeneratedKeyHolder(); + String sql = "INSERT INTO reservation (name, date, time) VALUES (?, ?, ?)"; + jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(sql, new String[] {"id"}); + ps.setString(1, reservation.getName()); + ps.setString(2, reservation.getDate()); + ps.setString(3, reservation.getTime()); + return ps; + }, keyHolder); + + Long id = keyHolder.getKey().longValue(); + + Reservation savedReservation = jdbcTemplate.queryForObject( + "SELECT * FROM reservation WHERE id = ?", + reservationRowMapper, + id + ); + + return ResponseEntity.created(URI.create("/reservations/" + savedReservation.getId())) + .body(savedReservation); } @GetMapping("/reservations") public ResponseEntity> read() { + List reservations = jdbcTemplate.query( + "SELECT * FROM reservation", + reservationRowMapper + ); + return ResponseEntity.ok().body(reservations); } @DeleteMapping("/reservations/{id}") public ResponseEntity delete(@PathVariable long id) { - Reservation reservation = reservations.stream() - .filter(it -> Objects.equals(it.getId(), id)) - .findFirst() - .orElseThrow(() -> new NotFoundReservationException("Deletion not found")); - reservations.remove(reservation); + List reservations = jdbcTemplate.query( + "SELECT * FROM reservation WHERE id = ?", + reservationRowMapper, + id + ); + + if (reservations.isEmpty()) { + throw new NotFoundReservationException("Reservation not found"); + } + + jdbcTemplate.update("DELETE FROM reservation WHERE id = ?", id); + return ResponseEntity.noContent().build(); } + private final RowMapper reservationRowMapper = (resultSet, rowNum) -> { + return new Reservation( + resultSet.getLong("id"), + resultSet.getString("name"), + resultSet.getString("date"), + resultSet.getString("time") + ); + }; + @ExceptionHandler(NotFoundReservationException.class) public ResponseEntity handleException(NotFoundReservationException e) { return ResponseEntity.badRequest().build(); diff --git a/src/test/java/roomescape/MissionStepTest.java b/src/test/java/roomescape/MissionStepTest.java index 16c6ada10..e49fb6bbb 100644 --- a/src/test/java/roomescape/MissionStepTest.java +++ b/src/test/java/roomescape/MissionStepTest.java @@ -8,12 +8,14 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.annotation.DirtiesContext; +import roomescape.Domain.Reservation; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @@ -110,4 +112,46 @@ public class MissionStepTest { throw new RuntimeException(e); } } + + @Test + void 육단계() { + jdbcTemplate.update("INSERT INTO reservation (name, date, time) VALUES (?, ?, ?)", "브라운", "2023-08-05", "15:40"); + + List reservations = RestAssured.given().log().all() + .when().get("/reservations") + .then().log().all() + .statusCode(200).extract() + .jsonPath().getList(".", Reservation.class); + + Integer count = jdbcTemplate.queryForObject("SELECT count(1) from reservation", Integer.class); + + assertThat(reservations.size()).isEqualTo(count); + } + + @Test + void 칠단계() { + Map params = new HashMap<>(); + params.put("name", "브라운"); + params.put("date", "2023-08-05"); + params.put("time", "10:00"); + + RestAssured.given().log().all() + .contentType(ContentType.JSON) + .body(params) + .when().post("/reservations") + .then().log().all() + .statusCode(201) + .header("Location", "/reservations/1"); + + Integer count = jdbcTemplate.queryForObject("SELECT count(1) from reservation", Integer.class); + assertThat(count).isEqualTo(1); + + RestAssured.given().log().all() + .when().delete("/reservations/1") + .then().log().all() + .statusCode(204); + + Integer countAfterDelete = jdbcTemplate.queryForObject("SELECT count(1) from reservation", Integer.class); + assertThat(countAfterDelete).isEqualTo(0); + } } From 3de53e405b9e6f868d32418600c14ade4a1b2772 Mon Sep 17 00:00:00 2001 From: csh3424 Date: Sat, 16 Nov 2024 18:06:48 +0900 Subject: [PATCH 7/9] =?UTF-8?q?Feat:=208=EB=8B=A8=EA=B3=84=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=20=EA=B4=80=EB=A6=AC=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controller/ReservationController.java | 2 - .../roomescape/Controller/TimeController.java | 97 +++++++++++++++++++ src/main/java/roomescape/Domain/Time.java | 27 ++++++ .../Exception/NotFoundTimeException.java | 8 ++ src/main/resources/schema.sql | 9 +- src/test/java/roomescape/MissionStepTest.java | 25 +++++ 6 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 src/main/java/roomescape/Controller/TimeController.java create mode 100644 src/main/java/roomescape/Domain/Time.java create mode 100644 src/main/java/roomescape/Exception/NotFoundTimeException.java diff --git a/src/main/java/roomescape/Controller/ReservationController.java b/src/main/java/roomescape/Controller/ReservationController.java index ea37f178e..38418c516 100644 --- a/src/main/java/roomescape/Controller/ReservationController.java +++ b/src/main/java/roomescape/Controller/ReservationController.java @@ -5,12 +5,10 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; -import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.KeyHolder; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.PathVariable; diff --git a/src/main/java/roomescape/Controller/TimeController.java b/src/main/java/roomescape/Controller/TimeController.java new file mode 100644 index 000000000..ff8eb8d29 --- /dev/null +++ b/src/main/java/roomescape/Controller/TimeController.java @@ -0,0 +1,97 @@ +package roomescape.Controller; + +import java.net.URI; +import java.sql.PreparedStatement; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import roomescape.Domain.Time; +import roomescape.Exception.NotFoundTimeException; + +@RestController +public class TimeController { + private final JdbcTemplate jdbcTemplate; + + @Autowired + public TimeController(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + @PostMapping("/times") + public ResponseEntity