Skip to content

Commit 4ca321e

Browse files
committed
round3: 코드 개선, 테스트 오류 수정
1 parent c80ed47 commit 4ca321e

10 files changed

Lines changed: 140 additions & 124 deletions

File tree

apps/commerce-api/src/main/java/com/loopers/application/order/OrderFacade.java

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
package com.loopers.application.order;
22

33
import com.loopers.domain.order.Order;
4-
import com.loopers.domain.order.OrderItem;
54
import com.loopers.domain.order.OrderService;
65
import com.loopers.domain.point.PointService;
76
import com.loopers.domain.product.Product;
87
import com.loopers.domain.product.ProductService;
98
import com.loopers.domain.supply.SupplyService;
109
import com.loopers.domain.user.User;
1110
import com.loopers.domain.user.UserService;
12-
import com.loopers.interfaces.api.order.OrderV1Dto;
1311
import com.loopers.support.error.CoreException;
1412
import com.loopers.support.error.ErrorType;
1513
import lombok.RequiredArgsConstructor;
@@ -18,7 +16,6 @@
1816
import org.springframework.stereotype.Component;
1917
import org.springframework.transaction.annotation.Transactional;
2018

21-
import java.util.List;
2219
import java.util.Map;
2320
import java.util.stream.Collectors;
2421

@@ -31,6 +28,7 @@ public class OrderFacade {
3128
private final PointService pointService;
3229
private final SupplyService supplyService;
3330

31+
@Transactional(readOnly = true)
3432
public OrderInfo getOrderInfo(String userId, Long orderId) {
3533
User user = userService.findByUserId(userId).orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "사용자를 찾을 수 없습니다."));
3634
Order order = orderService.getOrderByIdAndUserId(orderId, user.getId());
@@ -46,38 +44,22 @@ public Page<OrderInfo> getOrderList(String userId, Pageable pageable) {
4644
}
4745

4846
@Transactional
49-
public OrderInfo createOrder(String userId, OrderV1Dto.OrderRequest request) {
47+
public OrderInfo createOrder(String userId, OrderRequest request) {
5048
User user = userService.findByUserId(userId).orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "사용자를 찾을 수 없습니다."));
5149

52-
// request에서 productId - quantity 맵 생성
53-
Map<Long, Integer> productQuantityMap = request.items().stream()
54-
.collect(Collectors.toMap(
55-
OrderV1Dto.OrderRequest.OrderItemRequest::productId,
56-
OrderV1Dto.OrderRequest.OrderItemRequest::quantity
57-
));
50+
Map<Long, Integer> productIdQuantityMap = request.items().stream()
51+
.collect(Collectors.toMap(OrderItemRequest::productId, OrderItemRequest::quantity));
5852

59-
Map<Long, Product> productMap = productService.getProductMapByIds(productQuantityMap.keySet());
53+
Map<Long, Product> productMap = productService.getProductMapByIds(productIdQuantityMap.keySet());
6054

6155
request.items().forEach(item -> {
6256
supplyService.checkAndDecreaseStock(item.productId(), item.quantity());
6357
});
6458

65-
Integer totalAmount = productService.calculateTotalAmount(productQuantityMap);
66-
59+
Integer totalAmount = productService.calculateTotalAmount(productIdQuantityMap);
6760
pointService.checkAndDeductPoint(user.getId(), totalAmount);
6861

69-
List<OrderItem> orderItems = request.items()
70-
.stream()
71-
.map(item -> OrderItem.create(
72-
item.productId(),
73-
productMap.get(item.productId()).getName(),
74-
item.quantity(),
75-
productMap.get(item.productId()).getPrice()
76-
))
77-
.toList();
78-
Order order = Order.create(user.getId(), orderItems);
79-
80-
orderService.save(order);
62+
Order order = orderService.createOrder(request.items(), productMap, user.getId());
8163

8264
return OrderInfo.from(order);
8365
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.loopers.application.order;
2+
3+
public record OrderItemRequest(
4+
Long productId,
5+
Integer quantity
6+
) {
7+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.loopers.application.order;
2+
3+
import java.util.List;
4+
5+
public record OrderRequest(
6+
List<OrderItemRequest> items
7+
) {
8+
}

apps/commerce-api/src/main/java/com/loopers/domain/order/OrderService.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.loopers.domain.order;
22

3+
import com.loopers.application.order.OrderItemRequest;
4+
import com.loopers.domain.product.Product;
35
import com.loopers.support.error.CoreException;
46
import com.loopers.support.error.ErrorType;
57
import lombok.RequiredArgsConstructor;
@@ -9,6 +11,9 @@
911
import org.springframework.data.domain.Sort;
1012
import org.springframework.stereotype.Component;
1113

14+
import java.util.List;
15+
import java.util.Map;
16+
1217
@RequiredArgsConstructor
1318
@Component
1419
public class OrderService {
@@ -18,6 +23,21 @@ public Order save(Order order) {
1823
return orderRepository.save(order);
1924
}
2025

26+
public Order createOrder(List<OrderItemRequest> OrderItems, Map<Long, Product> productMap, Long userId) {
27+
List<OrderItem> orderItems = OrderItems
28+
.stream()
29+
.map(item -> OrderItem.create(
30+
item.productId(),
31+
productMap.get(item.productId()).getName(),
32+
item.quantity(),
33+
productMap.get(item.productId()).getPrice()
34+
))
35+
.toList();
36+
Order order = Order.create(userId, orderItems);
37+
38+
return orderRepository.save(order);
39+
}
40+
2141
public Order getOrderByIdAndUserId(Long orderId, Long userId) {
2242
return orderRepository.findByIdAndUserId(orderId, userId)
2343
.orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "주문을 찾을 수 없습니다."));

apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1ApiSpec.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.loopers.interfaces.api.order;
22

3+
import com.loopers.application.order.OrderRequest;
34
import com.loopers.interfaces.api.ApiResponse;
45
import io.swagger.v3.oas.annotations.Operation;
56
import io.swagger.v3.oas.annotations.media.Schema;
67
import io.swagger.v3.oas.annotations.tags.Tag;
7-
import org.springframework.data.domain.Page;
88
import org.springframework.data.domain.Pageable;
99
import org.springframework.data.web.PageableDefault;
1010
import org.springframework.web.bind.annotation.RequestHeader;
@@ -23,7 +23,7 @@ ApiResponse<OrderV1Dto.OrderResponse> createOrder(
2323
name = "주문 요청 정보",
2424
description = "주문 생성에 필요한 정보"
2525
)
26-
OrderV1Dto.OrderRequest request
26+
OrderRequest request
2727
);
2828

2929
// /api/v1/orders - GET

apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1Controller.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.loopers.application.order.OrderFacade;
44
import com.loopers.application.order.OrderInfo;
5+
import com.loopers.application.order.OrderRequest;
56
import com.loopers.interfaces.api.ApiResponse;
67
import com.loopers.support.error.CoreException;
78
import com.loopers.support.error.ErrorType;
@@ -22,7 +23,7 @@ public class OrderV1Controller implements OrderV1ApiSpec {
2223
@Override
2324
public ApiResponse<OrderV1Dto.OrderResponse> createOrder(
2425
@RequestHeader(value = "X-USER-ID", required = false) String userId,
25-
@RequestBody OrderV1Dto.OrderRequest request
26+
@RequestBody OrderRequest request
2627
) {
2728
if (StringUtils.isBlank(userId)) {
2829
throw new CoreException(ErrorType.BAD_REQUEST);

apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1Dto.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,6 @@
77
import java.util.List;
88

99
public class OrderV1Dto {
10-
public record OrderRequest(
11-
List<OrderItemRequest> items
12-
) {
13-
public record OrderItemRequest(
14-
Long productId,
15-
Integer quantity
16-
) {
17-
}
18-
}
1910

2011
public record OrderResponse(
2112
Long orderId,

apps/commerce-api/src/test/java/com/loopers/application/order/OrderFacadeIntegrationTest.java

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import com.loopers.infrastructure.product.ProductJpaRepository;
1515
import com.loopers.infrastructure.supply.SupplyJpaRepository;
1616
import com.loopers.infrastructure.user.UserJpaRepository;
17-
import com.loopers.interfaces.api.order.OrderV1Dto;
1817
import com.loopers.support.error.CoreException;
1918
import com.loopers.support.error.ErrorType;
2019
import com.loopers.utils.DatabaseCleanUp;
@@ -128,10 +127,10 @@ class CreateOrder {
128127
@Test
129128
void should_createOrder_when_validRequest() {
130129
// arrange
131-
OrderV1Dto.OrderRequest request = new OrderV1Dto.OrderRequest(
130+
OrderRequest request = new OrderRequest(
132131
List.of(
133-
new OrderV1Dto.OrderRequest.OrderItemRequest(productId1, 2),
134-
new OrderV1Dto.OrderRequest.OrderItemRequest(productId2, 1)
132+
new OrderItemRequest(productId1, 2),
133+
new OrderItemRequest(productId2, 1)
135134
)
136135
);
137136

@@ -150,9 +149,9 @@ void should_createOrder_when_validRequest() {
150149
void should_throwException_when_productIdDoesNotExist() {
151150
// arrange
152151
Long nonExistentProductId = 99999L;
153-
OrderV1Dto.OrderRequest request = new OrderV1Dto.OrderRequest(
152+
OrderRequest request = new OrderRequest(
154153
List.of(
155-
new OrderV1Dto.OrderRequest.OrderItemRequest(nonExistentProductId, 1)
154+
new OrderItemRequest(nonExistentProductId, 1)
156155
)
157156
);
158157

@@ -166,9 +165,9 @@ void should_throwException_when_productIdDoesNotExist() {
166165
@Test
167166
void should_throwException_when_singleProductStockInsufficient() {
168167
// arrange
169-
OrderV1Dto.OrderRequest request = new OrderV1Dto.OrderRequest(
168+
OrderRequest request = new OrderRequest(
170169
List.of(
171-
new OrderV1Dto.OrderRequest.OrderItemRequest(productId1, 99999)
170+
new OrderItemRequest(productId1, 99999)
172171
)
173172
);
174173

@@ -184,10 +183,10 @@ void should_throwException_when_partialStockInsufficient() {
184183
// arrange
185184
// productId1: 재고 100, productId2: 재고 50
186185
// productId1은 충분하지만 productId2는 부족
187-
OrderV1Dto.OrderRequest request = new OrderV1Dto.OrderRequest(
186+
OrderRequest request = new OrderRequest(
188187
List.of(
189-
new OrderV1Dto.OrderRequest.OrderItemRequest(productId1, 10), // 재고 충분
190-
new OrderV1Dto.OrderRequest.OrderItemRequest(productId2, 99999) // 재고 부족
188+
new OrderItemRequest(productId1, 10), // 재고 충분
189+
new OrderItemRequest(productId2, 99999) // 재고 부족
191190
)
192191
);
193192

@@ -203,10 +202,10 @@ void should_throwException_when_partialStockInsufficient() {
203202
@Test
204203
void should_throwException_when_allProductsStockInsufficient() {
205204
// arrange
206-
OrderV1Dto.OrderRequest request = new OrderV1Dto.OrderRequest(
205+
OrderRequest request = new OrderRequest(
207206
List.of(
208-
new OrderV1Dto.OrderRequest.OrderItemRequest(productId1, 99999),
209-
new OrderV1Dto.OrderRequest.OrderItemRequest(productId2, 99999)
207+
new OrderItemRequest(productId1, 99999),
208+
new OrderItemRequest(productId2, 99999)
210209
)
211210
);
212211

@@ -228,9 +227,9 @@ void should_throwException_when_supplyDoesNotExist() {
228227
productMetricsJpaRepository.save(metrics);
229228
// Supply는 생성하지 않음
230229

231-
OrderV1Dto.OrderRequest request = new OrderV1Dto.OrderRequest(
230+
OrderRequest request = new OrderRequest(
232231
List.of(
233-
new OrderV1Dto.OrderRequest.OrderItemRequest(savedProduct.getId(), 1)
232+
new OrderItemRequest(savedProduct.getId(), 1)
234233
)
235234
);
236235

@@ -245,17 +244,17 @@ void should_throwException_when_supplyDoesNotExist() {
245244
void should_throwException_when_pointInsufficient() {
246245
// arrange
247246
// 포인트를 모두 사용
248-
OrderV1Dto.OrderRequest firstOrder = new OrderV1Dto.OrderRequest(
247+
OrderRequest firstOrder = new OrderRequest(
249248
List.of(
250-
new OrderV1Dto.OrderRequest.OrderItemRequest(productId1, 10)
249+
new OrderItemRequest(productId1, 10)
251250
)
252251
);
253252
orderFacade.createOrder(userId, firstOrder);
254253

255254
// 포인트 부족한 주문 시도
256-
OrderV1Dto.OrderRequest request = new OrderV1Dto.OrderRequest(
255+
OrderRequest request = new OrderRequest(
257256
List.of(
258-
new OrderV1Dto.OrderRequest.OrderItemRequest(productId2, 1) // 20000원 필요 (부족)
257+
new OrderItemRequest(productId2, 1) // 20000원 필요 (부족)
259258
)
260259
);
261260

@@ -271,18 +270,18 @@ void should_throwException_when_pointInsufficient() {
271270
void should_createOrder_when_pointExactlyMatches() {
272271
// arrange
273272
// 포인트를 거의 모두 사용
274-
OrderV1Dto.OrderRequest firstOrder = new OrderV1Dto.OrderRequest(
273+
OrderRequest firstOrder = new OrderRequest(
275274
List.of(
276-
new OrderV1Dto.OrderRequest.OrderItemRequest(productId1, 9) // 90000원 사용
275+
new OrderItemRequest(productId1, 9) // 90000원 사용
277276
)
278277
);
279278
orderFacade.createOrder(userId, firstOrder);
280279
// 남은 포인트: 10000원
281280

282281
// 정확히 일치하는 주문
283-
OrderV1Dto.OrderRequest request = new OrderV1Dto.OrderRequest(
282+
OrderRequest request = new OrderRequest(
284283
List.of(
285-
new OrderV1Dto.OrderRequest.OrderItemRequest(productId1, 1) // 정확히 10000원
284+
new OrderItemRequest(productId1, 1) // 정확히 10000원
286285
)
287286
);
288287

@@ -300,10 +299,10 @@ void should_throwException_when_duplicateProducts() {
300299
// arrange
301300
// 같은 상품을 여러 번 주문 항목에 포함
302301
// Note: Collectors.toMap()은 중복 키가 있으면 IllegalStateException을 발생시킴
303-
OrderV1Dto.OrderRequest request = new OrderV1Dto.OrderRequest(
302+
OrderRequest request = new OrderRequest(
304303
List.of(
305-
new OrderV1Dto.OrderRequest.OrderItemRequest(productId1, 2),
306-
new OrderV1Dto.OrderRequest.OrderItemRequest(productId1, 3) // 중복
304+
new OrderItemRequest(productId1, 2),
305+
new OrderItemRequest(productId1, 3) // 중복
307306
)
308307
);
309308

@@ -320,9 +319,9 @@ void should_throwException_when_duplicateProducts() {
320319
void should_throwException_when_userDoesNotExist() {
321320
// arrange
322321
String nonExistentUserId = "nonexist";
323-
OrderV1Dto.OrderRequest request = new OrderV1Dto.OrderRequest(
322+
OrderRequest request = new OrderRequest(
324323
List.of(
325-
new OrderV1Dto.OrderRequest.OrderItemRequest(productId1, 1)
324+
new OrderItemRequest(productId1, 1)
326325
)
327326
);
328327

0 commit comments

Comments
 (0)