Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[김대겸] Step1 PR #651

Merged
merged 13 commits into from
Dec 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
77 changes: 63 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,69 @@

## 요구 사항

### 메뉴
- [X] 메뉴를 생성할 수 있다.
- [X] 가격은 0원 이상이어야 한다.
- [X] 등록된 메뉴 그룹에 포함되어야 한다.
- [X] 메뉴 상품은 모두 등록된 상품이어야 한다.
- [X] 메뉴의 가격은 메뉴 상품 가격의 합보다 작아야 한다.
- [X] 메뉴 목록을 조회할 수 있다.

### 메뉴그룹
- [X] 메뉴 그룹을 생성할 수 있다.
- [X] 메뉴 그룹 목록을 조회할 수 있다.

### 주문
- [X] 주문을 생성할 수 있다.
- [X] 최소 1개의 주문 항목이 존재해야 한다.
- [X] 주문 항목에 포함된 메뉴들은 모두 존재해야 한다.
- [X] 주문 테이블은 등록된 테이블이어야 한다.
- [X] 주문 목록을 조회할 수 있다.
- [X] 주문 상태를 변경할 수 있다.
- [X] 주문이 완료된 상태에는 주문 상태 변경이 불가능하다.

### 주문 테이블
- [X] 주문 테이블을 생성할 수 있다.
- [X] 주문 테이블 목록을 조회할 수 있다.
- [X] 주문 테이블으 빈 좌석 여부에 대해 변경할 수 있다.
- [X] 주문 테이블은 단체 지정이 되어 있지 않아야 한다.
- [X] 주문 테이블의 주문 상태는 조리 중이거나 식사 중이면 안된다.
- [X] 주문 테이블에 방문 고객 수를 변경할 수 있다.
- [X] 주문 테이블의 방문 고객 수는 0명 이상이어야 한다.
- [X] 주문 테이블은 빈 좌석이 아니어야 한다.

### 상품
- [X] 상품을 등록할 수 있다.
- [X] 상품의 가격은 0원 이상이어야 한다.
- [X] 상품의 목록을 조회할 수 있다.

### 단체 지정
- [X] 단체 지정을 할 수 있다.
- [X] 등록된 주문 테이블들이 2개 이상 필요하다.
- [X] 주문 테이블들은 비어있어야 한다.
- [X] 주문 테이블들은 단체 지정이 되어있지 않아야 한다.
- [X] 단체 지정을 해제할 수 있다.
- [X] 주문 테이블들의 상태가 조리 중이거나 식사중이면 안된다.

## 용어 사전

| 한글명 | 영문명 | 설명 |
| --- | --- | --- |
| 상품 | product | 메뉴를 관리하는 기준이 되는 데이터 |
| 메뉴 그룹 | menu group | 메뉴 묶음, 분류 |
| 메뉴 | menu | 메뉴 그룹에 속하는 실제 주문 가능 단위 |
| 메뉴 상품 | menu product | 메뉴에 속하는 수량이 있는 상품 |
| 금액 | amount | 가격 * 수량 |
| 주문 테이블 | order table | 매장에서 주문이 발생하는 영역 |
| 빈 테이블 | empty table | 주문을 등록할 수 없는 주문 테이블 |
| 주문 | order | 매장에서 발생하는 주문 |
| 주문 상태 | order status | 주문은 조리 ➜ 식사 ➜ 계산 완료 순서로 진행된다. |
| 한글명 | 영문명 | 설명 |
|----------|------------------|-------------------------------|
| 상품 | product | 메뉴를 관리하는 기준이 되는 데이터 |
| 메뉴 그룹 | menu group | 메뉴 묶음, 분류 |
| 메뉴 | menu | 메뉴 그룹에 속하는 실제 주문 가능 단위 |
| 메뉴 상품 | menu product | 메뉴에 속하는 수량이 있는 상품 |
| 금액 | amount | 가격 * 수량 |
| 주문 테이블 | order table | 매장에서 주문이 발생하는 영역 |
| 빈 테이블 | empty table | 주문을 등록할 수 없는 주문 테이블 |
| 주문 | order | 매장에서 발생하는 주문 |
| 주문 상태 | order status | 주문은 조리 ➜ 식사 ➜ 계산 완료 순서로 진행된다. |
| 방문한 손님 수 | number of guests | 필수 사항은 아니며 주문은 0명으로 등록할 수 있다. |
| 단체 지정 | table group | 통합 계산을 위해 개별 주문 테이블을 그룹화하는 기능 |
| 주문 항목 | order line item | 주문에 속하는 수량이 있는 메뉴 |
| 매장 식사 | eat in | 포장하지 않고 매장에서 식사하는 것 |
| 단체 지정 | table group | 통합 계산을 위해 개별 주문 테이블을 그룹화하는 기능 |
| 주문 항목 | order line item | 주문에 속하는 수량이 있는 메뉴 |
| 매장 식사 | eat in | 포장하지 않고 매장에서 식사하는 것 |

## 1단계 - 테스트를 통한 코드 보호
### 요구 사항 체크리스트
- [X] 키친포스 요구사항 작성
- [X] 키친포스 테스트 코드 작성
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ dependencies {
implementation 'org.flywaydb:flyway-core'
runtimeOnly 'com.h2database:h2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.rest-assured:rest-assured:3.3.0'
}

test {
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/kitchenpos/domain/Menu.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ public class Menu {
private Long menuGroupId;
private List<MenuProduct> menuProducts;

public Menu() {
}

private Menu(Long id, String name, BigDecimal price, Long menuGroupId,
List<MenuProduct> menuProducts) {
this.id = id;
this.name = name;
this.price = price;
this.menuGroupId = menuGroupId;
this.menuProducts = menuProducts;
}

public static Menu of(Long id, String name, BigDecimal price, Long menuGroupId,
List<MenuProduct> menuProducts) {
return new Menu(id, name, price, menuGroupId, menuProducts);
}

public Long getId() {
return id;
}
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/kitchenpos/domain/MenuGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ public class MenuGroup {
private Long id;
private String name;

public MenuGroup() {
}

private MenuGroup(Long id, String name) {
this.id = id;
this.name = name;
}

public static MenuGroup of(Long id, String name) {
return new MenuGroup(id, name);
}

public Long getId() {
return id;
}
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/kitchenpos/domain/MenuProduct.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ public class MenuProduct {
private Long productId;
private long quantity;

public MenuProduct() {
}

private MenuProduct(Long seq, Long menuId, Long productId, long quantity) {
this.seq = seq;
this.menuId = menuId;
this.productId = productId;
this.quantity = quantity;
}

public static MenuProduct of(Long seq, Long menuId, Long productId, long quantity) {
return new MenuProduct(seq, menuId, productId, quantity);
}

public Long getSeq() {
return seq;
}
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/kitchenpos/domain/Order.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ public class Order {
private LocalDateTime orderedTime;
private List<OrderLineItem> orderLineItems;

public Order() {
}

private Order(Long id, Long orderTableId, String orderStatus, LocalDateTime orderedTime,
List<OrderLineItem> orderLineItems) {
this.id = id;
this.orderTableId = orderTableId;
this.orderStatus = orderStatus;
this.orderedTime = orderedTime;
this.orderLineItems = orderLineItems;
}

public static Order of(Long id, Long orderTableId, String orderStatus, LocalDateTime orderedTime,
List<OrderLineItem> orderLineItems) {
return new Order(id, orderTableId, orderStatus, orderedTime, orderLineItems);
}

public Long getId() {
return id;
}
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/kitchenpos/domain/OrderLineItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ public class OrderLineItem {
private Long menuId;
private long quantity;

public OrderLineItem() {
}

private OrderLineItem(Long seq, Long orderId, Long menuId, long quantity) {
this.seq = seq;
this.orderId = orderId;
this.menuId = menuId;
this.quantity = quantity;
}

public static OrderLineItem of(Long seq, Long orderId, Long menuId, long quantity) {
return new OrderLineItem(seq, orderId, menuId, quantity);
}

public Long getSeq() {
return seq;
}
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/kitchenpos/domain/OrderTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ public class OrderTable {
private int numberOfGuests;
private boolean empty;

public OrderTable() {}

private OrderTable(Long id, Long tableGroupId, int numberOfGuests, boolean empty) {
this.id = id;
this.tableGroupId = tableGroupId;
this.numberOfGuests = numberOfGuests;
this.empty = empty;
}

public static OrderTable of(Long id, Long tableGroupId, int numberOfGuests, boolean empty) {
return new OrderTable(id, tableGroupId, numberOfGuests, empty);
}

public Long getId() {
return id;
}
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/kitchenpos/domain/Product.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ public class Product {
private String name;
private BigDecimal price;

public Product() {
}

private Product(Long id, String name, BigDecimal price) {
this.id = id;
this.name = name;
this.price = price;
}

public static Product of(Long id, String name, BigDecimal price) {
return new Product(id, name, price);
}

public Long getId() {
return id;
}
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/kitchenpos/domain/TableGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ public class TableGroup {
private LocalDateTime createdDate;
private List<OrderTable> orderTables;

public TableGroup() {
}

private TableGroup(Long id, LocalDateTime createdDate, List<OrderTable> orderTables) {
this.id = id;
this.createdDate = createdDate;
this.orderTables = orderTables;
}

public static TableGroup of(Long id, LocalDateTime createdDate, List<OrderTable> orderTables) {
return new TableGroup(id, createdDate, orderTables);
}

public Long getId() {
return id;
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/resources/sql/truncate.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE TABLE TABLE_GROUP;
TRUNCATE TABLE ORDERS;
TRUNCATE TABLE ORDER_LINE_ITEM;
TRUNCATE TABLE ORDER_TABLE;
TRUNCATE TABLE MENU;
TRUNCATE TABLE MENU_GROUP;
TRUNCATE TABLE MENU_PRODUCT;
TRUNCATE TABLE PRODUCT;
SET FOREIGN_KEY_CHECKS = 1;
20 changes: 20 additions & 0 deletions src/test/java/kitchenpos/acceptance/AcceptanceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package kitchenpos.acceptance;

import io.restassured.RestAssured;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.jdbc.Sql;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Sql("/sql/truncate.sql")
public class AcceptanceTest {

@LocalServerPort
int port;

@BeforeEach
public void setUp() {
RestAssured.port = port;
}
}
Comment on lines +9 to +20
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

인수테스트 정말 꼼꼼하게 잘 작성해주셧네요 ㅎㅎ
호출, 검증기능에 대해서도 잘 분리되어있으니 보기 편하네요!

62 changes: 62 additions & 0 deletions src/test/java/kitchenpos/acceptance/MenuAcceptanceStep.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package kitchenpos.acceptance;

import io.restassured.RestAssured;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;
import kitchenpos.domain.Menu;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;

import java.util.List;
import java.util.stream.Collectors;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;

public class MenuAcceptanceStep {

public static ExtractableResponse<Response> 등록된_메뉴(Menu menu) {
return 메뉴_생성_요청(menu);
}

public static ExtractableResponse<Response> 메뉴_생성_요청(Menu menu) {
return RestAssured
.given().log().all()
.body(menu)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.when().post("/api/menus")
.then().log().all()
.extract();
}

public static ExtractableResponse<Response> 메뉴_목록_조회_요청() {
return RestAssured
.given().log().all()
.when().get("/api/menus")
.then().log().all()
.extract();
}

public static void 메뉴_생성됨(ExtractableResponse<Response> response) {
assertAll(
() -> assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value()),
() -> assertThat(response.header("Location")).isNotBlank()
);
}

public static void 메뉴_목록_응답됨(ExtractableResponse<Response> response) {
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value());
}

public static void 메뉴_목록_포함됨(ExtractableResponse<Response> response, List<ExtractableResponse<Response>> createdResponses) {
List<Long> expectedMenuIds = createdResponses.stream()
.map(it -> Long.parseLong(it.header("Location").split("/")[3]))
.collect(Collectors.toList());

List<Long> resultMenuIds = response.jsonPath().getList(".", Menu.class).stream()
.map(Menu::getId)
.collect(Collectors.toList());

assertThat(resultMenuIds).containsAll(expectedMenuIds);
}
}